1use std::fmt::Display;
2
3use cairo_lang_debug::DebugWithDb;
4use cairo_lang_defs::diagnostic_utils::StableLocation;
5use cairo_lang_defs::ids::{
6 EnumId, FunctionTitleId, GenericKind, ImplDefId, ImplFunctionId, ModuleId, ModuleItemId,
7 NamedLanguageElementId, StructId, TopLevelLanguageElementId, TraitFunctionId, TraitId,
8 TraitImplId, TraitItemId, UseId,
9};
10use cairo_lang_defs::plugin::PluginDiagnostic;
11use cairo_lang_diagnostics::{
12 DiagnosticAdded, DiagnosticEntry, DiagnosticLocation, DiagnosticNote, DiagnosticsBuilder,
13 ErrorCode, Severity, error_code,
14};
15use cairo_lang_filesystem::db::Edition;
16use cairo_lang_filesystem::ids::SmolStrId;
17use cairo_lang_filesystem::span::TextWidth;
18use cairo_lang_parser::ParserDiagnostic;
19use cairo_lang_syntax as syntax;
20use cairo_lang_syntax::node::ast;
21use cairo_lang_syntax::node::helpers::GetIdentifier;
22use itertools::Itertools;
23use salsa::Database;
24use syntax::node::ids::SyntaxStablePtrId;
25
26use crate::corelib::LiteralError;
27use crate::expr::inference::InferenceError;
28use crate::items::feature_kind::FeatureMarkerDiagnostic;
29use crate::items::trt::ConcreteTraitTypeId;
30use crate::resolve::{ResolvedConcreteItem, ResolvedGenericItem};
31use crate::types::peel_snapshots;
32use crate::{ConcreteTraitId, semantic};
33
34#[cfg(test)]
35#[path = "diagnostic_test.rs"]
36mod test;
37
38pub type SemanticDiagnostics<'db> = DiagnosticsBuilder<'db, SemanticDiagnostic<'db>>;
39pub trait SemanticDiagnosticsBuilder<'db> {
40 fn report(
42 &mut self,
43 stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
44 kind: SemanticDiagnosticKind<'db>,
45 ) -> DiagnosticAdded;
46 fn report_after(
48 &mut self,
49 stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
50 kind: SemanticDiagnosticKind<'db>,
51 ) -> DiagnosticAdded;
52 fn report_with_inner_span(
55 &mut self,
56 stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
57 inner_span: (TextWidth, TextWidth),
58 kind: SemanticDiagnosticKind<'db>,
59 ) -> DiagnosticAdded;
60}
61impl<'db> SemanticDiagnosticsBuilder<'db> for SemanticDiagnostics<'db> {
62 fn report(
63 &mut self,
64 stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
65 kind: SemanticDiagnosticKind<'db>,
66 ) -> DiagnosticAdded {
67 self.add(SemanticDiagnostic::new(StableLocation::new(stable_ptr.into()), kind))
68 }
69 fn report_after(
70 &mut self,
71 stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
72 kind: SemanticDiagnosticKind<'db>,
73 ) -> DiagnosticAdded {
74 self.add(SemanticDiagnostic::new_after(StableLocation::new(stable_ptr.into()), kind))
75 }
76 fn report_with_inner_span(
77 &mut self,
78 stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
79 inner_span: (TextWidth, TextWidth),
80 kind: SemanticDiagnosticKind<'db>,
81 ) -> DiagnosticAdded {
82 self.add(SemanticDiagnostic::new(
83 StableLocation::with_inner_span(stable_ptr.into(), inner_span),
84 kind,
85 ))
86 }
87}
88
89#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
90pub struct SemanticDiagnostic<'db> {
91 pub stable_location: StableLocation<'db>,
92 pub kind: SemanticDiagnosticKind<'db>,
93 pub after: bool,
96}
97impl<'db> SemanticDiagnostic<'db> {
98 pub fn new(stable_location: StableLocation<'db>, kind: SemanticDiagnosticKind<'db>) -> Self {
100 SemanticDiagnostic { stable_location, kind, after: false }
101 }
102 pub fn new_after(
104 stable_location: StableLocation<'db>,
105 kind: SemanticDiagnosticKind<'db>,
106 ) -> Self {
107 SemanticDiagnostic { stable_location, kind, after: true }
108 }
109}
110impl<'db> DiagnosticEntry<'db> for SemanticDiagnostic<'db> {
111 fn format(&self, db: &dyn Database) -> String {
112 match &self.kind {
113 SemanticDiagnosticKind::ModuleFileNotFound(path) => {
114 format!("Module file not found. Expected path: {path}")
115 }
116 SemanticDiagnosticKind::Unsupported => "Unsupported feature.".into(),
117 SemanticDiagnosticKind::UnknownLiteral => "Unknown literal.".into(),
118 SemanticDiagnosticKind::UnknownBinaryOperator => "Unknown binary operator.".into(),
119 SemanticDiagnosticKind::UnknownTrait => "Unknown trait.".into(),
120 SemanticDiagnosticKind::UnknownImpl => "Unknown impl.".into(),
121 SemanticDiagnosticKind::UnexpectedElement { expected, actual } => {
122 let expected_str = expected.iter().map(|kind| kind.to_string()).join(" or ");
123 format!("Expected {expected_str}, found {actual}.")
124 }
125 SemanticDiagnosticKind::UnknownType => "Unknown type.".into(),
126 SemanticDiagnosticKind::UnknownEnum => "Unknown enum.".into(),
127 SemanticDiagnosticKind::LiteralError(literal_error) => literal_error.format(db),
128 SemanticDiagnosticKind::NotAVariant => {
129 "Not a variant. Use the full name Enum::Variant.".into()
130 }
131 SemanticDiagnosticKind::NotAStruct => "Not a struct.".into(),
132 SemanticDiagnosticKind::NotAType => "Not a type.".into(),
133 SemanticDiagnosticKind::NotATrait => "Not a trait.".into(),
134 SemanticDiagnosticKind::NotAnImpl => "Not an impl.".into(),
135 SemanticDiagnosticKind::ImplItemNotInTrait {
136 impl_def_id,
137 impl_item_name,
138 trait_id,
139 item_kind,
140 } => {
141 format!(
142 "Impl item {item_kind} `{}::{}` is not a member of trait `{}`.",
143 impl_def_id.name(db).long(db),
144 impl_item_name.long(db),
145 trait_id.name(db).long(db)
146 )
147 }
148 SemanticDiagnosticKind::ImplicitImplNotInferred {
149 trait_impl_id,
150 concrete_trait_id,
151 } => {
152 format!(
153 "Cannot infer implicit impl `{}.`\nCould not find implementation of trait \
154 `{:?}`",
155 trait_impl_id.name(db).long(db),
156 concrete_trait_id.debug(db)
157 )
158 }
159 SemanticDiagnosticKind::GenericsNotSupportedInItem { scope, item_kind } => {
160 format!("Generic parameters are not supported in {scope} item {item_kind}.")
161 }
162 SemanticDiagnosticKind::UnexpectedGenericArgs => "Unexpected generic arguments".into(),
163 SemanticDiagnosticKind::UnknownMember => "Unknown member.".into(),
164 SemanticDiagnosticKind::MemberSpecifiedMoreThanOnce => {
165 "Member specified more than once.".into()
166 }
167 SemanticDiagnosticKind::ConstCycle => {
168 "Cycle detected while resolving 'const' items.".into()
169 }
170 SemanticDiagnosticKind::UseCycle => {
171 "Cycle detected while resolving 'use' items.".into()
172 }
173 SemanticDiagnosticKind::TypeAliasCycle => {
174 "Cycle detected while resolving type-alias/impl-type items.".into()
175 }
176 SemanticDiagnosticKind::ImplAliasCycle => {
177 "Cycle detected while resolving 'impls alias' items.".into()
178 }
179 SemanticDiagnosticKind::ImplRequirementCycle => {
180 "Cycle detected while resolving generic param. Try specifying the generic impl \
181 parameter explicitly to break the cycle."
182 .into()
183 }
184 SemanticDiagnosticKind::MissingMember(member_name) => {
185 format!(r#"Missing member "{}"."#, member_name.long(db))
186 }
187 SemanticDiagnosticKind::WrongNumberOfParameters {
188 impl_def_id,
189 impl_function_id,
190 trait_id,
191 expected,
192 actual,
193 } => {
194 let function_name = impl_function_id.name(db).long(db);
195 format!(
196 "The number of parameters in the impl function `{}::{}` is incompatible with \
197 `{}::{}`. Expected: {}, actual: {}.",
198 impl_def_id.name(db).long(db),
199 function_name,
200 trait_id.name(db).long(db),
201 function_name,
202 expected,
203 actual,
204 )
205 }
206 SemanticDiagnosticKind::WrongNumberOfArguments { expected, actual } => {
207 format!("Wrong number of arguments. Expected {expected}, found: {actual}")
208 }
209 SemanticDiagnosticKind::WrongParameterType {
210 impl_def_id,
211 impl_function_id,
212 trait_id,
213 expected_ty,
214 actual_ty,
215 } => {
216 let function_name = impl_function_id.name(db).long(db);
217 format!(
218 "Parameter type of impl function `{}::{}` is incompatible with `{}::{}`. \
219 Expected: `{}`, actual: `{}`.",
220 impl_def_id.name(db).long(db),
221 function_name,
222 trait_id.name(db).long(db),
223 function_name,
224 expected_ty.format(db),
225 actual_ty.format(db)
226 )
227 }
228 SemanticDiagnosticKind::VariantCtorNotImmutable => {
229 "Variant constructor argument must be immutable.".to_string()
230 }
231 SemanticDiagnosticKind::TraitParamMutable { trait_id, function_id } => {
232 format!(
233 "Parameter of trait function `{}::{}` can't be defined as mutable.",
234 trait_id.name(db).long(db),
235 function_id.name(db).long(db),
236 )
237 }
238 SemanticDiagnosticKind::ParameterShouldBeReference {
239 impl_def_id,
240 impl_function_id,
241 trait_id,
242 } => {
243 let function_name = impl_function_id.name(db).long(db);
244 format!(
245 "Parameter of impl function {}::{} is incompatible with {}::{}. It should be \
246 a reference.",
247 impl_def_id.name(db).long(db),
248 function_name,
249 trait_id.name(db).long(db),
250 function_name,
251 )
252 }
253 SemanticDiagnosticKind::ParameterShouldNotBeReference {
254 impl_def_id,
255 impl_function_id,
256 trait_id,
257 } => {
258 let function_name = impl_function_id.name(db).long(db);
259 format!(
260 "Parameter of impl function {}::{} is incompatible with {}::{}. It should not \
261 be a reference.",
262 impl_def_id.name(db).long(db),
263 function_name,
264 trait_id.name(db).long(db),
265 function_name,
266 )
267 }
268 SemanticDiagnosticKind::WrongParameterName {
269 impl_def_id,
270 impl_function_id,
271 trait_id,
272 expected_name,
273 } => {
274 let function_name = impl_function_id.name(db).long(db);
275 format!(
276 "Parameter name of impl function {}::{function_name} is incompatible with \
277 {}::{function_name} parameter `{}`.",
278 impl_def_id.name(db).long(db),
279 trait_id.name(db).long(db),
280 expected_name.long(db)
281 )
282 }
283 SemanticDiagnosticKind::WrongType { expected_ty, actual_ty } => {
284 format!(
285 r#"Expected type "{}", found: "{}"."#,
286 expected_ty.format(db),
287 actual_ty.format(db)
288 )
289 }
290 SemanticDiagnosticKind::InconsistentBinding => "variable is bound inconsistently \
291 across alternatives separated by `|` \
292 bound in different ways"
293 .into(),
294 SemanticDiagnosticKind::WrongArgumentType { expected_ty, actual_ty } => {
295 let diagnostic_prefix = format!(
296 r#"Unexpected argument type. Expected: "{}", found: "{}"."#,
297 expected_ty.format(db),
298 actual_ty.format(db)
299 );
300 if (expected_ty.is_fully_concrete(db) && actual_ty.is_fully_concrete(db))
301 || peel_snapshots(db, *expected_ty).0 == peel_snapshots(db, *actual_ty).0
302 {
303 diagnostic_prefix
304 } else {
305 format!(
306 "{diagnostic_prefix}\nIt is possible that the type inference failed \
307 because the types differ in the number of snapshots.\nConsider adding or \
308 removing snapshots."
309 )
310 }
311 }
312 SemanticDiagnosticKind::WrongReturnType { expected_ty, actual_ty } => {
313 format!(
314 r#"Unexpected return type. Expected: "{}", found: "{}"."#,
315 expected_ty.format(db),
316 actual_ty.format(db)
317 )
318 }
319 SemanticDiagnosticKind::WrongExprType { expected_ty, actual_ty } => {
320 format!(
321 r#"Unexpected expression type. Expected: "{}", found: "{}"."#,
322 expected_ty.format(db),
323 actual_ty.format(db)
324 )
325 }
326 SemanticDiagnosticKind::WrongNumberOfGenericParamsForImplFunction {
327 expected,
328 actual,
329 } => {
330 format!(
331 "Wrong number of generic parameters for impl function. Expected: {expected}, \
332 found: {actual}."
333 )
334 }
335 SemanticDiagnosticKind::WrongReturnTypeForImpl {
336 impl_def_id,
337 impl_function_id,
338 trait_id,
339 expected_ty,
340 actual_ty,
341 } => {
342 let function_name = impl_function_id.name(db).long(db);
343 format!(
344 "Return type of impl function `{}::{}` is incompatible with `{}::{}`. \
345 Expected: `{}`, actual: `{}`.",
346 impl_def_id.name(db).long(db),
347 function_name,
348 trait_id.name(db).long(db),
349 function_name,
350 expected_ty.format(db),
351 actual_ty.format(db)
352 )
353 }
354 SemanticDiagnosticKind::WrongGenericParamTraitForImplFunction {
355 impl_def_id,
356 impl_function_id,
357 trait_id,
358 expected_trait,
359 actual_trait,
360 } => {
361 let function_name = impl_function_id.name(db).long(db);
362 format!(
363 "Generic parameter trait of impl function `{}::{}` is incompatible with \
364 `{}::{}`. Expected: `{:?}`, actual: `{:?}`.",
365 impl_def_id.name(db).long(db),
366 function_name,
367 trait_id.name(db).long(db),
368 function_name,
369 expected_trait.debug(db),
370 actual_trait.debug(db)
371 )
372 }
373 SemanticDiagnosticKind::WrongGenericParamKindForImplFunction {
374 impl_def_id,
375 impl_function_id,
376 trait_id,
377 expected_kind,
378 actual_kind,
379 } => {
380 let function_name = impl_function_id.name(db).long(db);
381 format!(
382 "Generic parameter kind of impl function `{}::{}` is incompatible with \
383 `{}::{}`. Expected: `{:?}`, actual: `{:?}`.",
384 impl_def_id.name(db).long(db),
385 function_name,
386 trait_id.name(db).long(db),
387 function_name,
388 expected_kind,
389 actual_kind
390 )
391 }
392 SemanticDiagnosticKind::AmbiguousTrait { trait_function_id0, trait_function_id1 } => {
393 format!(
394 "Ambiguous method call. More than one applicable trait function with a \
395 suitable self type was found: {} and {}. Consider adding type annotations or \
396 explicitly refer to the impl function.",
397 trait_function_id0.full_path(db),
398 trait_function_id1.full_path(db)
399 )
400 }
401 SemanticDiagnosticKind::VariableNotFound(name) => {
402 format!(r#"Variable "{}" not found."#, name.long(db))
403 }
404 SemanticDiagnosticKind::MissingVariableInPattern => {
405 "Missing variable in pattern.".into()
406 }
407 SemanticDiagnosticKind::StructMemberRedefinition { struct_id, member_name } => {
408 format!(
409 r#"Redefinition of member "{}" on struct "{}"."#,
410 member_name.long(db),
411 struct_id.full_path(db)
412 )
413 }
414 SemanticDiagnosticKind::EnumVariantRedefinition { enum_id, variant_name } => {
415 format!(
416 r#"Redefinition of variant "{}" on enum "{}"."#,
417 variant_name.long(db),
418 enum_id.full_path(db)
419 )
420 }
421 SemanticDiagnosticKind::InfiniteSizeType(ty) => {
422 format!(r#"Recursive type "{}" has infinite size."#, ty.format(db))
423 }
424 SemanticDiagnosticKind::ArrayOfZeroSizedElements(ty) => {
425 format!(r#"Cannot have array of type "{}" that is zero sized."#, ty.format(db))
426 }
427 SemanticDiagnosticKind::ParamNameRedefinition { function_title_id, param_name } => {
428 format!(
429 r#"Redefinition of parameter name "{}"{}"#,
430 param_name.long(db),
431 function_title_id
432 .map(|function_title_id| format!(
433 r#" in function "{}"."#,
434 function_title_id.full_path(db)
435 ))
436 .unwrap_or(".".into()),
437 )
438 }
439 SemanticDiagnosticKind::ConditionNotBool(condition_ty) => {
440 format!(r#"Condition has type "{}", expected bool."#, condition_ty.format(db))
441 }
442 SemanticDiagnosticKind::IncompatibleArms {
443 multi_arm_expr_kind: incompatibility_kind,
444 pending_ty: first_ty,
445 different_ty,
446 } => {
447 let prefix = match incompatibility_kind {
448 MultiArmExprKind::Match => "Match arms have incompatible types",
449 MultiArmExprKind::If => "If blocks have incompatible types",
450 MultiArmExprKind::Loop => "Loop has incompatible return types",
451 };
452 format!(r#"{prefix}: "{}" and "{}""#, first_ty.format(db), different_ty.format(db))
453 }
454 SemanticDiagnosticKind::TypeHasNoMembers { ty, member_name: _ } => {
455 format!(r#"Type "{}" has no members."#, ty.format(db))
456 }
457 SemanticDiagnosticKind::NoSuchStructMember { struct_id, member_name } => {
458 format!(
459 r#"Struct "{}" has no member "{}""#,
460 struct_id.full_path(db),
461 member_name.long(db)
462 )
463 }
464 SemanticDiagnosticKind::NoSuchTypeMember { ty, member_name } => {
465 format!(r#"Type "{}" has no member "{}""#, ty.format(db), member_name.long(db))
466 }
467 SemanticDiagnosticKind::MemberNotVisible(member_name) => {
468 format!(r#"Member "{}" is not visible in this context."#, member_name.long(db))
469 }
470 SemanticDiagnosticKind::NoSuchVariant { enum_id, variant_name } => {
471 format!(
472 r#"Enum "{}" has no variant "{}""#,
473 enum_id.full_path(db),
474 variant_name.long(db)
475 )
476 }
477 SemanticDiagnosticKind::ReturnTypeNotErrorPropagateType => {
478 "`?` can only be used in a function with `Option` or `Result` return type.".into()
479 }
480 SemanticDiagnosticKind::IncompatibleErrorPropagateType { return_ty, err_ty } => {
481 format!(
482 r#"Return type "{}" does not wrap error "{}""#,
483 return_ty.format(db),
484 err_ty.format(db)
485 )
486 }
487 SemanticDiagnosticKind::ErrorPropagateOnNonErrorType(ty) => {
488 format!(r#"Type "{}" can not error propagate"#, ty.format(db))
489 }
490 SemanticDiagnosticKind::UnhandledMustUseType(ty) => {
491 format!(r#"Unhandled `#[must_use]` type `{}`"#, ty.format(db))
492 }
493 SemanticDiagnosticKind::UnhandledMustUseFunction => {
494 "Unhandled `#[must_use]` function.".into()
495 }
496 SemanticDiagnosticKind::UnstableFeature { feature_name, note } => {
497 format!(
498 "Usage of unstable feature `{0}` with no `#[feature({0})]` attribute.{1}",
499 feature_name.long(db),
500 note.as_ref()
501 .map(|note| format!(" Note: {}", note.long(db)))
502 .unwrap_or_default()
503 )
504 }
505 SemanticDiagnosticKind::DeprecatedFeature { feature_name, note } => {
506 format!(
507 "Usage of deprecated feature `{0}` with no `#[feature({0})]` attribute.{1}",
508 feature_name.long(db),
509 note.as_ref()
510 .map(|note| format!(" Note: {}", note.long(db)))
511 .unwrap_or_default()
512 )
513 }
514 SemanticDiagnosticKind::InternalFeature { feature_name, note } => {
515 format!(
516 "Usage of internal feature `{0}` with no `#[feature({0})]` attribute.{1}",
517 feature_name.long(db),
518 note.as_ref()
519 .map(|note| format!(" Note: {}", note.long(db)))
520 .unwrap_or_default()
521 )
522 }
523 SemanticDiagnosticKind::FeatureMarkerDiagnostic(diagnostic) => match diagnostic {
524 FeatureMarkerDiagnostic::MultipleMarkers => {
525 "Multiple feature marker attributes.".into()
526 }
527 FeatureMarkerDiagnostic::MissingAllowFeature => {
528 "Missing `feature` arg for feature marker attribute.".into()
529 }
530 FeatureMarkerDiagnostic::UnsupportedArgument => {
531 "Unsupported argument for feature marker attribute.".into()
532 }
533 FeatureMarkerDiagnostic::DuplicatedArgument => {
534 "Duplicated argument for feature marker attribute.".into()
535 }
536 },
537 SemanticDiagnosticKind::UnusedVariable => {
538 "Unused variable. Consider ignoring by prefixing with `_`.".into()
539 }
540 SemanticDiagnosticKind::UnusedConstant => {
541 "Unused constant. Consider ignoring by prefixing with `_`.".into()
542 }
543 SemanticDiagnosticKind::MultipleConstantDefinition(constant_name) => {
544 format!(r#"Multiple definitions of constant "{}"."#, constant_name.long(db))
545 }
546 SemanticDiagnosticKind::UnusedUse => "Unused use.".into(),
547 SemanticDiagnosticKind::MultipleDefinitionforBinding(name) => {
548 format!(
549 r#"Multiple definitions of identifier '{}' as constant and variable."#,
550 name.long(db)
551 )
552 }
553 SemanticDiagnosticKind::MultipleGenericItemDefinition(type_name) => {
554 format!(r#"Multiple definitions of an item "{}"."#, type_name.long(db))
555 }
556 SemanticDiagnosticKind::UnsupportedUseItemInStatement => {
557 "Unsupported use item in statement.".into()
558 }
559 SemanticDiagnosticKind::InvalidMemberExpression => "Invalid member expression.".into(),
560 SemanticDiagnosticKind::InvalidPath => "Invalid path.".into(),
561 SemanticDiagnosticKind::RefArgNotAVariable => "ref argument must be a variable.".into(),
562 SemanticDiagnosticKind::RefArgNotMutable => {
563 "ref argument must be a mutable variable.".into()
564 }
565 SemanticDiagnosticKind::RefArgNotExplicit => {
566 "ref argument must be passed with a preceding 'ref'.".into()
567 }
568 SemanticDiagnosticKind::ImmutableArgWithModifiers => {
569 "Argument to immutable parameter cannot have modifiers.".into()
570 }
571 SemanticDiagnosticKind::AssignmentToImmutableVar => {
572 "Cannot assign to an immutable variable.".into()
573 }
574 SemanticDiagnosticKind::InvalidLhsForAssignment => {
575 "Invalid left-hand side of assignment.".into()
576 }
577 SemanticDiagnosticKind::PathNotFound(item_type) => match item_type {
578 NotFoundItemType::Identifier => "Identifier not found.".into(),
579 NotFoundItemType::Function => "Function not found.".into(),
580 NotFoundItemType::Type => "Type not found.".into(),
581 NotFoundItemType::Trait => "Trait not found.".into(),
582 NotFoundItemType::Impl => "Impl not found.".into(),
583 NotFoundItemType::Macro => "Macro not found.".into(),
584 },
585 SemanticDiagnosticKind::AmbiguousPath(module_items) => {
586 format!(
587 "Ambiguous path. Multiple matching items: {}",
588 module_items.iter().map(|item| format!("`{}`", item.full_path(db))).join(", ")
589 )
590 }
591 SemanticDiagnosticKind::UseSelfNonMulti => {
592 "`self` in `use` items is not allowed not in multi.".into()
593 }
594 SemanticDiagnosticKind::UseSelfEmptyPath => {
595 "`self` in `use` items is not allowed for empty path.".into()
596 }
597 SemanticDiagnosticKind::UseStarEmptyPath => {
598 "`*` in `use` items is not allowed for empty path.".into()
599 }
600 SemanticDiagnosticKind::GlobalUsesNotSupportedInEdition(edition) => {
601 format!("Global `use` item is not supported in `{edition:?}` edition.")
602 }
603 SemanticDiagnosticKind::TraitInTraitMustBeExplicit => {
604 "In a trait, paths of the same trait must be fully explicit. Either use `Self` if \
605 this is the intention, or explicitly specify all the generic arguments."
606 .to_string()
607 }
608 SemanticDiagnosticKind::ImplInImplMustBeExplicit => {
609 "In an impl, paths of the same impl must be fully explicit. Either use `Self` if \
610 this is the intention, or explicitly specify all the generic arguments."
611 .to_string()
612 }
613 SemanticDiagnosticKind::TraitItemForbiddenInTheTrait => {
614 "In a trait, paths of the same trait are not allowed. Did you mean to use `Self::`?"
615 .to_string()
616 }
617 SemanticDiagnosticKind::TraitItemForbiddenInItsImpl => "In an impl, paths of the \
618 impl's trait are not allowed. \
619 Did you mean to use `Self::`?"
620 .to_string(),
621 SemanticDiagnosticKind::ImplItemForbiddenInTheImpl => {
622 "In an impl, paths of the same impl are not allowed. Did you mean to use `Self::`?"
623 .to_string()
624 }
625 SemanticDiagnosticKind::SuperUsedInRootModule => {
626 "'super' cannot be used for the crate's root module.".into()
627 }
628 SemanticDiagnosticKind::SuperUsedInMacroCallTopLevel => {
629 "`super` used in macro call top level.".into()
630 }
631 SemanticDiagnosticKind::ItemNotVisible(item_id, containing_modules) => {
632 format!(
633 "Item `{}` is not visible in this context{}.",
634 item_id.full_path(db),
635 if containing_modules.is_empty() {
636 "".to_string()
637 } else if let [module_id] = &containing_modules[..] {
638 format!(" through module `{}`", module_id.full_path(db))
639 } else {
640 format!(
641 " through any of the modules: {}",
642 containing_modules
643 .iter()
644 .map(|module_id| format!("`{}`", module_id.full_path(db)))
645 .join(", ")
646 )
647 }
648 )
649 }
650 SemanticDiagnosticKind::UnusedImport(use_id) => {
651 format!("Unused import: `{}`", use_id.full_path(db))
652 }
653 SemanticDiagnosticKind::UnexpectedEnumPattern(ty) => {
654 format!(r#"Unexpected type for enum pattern. "{}" is not an enum."#, ty.format(db),)
655 }
656 SemanticDiagnosticKind::UnexpectedStructPattern(ty) => {
657 format!(
658 r#"Unexpected type for struct pattern. "{}" is not a struct."#,
659 ty.format(db),
660 )
661 }
662 SemanticDiagnosticKind::UnexpectedTuplePattern(ty) => {
663 format!(r#"Unexpected type for tuple pattern. "{}" is not a tuple."#, ty.format(db),)
664 }
665 SemanticDiagnosticKind::UnexpectedFixedSizeArrayPattern(ty) => {
666 format!(
667 "Unexpected type for fixed size array pattern. \"{}\" is not a fixed size \
668 array.",
669 ty.format(db),
670 )
671 }
672 SemanticDiagnosticKind::WrongNumberOfTupleElements { expected, actual } => format!(
673 r#"Wrong number of tuple elements in pattern. Expected: {expected}. Got: {actual}."#,
674 ),
675 SemanticDiagnosticKind::WrongNumberOfFixedSizeArrayElements { expected, actual } => {
676 format!(
677 "Wrong number of fixed size array elements in pattern. Expected: {expected}. \
678 Got: {actual}.",
679 )
680 }
681 SemanticDiagnosticKind::WrongEnum { expected_enum, actual_enum } => {
682 format!(
683 r#"Wrong enum in pattern. Expected: "{}". Got: "{}"."#,
684 expected_enum.full_path(db),
685 actual_enum.full_path(db)
686 )
687 }
688 SemanticDiagnosticKind::RedundantModifier { current_modifier, previous_modifier } => {
689 format!(
690 "`{}` modifier was specified after another modifier (`{}`). Only a single \
691 modifier is allowed.",
692 current_modifier.long(db),
693 previous_modifier.long(db)
694 )
695 }
696 SemanticDiagnosticKind::ReferenceLocalVariable => {
697 "`ref` is only allowed for function parameters, not for local variables."
698 .to_string()
699 }
700 SemanticDiagnosticKind::InvalidCopyTraitImpl(inference_error) => {
701 format!("Invalid copy trait implementation, {}", inference_error.format(db))
702 }
703 SemanticDiagnosticKind::InvalidDropTraitImpl(inference_error) => {
704 format!("Invalid drop trait implementation, {}", inference_error.format(db))
705 }
706 SemanticDiagnosticKind::InvalidImplItem(item_kw) => {
707 format!("`{}` is not allowed inside impl.", item_kw.long(db))
708 }
709 SemanticDiagnosticKind::MissingItemsInImpl(item_names) => {
710 format!(
711 "Not all trait items are implemented. Missing: {}.",
712 item_names.iter().map(|name| format!("'{}'", name.long(db))).join(", ")
713 )
714 }
715 SemanticDiagnosticKind::PassPanicAsNopanic { impl_function_id, trait_id } => {
716 let name = impl_function_id.name(db).long(db);
717 let trait_name = trait_id.name(db).long(db);
718 format!(
719 "The signature of function `{name}` is incompatible with trait \
720 `{trait_name}`. The trait function is declared as nopanic."
721 )
722 }
723 SemanticDiagnosticKind::PassConstAsNonConst { impl_function_id, trait_id } => {
724 let name = impl_function_id.name(db).long(db);
725 let trait_name = trait_id.name(db).long(db);
726 format!(
727 "The signature of function `{name}` is incompatible with trait \
728 `{trait_name}`. The trait function is declared as const."
729 )
730 }
731 SemanticDiagnosticKind::PanicableFromNonPanicable => {
732 "Function is declared as nopanic but calls a function that may panic.".into()
733 }
734 SemanticDiagnosticKind::PanicableExternFunction => {
735 "An extern function must be marked as nopanic.".into()
736 }
737 SemanticDiagnosticKind::PluginDiagnostic(diagnostic) => {
738 format!("Plugin diagnostic: {}", diagnostic.message)
739 }
740 SemanticDiagnosticKind::MacroGeneratedCodeParserDiagnostic(parser_diagnostic) => {
741 format!("Parser error in macro-expanded code: {}", parser_diagnostic.format(db))
742 }
743 SemanticDiagnosticKind::NameDefinedMultipleTimes(name) => {
744 format!("The name `{}` is defined multiple times.", name.long(db))
745 }
746 SemanticDiagnosticKind::NonPrivateUseStar => {
747 "`pub` not supported for global `use`.".into()
748 }
749 SemanticDiagnosticKind::SelfGlobalUse => {
750 "cannot glob-import a module into itself".into()
751 }
752 SemanticDiagnosticKind::NamedArgumentsAreNotSupported => {
753 "Named arguments are not supported in this context.".into()
754 }
755 SemanticDiagnosticKind::UnnamedArgumentFollowsNamed => {
756 "Unnamed arguments cannot follow named arguments.".into()
757 }
758 SemanticDiagnosticKind::NamedArgumentMismatch { expected, found } => {
759 format!(
760 "Unexpected argument name. Expected: '{}', found '{}'.",
761 expected.long(db),
762 found.long(db)
763 )
764 }
765 SemanticDiagnosticKind::UnsupportedOutsideOfFunction(feature_name) => {
766 let feature_name_str = match feature_name {
767 UnsupportedOutsideOfFunctionFeatureName::ReturnStatement => "Return statement",
768 UnsupportedOutsideOfFunctionFeatureName::ErrorPropagate => "The '?' operator",
769 };
770 format!("{feature_name_str} is not supported outside of functions.")
771 }
772 SemanticDiagnosticKind::UnsupportedConstant => {
773 "This expression is not supported as constant.".into()
774 }
775 SemanticDiagnosticKind::FailedConstantCalculation => {
776 "Failed to calculate constant.".into()
777 }
778 SemanticDiagnosticKind::ConstantCalculationDepthExceeded => {
779 "Constant calculation depth exceeded.".into()
780 }
781 SemanticDiagnosticKind::InnerFailedConstantCalculation(inner, _) => inner.format(db),
782 SemanticDiagnosticKind::DivisionByZero => "Division by zero.".into(),
783 SemanticDiagnosticKind::ExternTypeWithImplGenericsNotSupported => {
784 "Extern types with impl generics are not supported.".into()
785 }
786 SemanticDiagnosticKind::MissingSemicolon => "Missing semicolon".into(),
787 SemanticDiagnosticKind::TraitMismatch { expected_trt, actual_trt } => {
788 format!(
789 "Expected an impl of `{:?}`. Got an impl of `{:?}`.",
790 expected_trt.debug(db),
791 actual_trt.debug(db),
792 )
793 }
794 SemanticDiagnosticKind::InternalInferenceError(err) => err.format(db),
795 SemanticDiagnosticKind::DerefNonRef { ty } => {
796 format!("Type `{}` cannot be dereferenced", ty.format(db))
797 }
798 SemanticDiagnosticKind::NoImplementationOfIndexOperator { ty, inference_errors } => {
799 if inference_errors.is_empty() {
800 format!(
801 "Type `{}` does not implement the `Index` trait nor the `IndexView` trait.",
802 ty.format(db)
803 )
804 } else {
805 format!(
806 "Type `{}` could not be indexed.\n{}",
807 ty.format(db),
808 inference_errors.format(db)
809 )
810 }
811 }
812 SemanticDiagnosticKind::MultipleImplementationOfIndexOperator(ty) => {
813 format!(
814 r#"Type "{}" implements both the "Index" trait and the "IndexView" trait."#,
815 ty.format(db)
816 )
817 }
818 SemanticDiagnosticKind::UnsupportedInlineArguments => {
819 "Unsupported `inline` arguments.".into()
820 }
821 SemanticDiagnosticKind::RedundantInlineAttribute => {
822 "Redundant `inline` attribute.".into()
823 }
824 SemanticDiagnosticKind::InlineAttrForExternFunctionNotAllowed => {
825 "`inline` attribute is not allowed for extern functions.".into()
826 }
827 SemanticDiagnosticKind::InlineAlwaysWithImplGenericArgNotAllowed => {
828 "`#[inline(always)]` is not allowed for functions with impl generic parameters."
829 .into()
830 }
831 SemanticDiagnosticKind::CannotCallMethod {
832 ty,
833 method_name,
834 inference_errors,
835 relevant_traits,
836 } => {
837 if !inference_errors.is_empty() {
838 return format!(
839 "Method `{}` could not be called on type `{}`.\n{}",
840 method_name.long(db),
841 ty.format(db),
842 inference_errors.format(db)
843 );
844 }
845 if !relevant_traits.is_empty() {
846 let suggestions = relevant_traits
847 .iter()
848 .map(|trait_path| format!("`{trait_path}`"))
849 .collect::<Vec<_>>()
850 .join(", ");
851
852 format!(
853 "Method `{}` not found on type `{}`. Consider importing one of the \
854 following traits: {}.",
855 method_name.long(db),
856 ty.format(db),
857 suggestions
858 )
859 } else {
860 format!(
861 "Method `{}` not found on type `{}`. Did you import the correct trait and \
862 impl?",
863 method_name.long(db),
864 ty.format(db)
865 )
866 }
867 }
868 SemanticDiagnosticKind::TailExpressionNotAllowedInLoop => {
869 "Tail expression not allowed in a `loop` block.".into()
870 }
871 SemanticDiagnosticKind::ContinueOnlyAllowedInsideALoop => {
872 "`continue` only allowed inside a `loop`.".into()
873 }
874 SemanticDiagnosticKind::BreakOnlyAllowedInsideALoop => {
875 "`break` only allowed inside a `loop`.".into()
876 }
877 SemanticDiagnosticKind::BreakWithValueOnlyAllowedInsideALoop => {
878 "Can only break with a value inside a `loop`.".into()
879 }
880 SemanticDiagnosticKind::ErrorPropagateNotAllowedInsideALoop => {
881 "`?` not allowed inside a `loop`.".into()
882 }
883 SemanticDiagnosticKind::ConstGenericParamNotSupported => {
884 "Const generic args are not allowed in this context.".into()
885 }
886 SemanticDiagnosticKind::NegativeImplsNotEnabled => {
887 "Negative impls are not enabled in the current crate.".into()
888 }
889 SemanticDiagnosticKind::NegativeImplsOnlyOnImpls => {
890 "Negative impls supported only in impl definitions.".into()
891 }
892 SemanticDiagnosticKind::ImplicitPrecedenceAttrForExternFunctionNotAllowed => {
893 "`implicit_precedence` attribute is not allowed for extern functions.".into()
894 }
895 SemanticDiagnosticKind::RedundantImplicitPrecedenceAttribute => {
896 "Redundant `implicit_precedence` attribute.".into()
897 }
898 SemanticDiagnosticKind::UnsupportedImplicitPrecedenceArguments => {
899 "Unsupported `implicit_precedence` arguments.".into()
900 }
901 SemanticDiagnosticKind::UnsupportedFeatureAttrArguments => {
902 "`feature` attribute argument should be a single string.".into()
903 }
904 SemanticDiagnosticKind::UnsupportedAllowAttrArguments => {
905 "`allow` attribute argument not supported.".into()
907 }
908 SemanticDiagnosticKind::UnsupportedPubArgument => "Unsupported `pub` argument.".into(),
909 SemanticDiagnosticKind::UnknownStatementAttribute => {
910 "Unknown statement attribute.".into()
911 }
912 SemanticDiagnosticKind::InlineMacroNotFound(macro_name) => {
913 format!("Inline macro `{}` not found.", macro_name.long(db))
914 }
915 SemanticDiagnosticKind::InlineMacroFailed(macro_name) => {
916 format!("Inline macro `{}` failed.", macro_name.long(db))
917 }
918 SemanticDiagnosticKind::InlineMacroNoMatchingRule(macro_name) => {
919 format!("No matching rule found in inline macro `{}`.", macro_name.long(db))
920 }
921 SemanticDiagnosticKind::MacroCallToNotAMacro(name) => {
922 format!("Call to `{}` which is not a macro.", name.long(db))
923 }
924 SemanticDiagnosticKind::UnknownGenericParam(name) => {
925 format!("Unknown generic parameter `{}`.", name.long(db))
926 }
927 SemanticDiagnosticKind::PositionalGenericAfterNamed => {
928 "Positional generic parameters must come before named generic parameters.".into()
929 }
930 SemanticDiagnosticKind::GenericArgDuplicate(name) => {
931 format!("Generic argument `{}` is specified more than once.", name.long(db))
932 }
933 SemanticDiagnosticKind::TooManyGenericArguments { expected, actual } => {
934 format!("Expected {expected} generic arguments, found {actual}.")
935 }
936 SemanticDiagnosticKind::GenericArgOutOfOrder(name) => {
937 format!("Generic argument `{}` is out of order.", name.long(db))
938 }
939 SemanticDiagnosticKind::ArgPassedToNegativeImpl => {
940 "Only `_` is valid as a negative impl argument.".into()
941 }
942 SemanticDiagnosticKind::CouponForExternFunctionNotAllowed => {
943 "Coupon cannot be used with extern functions.".into()
944 }
945 SemanticDiagnosticKind::CouponArgumentNoModifiers => {
946 "The __coupon__ argument cannot have modifiers.".into()
947 }
948 SemanticDiagnosticKind::CouponsDisabled => {
949 "Coupons are disabled in the current crate.\nYou can enable them by enabling the \
950 coupons experimental feature in the crate config."
951 .into()
952 }
953 SemanticDiagnosticKind::StructBaseStructExpressionNotLast => {
954 "The base struct must always be the last argument.".into()
955 }
956 SemanticDiagnosticKind::StructBaseStructExpressionNoEffect => {
957 "Base struct has no effect, all the fields in the struct have already been \
958 specified."
959 .into()
960 }
961 SemanticDiagnosticKind::FixedSizeArrayTypeNonSingleType => {
962 "Fixed size array type must have exactly one type.".into()
963 }
964 SemanticDiagnosticKind::FixedSizeArrayTypeEmptySize => {
965 "Fixed size array type must have a size clause.".into()
966 }
967 SemanticDiagnosticKind::FixedSizeArrayNonNumericSize => {
968 "Fixed size array type must have a positive integer size.".into()
969 }
970 SemanticDiagnosticKind::FixedSizeArrayNonSingleValue => {
971 "Fixed size array with defined size must have exactly one value.".into()
972 }
973 SemanticDiagnosticKind::FixedSizeArraySizeTooBig => {
974 "Fixed size array size must be smaller than 2^15.".into()
975 }
976 SemanticDiagnosticKind::SelfNotSupportedInContext => {
977 "`Self` is not supported in this context.".into()
978 }
979 SemanticDiagnosticKind::SelfMustBeFirst => {
980 "`Self` can only be the first segment of a path.".into()
981 }
982 SemanticDiagnosticKind::DollarNotSupportedInContext => {
983 "`$` is not supported in this context.".into()
984 }
985 SemanticDiagnosticKind::UnknownResolverModifier { modifier } => {
986 format!("`${}` is not supported.", modifier.long(db))
987 }
988 SemanticDiagnosticKind::EmptyPathAfterResolverModifier => {
989 "Expected path after modifier.".into()
990 }
991 SemanticDiagnosticKind::CannotCreateInstancesOfPhantomTypes => {
992 "Can not create instances of phantom types.".into()
993 }
994 SemanticDiagnosticKind::NonPhantomTypeContainingPhantomType => {
995 "Non-phantom type containing phantom type.".into()
996 }
997 SemanticDiagnosticKind::DerefCycle { deref_chain } => {
998 format!("Deref impls cycle detected:\n{deref_chain}")
999 }
1000 SemanticDiagnosticKind::NoImplementationOfTrait {
1001 ty,
1002 trait_name,
1003 inference_errors,
1004 } => {
1005 if inference_errors.is_empty() {
1006 format!(
1007 "Implementation of trait `{}` not found on type `{}`. Did you import the \
1008 correct trait and impl?",
1009 trait_name.long(db),
1010 ty.format(db)
1011 )
1012 } else {
1013 format!(
1014 "Could not find implementation of trait `{}` on type `{}`.\n{}",
1015 trait_name.long(db),
1016 ty.format(db),
1017 inference_errors.format(db)
1018 )
1019 }
1020 }
1021 SemanticDiagnosticKind::CallExpressionRequiresFunction { ty, inference_errors } => {
1022 if inference_errors.is_empty() {
1023 format!("Call expression requires a function, found `{}`.", ty.format(db))
1024 } else {
1025 format!(
1026 "Call expression requires a function, found `{}`.\n{}",
1027 ty.format(db),
1028 inference_errors.format(db)
1029 )
1030 }
1031 }
1032 SemanticDiagnosticKind::CompilerTraitReImplementation { trait_id } => {
1033 format!(
1034 "Trait `{}` should not be implemented outside of the corelib.",
1035 trait_id.full_path(db)
1036 )
1037 }
1038 SemanticDiagnosticKind::ClosureInGlobalScope => {
1039 "Closures are not allowed in this context.".into()
1040 }
1041 SemanticDiagnosticKind::MaybeMissingColonColon => "Are you missing a `::`?.".into(),
1042 SemanticDiagnosticKind::CallingShadowedFunction { shadowed_function_name } => {
1043 format!(
1044 "Function `{}` is shadowed by a local variable.",
1045 shadowed_function_name.long(db)
1046 )
1047 }
1048 SemanticDiagnosticKind::RefClosureArgument => {
1049 "Arguments to closure functions cannot be references".into()
1050 }
1051 SemanticDiagnosticKind::RefClosureParam => {
1052 "Closure parameters cannot be references".into()
1053 }
1054 SemanticDiagnosticKind::MustBeNextToTypeOrTrait { trait_id } => {
1055 format!(
1056 "'{}' implementation must be defined in the same module as either the type \
1057 being dereferenced or the trait itself",
1058 trait_id.name(db).long(db)
1059 )
1060 }
1061 SemanticDiagnosticKind::MutableCapturedVariable => {
1062 "Capture of mutable variables in a closure is not supported".into()
1063 }
1064 SemanticDiagnosticKind::NonTraitTypeConstrained { identifier, concrete_trait_id } => {
1065 format!(
1066 "associated type `{}` not found for `{}`",
1067 identifier.long(db),
1068 concrete_trait_id.full_path(db)
1069 )
1070 }
1071 SemanticDiagnosticKind::DuplicateTypeConstraint {
1072 concrete_trait_type_id: trait_type_id,
1073 } => {
1074 format!(
1075 "the value of the associated type `{}` in trait `{}` is already specified",
1076 trait_type_id.trait_type(db).name(db).long(db),
1077 trait_type_id.concrete_trait(db).full_path(db)
1078 )
1079 }
1080 SemanticDiagnosticKind::TypeConstraintsSyntaxNotEnabled => {
1081 "Type constraints syntax is not enabled in the current crate.".into()
1082 }
1083 SemanticDiagnosticKind::PatternMissingArgs(path) => {
1084 format!(
1085 "Pattern missing subpattern for the payload of variant. Consider using `{}(_)`",
1086 path.segments(db)
1087 .elements(db)
1088 .map(|seg| seg.identifier(db).long(db))
1089 .join("::")
1090 )
1091 }
1092 SemanticDiagnosticKind::UndefinedMacroPlaceholder(name) => {
1093 format!("Undefined macro placeholder: '{}'.", name.long(db))
1094 }
1095 SemanticDiagnosticKind::UserDefinedInlineMacrosDisabled => {
1096 "User defined inline macros are disabled in the current crate.".into()
1097 }
1098 SemanticDiagnosticKind::NonNeverLetElseType => concat!(
1099 "`else` clause of `let...else` must exit the scope. ",
1100 "Consider using `return`, `continue`, ..."
1101 )
1102 .into(),
1103 }
1104 }
1105 fn location(&self, db: &'db dyn Database) -> DiagnosticLocation<'db> {
1106 if let SemanticDiagnosticKind::MacroGeneratedCodeParserDiagnostic(parser_diagnostic) =
1107 &self.kind
1108 {
1109 return DiagnosticLocation {
1110 file_id: parser_diagnostic.file_id,
1111 span: parser_diagnostic.span,
1112 };
1113 };
1114
1115 let mut location = self.stable_location.diagnostic_location(db);
1116 if self.after {
1117 location = location.after();
1118 }
1119 location
1120 }
1121
1122 fn severity(&self) -> Severity {
1123 match &self.kind {
1124 SemanticDiagnosticKind::UnusedVariable
1125 | SemanticDiagnosticKind::UnhandledMustUseType { .. }
1126 | SemanticDiagnosticKind::UnhandledMustUseFunction
1127 | SemanticDiagnosticKind::TraitInTraitMustBeExplicit
1128 | SemanticDiagnosticKind::ImplInImplMustBeExplicit
1129 | SemanticDiagnosticKind::TraitItemForbiddenInTheTrait
1130 | SemanticDiagnosticKind::TraitItemForbiddenInItsImpl
1131 | SemanticDiagnosticKind::ImplItemForbiddenInTheImpl
1132 | SemanticDiagnosticKind::UnstableFeature { .. }
1133 | SemanticDiagnosticKind::DeprecatedFeature { .. }
1134 | SemanticDiagnosticKind::UnusedImport { .. }
1135 | SemanticDiagnosticKind::CallingShadowedFunction { .. }
1136 | SemanticDiagnosticKind::UnusedConstant
1137 | SemanticDiagnosticKind::UnusedUse
1138 | SemanticDiagnosticKind::PatternMissingArgs(_)
1139 | SemanticDiagnosticKind::UnsupportedAllowAttrArguments => Severity::Warning,
1140 SemanticDiagnosticKind::PluginDiagnostic(diag) => diag.severity,
1141 _ => Severity::Error,
1142 }
1143 }
1144
1145 fn notes(&self, _db: &dyn Database) -> &[DiagnosticNote<'_>] {
1146 if let SemanticDiagnosticKind::InnerFailedConstantCalculation(_, notes) = &self.kind {
1147 notes
1148 } else {
1149 &[]
1150 }
1151 }
1152
1153 fn error_code(&self) -> Option<ErrorCode> {
1154 self.kind.error_code()
1155 }
1156
1157 fn is_same_kind(&self, other: &Self) -> bool {
1158 other.kind == self.kind
1159 }
1160}
1161
1162#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1163pub enum SemanticDiagnosticKind<'db> {
1164 ModuleFileNotFound(String),
1165 Unsupported,
1166 UnknownLiteral,
1167 UnknownBinaryOperator,
1168 UnknownTrait,
1169 UnknownImpl,
1170 UnexpectedElement {
1171 expected: Vec<ElementKind>,
1172 actual: ElementKind,
1173 },
1174 UnknownType,
1175 UnknownEnum,
1176 LiteralError(LiteralError<'db>),
1177 NotAVariant,
1178 NotAStruct,
1179 NotAType,
1180 NotATrait,
1181 NotAnImpl,
1182 ImplItemNotInTrait {
1183 impl_def_id: ImplDefId<'db>,
1184 impl_item_name: SmolStrId<'db>,
1185 trait_id: TraitId<'db>,
1186 item_kind: String,
1187 },
1188 ImplicitImplNotInferred {
1189 trait_impl_id: TraitImplId<'db>,
1190 concrete_trait_id: ConcreteTraitId<'db>,
1191 },
1192 GenericsNotSupportedInItem {
1193 scope: String,
1194 item_kind: String,
1195 },
1196 UnexpectedGenericArgs,
1197 UnknownMember,
1198 CannotCreateInstancesOfPhantomTypes,
1199 NonPhantomTypeContainingPhantomType,
1200 MemberSpecifiedMoreThanOnce,
1201 StructBaseStructExpressionNotLast,
1202 StructBaseStructExpressionNoEffect,
1203 ConstCycle,
1204 UseCycle,
1205 TypeAliasCycle,
1206 ImplAliasCycle,
1207 ImplRequirementCycle,
1208 MissingMember(SmolStrId<'db>),
1209 WrongNumberOfParameters {
1210 impl_def_id: ImplDefId<'db>,
1211 impl_function_id: ImplFunctionId<'db>,
1212 trait_id: TraitId<'db>,
1213 expected: usize,
1214 actual: usize,
1215 },
1216 WrongNumberOfArguments {
1217 expected: usize,
1218 actual: usize,
1219 },
1220 WrongParameterType {
1221 impl_def_id: ImplDefId<'db>,
1222 impl_function_id: ImplFunctionId<'db>,
1223 trait_id: TraitId<'db>,
1224 expected_ty: semantic::TypeId<'db>,
1225 actual_ty: semantic::TypeId<'db>,
1226 },
1227 VariantCtorNotImmutable,
1228 TraitParamMutable {
1229 trait_id: TraitId<'db>,
1230 function_id: TraitFunctionId<'db>,
1231 },
1232 ParameterShouldBeReference {
1233 impl_def_id: ImplDefId<'db>,
1234 impl_function_id: ImplFunctionId<'db>,
1235 trait_id: TraitId<'db>,
1236 },
1237 ParameterShouldNotBeReference {
1238 impl_def_id: ImplDefId<'db>,
1239 impl_function_id: ImplFunctionId<'db>,
1240 trait_id: TraitId<'db>,
1241 },
1242 WrongParameterName {
1243 impl_def_id: ImplDefId<'db>,
1244 impl_function_id: ImplFunctionId<'db>,
1245 trait_id: TraitId<'db>,
1246 expected_name: SmolStrId<'db>,
1247 },
1248 WrongGenericParamTraitForImplFunction {
1249 impl_def_id: ImplDefId<'db>,
1250 impl_function_id: ImplFunctionId<'db>,
1251 trait_id: TraitId<'db>,
1252 expected_trait: ConcreteTraitId<'db>,
1253 actual_trait: ConcreteTraitId<'db>,
1254 },
1255 WrongGenericParamKindForImplFunction {
1256 impl_def_id: ImplDefId<'db>,
1257 impl_function_id: ImplFunctionId<'db>,
1258 trait_id: TraitId<'db>,
1259 expected_kind: GenericKind,
1260 actual_kind: GenericKind,
1261 },
1262 WrongType {
1263 expected_ty: semantic::TypeId<'db>,
1264 actual_ty: semantic::TypeId<'db>,
1265 },
1266 InconsistentBinding,
1267 WrongArgumentType {
1268 expected_ty: semantic::TypeId<'db>,
1269 actual_ty: semantic::TypeId<'db>,
1270 },
1271 WrongReturnType {
1272 expected_ty: semantic::TypeId<'db>,
1273 actual_ty: semantic::TypeId<'db>,
1274 },
1275 WrongExprType {
1276 expected_ty: semantic::TypeId<'db>,
1277 actual_ty: semantic::TypeId<'db>,
1278 },
1279 WrongNumberOfGenericParamsForImplFunction {
1280 expected: usize,
1281 actual: usize,
1282 },
1283 WrongReturnTypeForImpl {
1284 impl_def_id: ImplDefId<'db>,
1285 impl_function_id: ImplFunctionId<'db>,
1286 trait_id: TraitId<'db>,
1287 expected_ty: semantic::TypeId<'db>,
1288 actual_ty: semantic::TypeId<'db>,
1289 },
1290 AmbiguousTrait {
1291 trait_function_id0: TraitFunctionId<'db>,
1292 trait_function_id1: TraitFunctionId<'db>,
1293 },
1294 VariableNotFound(SmolStrId<'db>),
1295 MissingVariableInPattern,
1296 StructMemberRedefinition {
1297 struct_id: StructId<'db>,
1298 member_name: SmolStrId<'db>,
1299 },
1300 EnumVariantRedefinition {
1301 enum_id: EnumId<'db>,
1302 variant_name: SmolStrId<'db>,
1303 },
1304 InfiniteSizeType(semantic::TypeId<'db>),
1305 ArrayOfZeroSizedElements(semantic::TypeId<'db>),
1306 ParamNameRedefinition {
1307 function_title_id: Option<FunctionTitleId<'db>>,
1308 param_name: SmolStrId<'db>,
1309 },
1310 ConditionNotBool(semantic::TypeId<'db>),
1311 IncompatibleArms {
1312 multi_arm_expr_kind: MultiArmExprKind,
1313 pending_ty: semantic::TypeId<'db>,
1314 different_ty: semantic::TypeId<'db>,
1315 },
1316 TypeHasNoMembers {
1317 ty: semantic::TypeId<'db>,
1318 member_name: SmolStrId<'db>,
1319 },
1320 CannotCallMethod {
1321 ty: semantic::TypeId<'db>,
1322 method_name: SmolStrId<'db>,
1323 inference_errors: TraitInferenceErrors<'db>,
1324 relevant_traits: Vec<String>,
1325 },
1326 NoSuchStructMember {
1327 struct_id: StructId<'db>,
1328 member_name: SmolStrId<'db>,
1329 },
1330 NoSuchTypeMember {
1331 ty: semantic::TypeId<'db>,
1332 member_name: SmolStrId<'db>,
1333 },
1334 MemberNotVisible(SmolStrId<'db>),
1335 NoSuchVariant {
1336 enum_id: EnumId<'db>,
1337 variant_name: SmolStrId<'db>,
1338 },
1339 ReturnTypeNotErrorPropagateType,
1340 IncompatibleErrorPropagateType {
1341 return_ty: semantic::TypeId<'db>,
1342 err_ty: semantic::TypeId<'db>,
1343 },
1344 ErrorPropagateOnNonErrorType(semantic::TypeId<'db>),
1345 UnhandledMustUseType(semantic::TypeId<'db>),
1346 UnstableFeature {
1347 feature_name: SmolStrId<'db>,
1348 note: Option<SmolStrId<'db>>,
1349 },
1350 DeprecatedFeature {
1351 feature_name: SmolStrId<'db>,
1352 note: Option<SmolStrId<'db>>,
1353 },
1354 InternalFeature {
1355 feature_name: SmolStrId<'db>,
1356 note: Option<SmolStrId<'db>>,
1357 },
1358 FeatureMarkerDiagnostic(FeatureMarkerDiagnostic),
1359 UnhandledMustUseFunction,
1360 UnusedVariable,
1361 UnusedConstant,
1362 UnusedUse,
1363 MultipleConstantDefinition(SmolStrId<'db>),
1364 MultipleDefinitionforBinding(SmolStrId<'db>),
1365 MultipleGenericItemDefinition(SmolStrId<'db>),
1366 UnsupportedUseItemInStatement,
1367 ConstGenericParamNotSupported,
1368 NegativeImplsNotEnabled,
1369 NegativeImplsOnlyOnImpls,
1370 RefArgNotAVariable,
1371 RefArgNotMutable,
1372 RefArgNotExplicit,
1373 ImmutableArgWithModifiers,
1374 AssignmentToImmutableVar,
1375 InvalidLhsForAssignment,
1376 InvalidMemberExpression,
1377 InvalidPath,
1378 PathNotFound(NotFoundItemType),
1379 AmbiguousPath(Vec<ModuleItemId<'db>>),
1380 UseSelfNonMulti,
1381 UseSelfEmptyPath,
1382 UseStarEmptyPath,
1383 GlobalUsesNotSupportedInEdition(Edition),
1384 TraitInTraitMustBeExplicit,
1385 ImplInImplMustBeExplicit,
1386 TraitItemForbiddenInTheTrait,
1387 TraitItemForbiddenInItsImpl,
1388 ImplItemForbiddenInTheImpl,
1389 SuperUsedInRootModule,
1390 SuperUsedInMacroCallTopLevel,
1391 ItemNotVisible(ModuleItemId<'db>, Vec<ModuleId<'db>>),
1392 UnusedImport(UseId<'db>),
1393 RedundantModifier {
1394 current_modifier: SmolStrId<'db>,
1395 previous_modifier: SmolStrId<'db>,
1396 },
1397 ReferenceLocalVariable,
1398 UnexpectedEnumPattern(semantic::TypeId<'db>),
1399 UnexpectedStructPattern(semantic::TypeId<'db>),
1400 UnexpectedTuplePattern(semantic::TypeId<'db>),
1401 UnexpectedFixedSizeArrayPattern(semantic::TypeId<'db>),
1402 WrongNumberOfTupleElements {
1403 expected: usize,
1404 actual: usize,
1405 },
1406 WrongNumberOfFixedSizeArrayElements {
1407 expected: usize,
1408 actual: usize,
1409 },
1410 WrongEnum {
1411 expected_enum: EnumId<'db>,
1412 actual_enum: EnumId<'db>,
1413 },
1414 InvalidCopyTraitImpl(InferenceError<'db>),
1415 InvalidDropTraitImpl(InferenceError<'db>),
1416 InvalidImplItem(SmolStrId<'db>),
1417 MissingItemsInImpl(Vec<SmolStrId<'db>>),
1418 PassPanicAsNopanic {
1419 impl_function_id: ImplFunctionId<'db>,
1420 trait_id: TraitId<'db>,
1421 },
1422 PassConstAsNonConst {
1423 impl_function_id: ImplFunctionId<'db>,
1424 trait_id: TraitId<'db>,
1425 },
1426 PanicableFromNonPanicable,
1427 PanicableExternFunction,
1428 MacroGeneratedCodeParserDiagnostic(ParserDiagnostic<'db>),
1429 PluginDiagnostic(PluginDiagnostic<'db>),
1430 NameDefinedMultipleTimes(SmolStrId<'db>),
1431 NonPrivateUseStar,
1432 SelfGlobalUse,
1433 NamedArgumentsAreNotSupported,
1434 ArgPassedToNegativeImpl,
1435 UnnamedArgumentFollowsNamed,
1436 NamedArgumentMismatch {
1437 expected: SmolStrId<'db>,
1438 found: SmolStrId<'db>,
1439 },
1440 UnsupportedOutsideOfFunction(UnsupportedOutsideOfFunctionFeatureName),
1441 UnsupportedConstant,
1442 FailedConstantCalculation,
1443 ConstantCalculationDepthExceeded,
1444 InnerFailedConstantCalculation(Box<SemanticDiagnostic<'db>>, Vec<DiagnosticNote<'db>>),
1445 DivisionByZero,
1446 ExternTypeWithImplGenericsNotSupported,
1447 MissingSemicolon,
1448 TraitMismatch {
1449 expected_trt: semantic::ConcreteTraitId<'db>,
1450 actual_trt: semantic::ConcreteTraitId<'db>,
1451 },
1452 DerefNonRef {
1453 ty: semantic::TypeId<'db>,
1454 },
1455 InternalInferenceError(InferenceError<'db>),
1456 NoImplementationOfIndexOperator {
1457 ty: semantic::TypeId<'db>,
1458 inference_errors: TraitInferenceErrors<'db>,
1459 },
1460 NoImplementationOfTrait {
1461 ty: semantic::TypeId<'db>,
1462 trait_name: SmolStrId<'db>,
1463 inference_errors: TraitInferenceErrors<'db>,
1464 },
1465 CallExpressionRequiresFunction {
1466 ty: semantic::TypeId<'db>,
1467 inference_errors: TraitInferenceErrors<'db>,
1468 },
1469 MultipleImplementationOfIndexOperator(semantic::TypeId<'db>),
1470
1471 UnsupportedInlineArguments,
1472 RedundantInlineAttribute,
1473 InlineAttrForExternFunctionNotAllowed,
1474 InlineAlwaysWithImplGenericArgNotAllowed,
1475 TailExpressionNotAllowedInLoop,
1476 ContinueOnlyAllowedInsideALoop,
1477 BreakOnlyAllowedInsideALoop,
1478 BreakWithValueOnlyAllowedInsideALoop,
1479 ErrorPropagateNotAllowedInsideALoop,
1480 ImplicitPrecedenceAttrForExternFunctionNotAllowed,
1481 RedundantImplicitPrecedenceAttribute,
1482 UnsupportedImplicitPrecedenceArguments,
1483 UnsupportedFeatureAttrArguments,
1484 UnsupportedAllowAttrArguments,
1485 UnsupportedPubArgument,
1486 UnknownStatementAttribute,
1487 InlineMacroNotFound(SmolStrId<'db>),
1488 InlineMacroFailed(SmolStrId<'db>),
1489 InlineMacroNoMatchingRule(SmolStrId<'db>),
1490 MacroCallToNotAMacro(SmolStrId<'db>),
1491 UnknownGenericParam(SmolStrId<'db>),
1492 PositionalGenericAfterNamed,
1493 GenericArgDuplicate(SmolStrId<'db>),
1494 TooManyGenericArguments {
1495 expected: usize,
1496 actual: usize,
1497 },
1498 GenericArgOutOfOrder(SmolStrId<'db>),
1499 CouponForExternFunctionNotAllowed,
1500 CouponArgumentNoModifiers,
1501 CouponsDisabled,
1503 FixedSizeArrayTypeNonSingleType,
1504 FixedSizeArrayTypeEmptySize,
1505 FixedSizeArrayNonNumericSize,
1506 FixedSizeArrayNonSingleValue,
1507 FixedSizeArraySizeTooBig,
1508 SelfNotSupportedInContext,
1509 SelfMustBeFirst,
1510 DollarNotSupportedInContext,
1511 UnknownResolverModifier {
1512 modifier: SmolStrId<'db>,
1513 },
1514 EmptyPathAfterResolverModifier,
1515 DerefCycle {
1516 deref_chain: String,
1517 },
1518 CompilerTraitReImplementation {
1519 trait_id: TraitId<'db>,
1520 },
1521 ClosureInGlobalScope,
1522 MaybeMissingColonColon,
1523 CallingShadowedFunction {
1524 shadowed_function_name: SmolStrId<'db>,
1525 },
1526 RefClosureArgument,
1527 RefClosureParam,
1528 MustBeNextToTypeOrTrait {
1529 trait_id: TraitId<'db>,
1530 },
1531 MutableCapturedVariable,
1532 NonTraitTypeConstrained {
1533 identifier: SmolStrId<'db>,
1534 concrete_trait_id: ConcreteTraitId<'db>,
1535 },
1536 DuplicateTypeConstraint {
1537 concrete_trait_type_id: ConcreteTraitTypeId<'db>,
1538 },
1539 TypeConstraintsSyntaxNotEnabled,
1540 PatternMissingArgs(ast::ExprPath<'db>),
1541 UndefinedMacroPlaceholder(SmolStrId<'db>),
1542 UserDefinedInlineMacrosDisabled,
1543 NonNeverLetElseType,
1544}
1545
1546#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1548pub enum MultiArmExprKind {
1549 If,
1550 Match,
1551 Loop,
1552}
1553
1554impl<'db> SemanticDiagnosticKind<'db> {
1555 pub fn error_code(&self) -> Option<ErrorCode> {
1556 Some(match &self {
1557 Self::UnusedVariable => error_code!(E0001),
1558 Self::CannotCallMethod { .. } => {
1559 error_code!(E0002)
1560 }
1561 Self::MissingMember(_) => error_code!(E0003),
1562 Self::MissingItemsInImpl(_) => error_code!(E0004),
1563 Self::ModuleFileNotFound(_) => error_code!(E0005),
1564 Self::PathNotFound(_) => error_code!(E0006),
1565 Self::NoSuchTypeMember { .. } => error_code!(E0007),
1566 _ => return None,
1567 })
1568 }
1569}
1570
1571#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1573pub enum NotFoundItemType {
1574 Identifier,
1575 Function,
1576 Type,
1577 Trait,
1578 Impl,
1579 Macro,
1580}
1581
1582#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1583pub enum UnsupportedOutsideOfFunctionFeatureName {
1584 ReturnStatement,
1585 ErrorPropagate,
1586}
1587
1588#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1589pub enum ElementKind {
1590 Constant,
1591 Variable,
1592 Module,
1593 Function,
1594 Type,
1595 Variant,
1596 Trait,
1597 Impl,
1598 Macro,
1599}
1600impl<'db> From<&ResolvedConcreteItem<'db>> for ElementKind {
1601 fn from(val: &ResolvedConcreteItem<'db>) -> Self {
1602 match val {
1603 ResolvedConcreteItem::Constant(_) => ElementKind::Constant,
1604 ResolvedConcreteItem::Module(_) => ElementKind::Module,
1605 ResolvedConcreteItem::Function(_) => ElementKind::Function,
1606 ResolvedConcreteItem::Type(_) => ElementKind::Type,
1607 ResolvedConcreteItem::Variant(_) => ElementKind::Variant,
1608 ResolvedConcreteItem::Trait(_) | ResolvedConcreteItem::SelfTrait(_) => {
1609 ElementKind::Trait
1610 }
1611 ResolvedConcreteItem::Impl(_) => ElementKind::Impl,
1612 ResolvedConcreteItem::Macro(_) => ElementKind::Macro,
1613 }
1614 }
1615}
1616impl<'db> From<&ResolvedGenericItem<'db>> for ElementKind {
1617 fn from(val: &ResolvedGenericItem<'db>) -> Self {
1618 match val {
1619 ResolvedGenericItem::GenericConstant(_)
1620 | ResolvedGenericItem::TraitItem(TraitItemId::Constant(_)) => ElementKind::Constant,
1621 ResolvedGenericItem::Module(_) => ElementKind::Module,
1622 ResolvedGenericItem::GenericFunction(_)
1623 | ResolvedGenericItem::TraitItem(TraitItemId::Function(_)) => ElementKind::Function,
1624 ResolvedGenericItem::GenericType(_)
1625 | ResolvedGenericItem::GenericTypeAlias(_)
1626 | ResolvedGenericItem::TraitItem(TraitItemId::Type(_)) => ElementKind::Type,
1627 ResolvedGenericItem::Variant(_) => ElementKind::Variant,
1628 ResolvedGenericItem::Trait(_) => ElementKind::Trait,
1629 ResolvedGenericItem::Impl(_)
1630 | ResolvedGenericItem::GenericImplAlias(_)
1631 | ResolvedGenericItem::TraitItem(TraitItemId::Impl(_)) => ElementKind::Impl,
1632 ResolvedGenericItem::Variable(_) => ElementKind::Variable,
1633 ResolvedGenericItem::Macro(_) => ElementKind::Macro,
1634 }
1635 }
1636}
1637impl Display for ElementKind {
1638 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1639 let res = match self {
1640 ElementKind::Constant => "constant",
1641 ElementKind::Variable => "variable",
1642 ElementKind::Module => "module",
1643 ElementKind::Function => "function",
1644 ElementKind::Type => "type",
1645 ElementKind::Variant => "variant",
1646 ElementKind::Trait => "trait",
1647 ElementKind::Impl => "impl",
1648 ElementKind::Macro => "macro",
1649 };
1650 write!(f, "{res}")
1651 }
1652}
1653
1654#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1656pub struct TraitInferenceErrors<'db> {
1657 pub traits_and_errors: Vec<(TraitFunctionId<'db>, InferenceError<'db>)>,
1658}
1659impl<'db> TraitInferenceErrors<'db> {
1660 pub fn is_empty(&self) -> bool {
1662 self.traits_and_errors.is_empty()
1663 }
1664 fn format(&self, db: &dyn Database) -> String {
1666 self.traits_and_errors
1667 .iter()
1668 .map(|(trait_function_id, inference_error)| {
1669 format!(
1670 "Candidate `{}` inference failed with: {}",
1671 trait_function_id.full_path(db),
1672 inference_error.format(db)
1673 )
1674 })
1675 .join("\n")
1676 }
1677}