Skip to main content

cairo_lang_semantic/
diagnostic.rs

1use std::fmt::Display;
2use std::ops::{Deref, DerefMut};
3
4use cairo_lang_debug::DebugWithDb;
5use cairo_lang_defs::diagnostic_utils::StableLocation;
6use cairo_lang_defs::ids::{
7    EnumId, FunctionTitleId, GenericKind, ImplDefId, ImplFunctionId, ModuleId, ModuleItemId,
8    NamedLanguageElementId, StructId, TopLevelLanguageElementId, TraitFunctionId, TraitId,
9    TraitImplId, TraitItemId, UseId,
10};
11use cairo_lang_defs::plugin::PluginDiagnostic;
12use cairo_lang_diagnostics::{
13    DiagnosticAdded, DiagnosticEntry, DiagnosticNote, Diagnostics, DiagnosticsBuilder, ErrorCode,
14    Severity, error_code,
15};
16use cairo_lang_filesystem::db::Edition;
17use cairo_lang_filesystem::ids::{SmolStrId, SpanInFile};
18use cairo_lang_filesystem::span::TextWidth;
19use cairo_lang_parser::ParserDiagnostic;
20use cairo_lang_syntax as syntax;
21use cairo_lang_syntax::node::ast;
22use cairo_lang_syntax::node::helpers::GetIdentifier;
23use itertools::Itertools;
24use salsa::Database;
25use syntax::node::ids::SyntaxStablePtrId;
26
27use crate::corelib::LiteralError;
28use crate::expr::inference::InferenceError;
29use crate::items::feature_kind::FeatureMarkerDiagnostic;
30use crate::items::trt::ConcreteTraitTypeId;
31use crate::path::ContextualizePath;
32use crate::resolve::{ResolvedConcreteItem, ResolvedGenericItem};
33use crate::types::peel_snapshots;
34use crate::{ConcreteTraitId, semantic};
35
36#[cfg(test)]
37#[path = "diagnostic_test.rs"]
38mod test;
39
40/// A diagnostics builder with module context for semantic diagnostics.
41pub struct SemanticDiagnostics<'db> {
42    builder: DiagnosticsBuilder<'db, SemanticDiagnostic<'db>>,
43    context_module: ModuleId<'db>,
44}
45
46impl<'db> SemanticDiagnostics<'db> {
47    /// Create a new SemanticDiagnostics with the given context module.
48    pub fn new(context_module: ModuleId<'db>) -> Self {
49        Self { builder: DiagnosticsBuilder::default(), context_module }
50    }
51
52    /// Create a new SemanticDiagnostics from the given context module and diagnostics.
53    pub fn from_diagnostics(
54        context_module: ModuleId<'db>,
55        diagnostics: Diagnostics<'db, SemanticDiagnostic<'db>>,
56    ) -> Self {
57        let mut builder = DiagnosticsBuilder::default();
58        builder.extend(diagnostics);
59        Self { builder, context_module }
60    }
61
62    /// Build a Diagnostics object.
63    pub fn build(self) -> Diagnostics<'db, SemanticDiagnostic<'db>> {
64        self.builder.build()
65    }
66}
67
68impl<'db> Deref for SemanticDiagnostics<'db> {
69    type Target = DiagnosticsBuilder<'db, SemanticDiagnostic<'db>>;
70
71    fn deref(&self) -> &Self::Target {
72        &self.builder
73    }
74}
75
76impl<'db> DerefMut for SemanticDiagnostics<'db> {
77    fn deref_mut(&mut self) -> &mut Self::Target {
78        &mut self.builder
79    }
80}
81
82pub trait SemanticDiagnosticsBuilder<'db> {
83    /// Report a diagnostic in the location of the given ptr.
84    fn report(
85        &mut self,
86        stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
87        kind: SemanticDiagnosticKind<'db>,
88    ) -> DiagnosticAdded;
89    /// Report a diagnostic in the location after the given ptr (with width 0).
90    fn report_after(
91        &mut self,
92        stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
93        kind: SemanticDiagnosticKind<'db>,
94    ) -> DiagnosticAdded;
95    /// Report a diagnostic in a sub-span of the location of the given ptr. The inner span is
96    /// specified by an offset from the start of the pointer location and a width.
97    fn report_with_inner_span(
98        &mut self,
99        stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
100        inner_span: (TextWidth, TextWidth),
101        kind: SemanticDiagnosticKind<'db>,
102    ) -> DiagnosticAdded;
103}
104impl<'db> SemanticDiagnosticsBuilder<'db> for SemanticDiagnostics<'db> {
105    fn report(
106        &mut self,
107        stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
108        kind: SemanticDiagnosticKind<'db>,
109    ) -> DiagnosticAdded {
110        self.builder.add(SemanticDiagnostic::new(
111            StableLocation::new(stable_ptr.into()),
112            kind,
113            self.context_module,
114        ))
115    }
116    fn report_after(
117        &mut self,
118        stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
119        kind: SemanticDiagnosticKind<'db>,
120    ) -> DiagnosticAdded {
121        self.builder.add(SemanticDiagnostic::new_after(
122            StableLocation::new(stable_ptr.into()),
123            kind,
124            self.context_module,
125        ))
126    }
127    fn report_with_inner_span(
128        &mut self,
129        stable_ptr: impl Into<SyntaxStablePtrId<'db>>,
130        inner_span: (TextWidth, TextWidth),
131        kind: SemanticDiagnosticKind<'db>,
132    ) -> DiagnosticAdded {
133        self.builder.add(SemanticDiagnostic::new(
134            StableLocation::with_inner_span(stable_ptr.into(), inner_span),
135            kind,
136            self.context_module,
137        ))
138    }
139}
140
141#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
142pub struct SemanticDiagnostic<'db> {
143    pub stable_location: StableLocation<'db>,
144    pub kind: SemanticDiagnosticKind<'db>,
145    /// true if the diagnostic should be reported *after* the given location. Normally false, in
146    /// which case the diagnostic points to the given location (as-is).
147    pub after: bool,
148    /// The module context in which this diagnostic was reported.
149    pub context_module: ModuleId<'db>,
150}
151impl<'db> SemanticDiagnostic<'db> {
152    /// Create a diagnostic in the given location.
153    pub fn new(
154        stable_location: StableLocation<'db>,
155        kind: SemanticDiagnosticKind<'db>,
156        context_module: ModuleId<'db>,
157    ) -> Self {
158        SemanticDiagnostic { stable_location, kind, after: false, context_module }
159    }
160    /// Create a diagnostic in the location after the given location (with width 0).
161    pub fn new_after(
162        stable_location: StableLocation<'db>,
163        kind: SemanticDiagnosticKind<'db>,
164        context_module: ModuleId<'db>,
165    ) -> Self {
166        SemanticDiagnostic { stable_location, kind, after: true, context_module }
167    }
168}
169impl<'db> DiagnosticEntry<'db> for SemanticDiagnostic<'db> {
170    fn format(&self, db: &dyn Database) -> String {
171        match &self.kind {
172            SemanticDiagnosticKind::ModuleFileNotFound(path) => {
173                format!("Module file not found. Expected path: {path}")
174            }
175            SemanticDiagnosticKind::Unsupported => "Unsupported feature.".into(),
176            SemanticDiagnosticKind::UnknownLiteral => "Unknown literal.".into(),
177            SemanticDiagnosticKind::UnknownBinaryOperator => "Unknown binary operator.".into(),
178            SemanticDiagnosticKind::UnknownTrait => "Unknown trait.".into(),
179            SemanticDiagnosticKind::UnknownImpl => "Unknown impl.".into(),
180            SemanticDiagnosticKind::UnexpectedElement { expected, actual } => {
181                let expected_str = expected.iter().map(|kind| kind.to_string()).join(" or ");
182                format!("Expected {expected_str}, found {actual}.")
183            }
184            SemanticDiagnosticKind::UnknownType => "Unknown type.".into(),
185            SemanticDiagnosticKind::UnknownEnum => "Unknown enum.".into(),
186            SemanticDiagnosticKind::LiteralError(literal_error) => literal_error.format(db),
187            SemanticDiagnosticKind::NotAVariant => {
188                "Not a variant. Use the full name Enum::Variant.".into()
189            }
190            SemanticDiagnosticKind::NotAStruct => "Not a struct.".into(),
191            SemanticDiagnosticKind::NotAType => "Not a type.".into(),
192            SemanticDiagnosticKind::NotATrait => "Not a trait.".into(),
193            SemanticDiagnosticKind::NotAnImpl => "Not an impl.".into(),
194            SemanticDiagnosticKind::ImplItemNotInTrait {
195                impl_def_id,
196                impl_item_name,
197                trait_id,
198                item_kind,
199            } => {
200                format!(
201                    "Impl item {item_kind} `{}::{}` is not a member of trait `{}`.",
202                    impl_def_id.name(db).long(db),
203                    impl_item_name.long(db),
204                    trait_id.name(db).long(db)
205                )
206            }
207            SemanticDiagnosticKind::ImplicitImplNotInferred {
208                trait_impl_id,
209                concrete_trait_id,
210            } => {
211                format!(
212                    "Cannot infer implicit impl `{}.`\nCould not find implementation of trait \
213                     `{:?}`",
214                    trait_impl_id.name(db).long(db),
215                    concrete_trait_id.debug(db)
216                )
217            }
218            SemanticDiagnosticKind::GenericsNotSupportedInItem { scope, item_kind } => {
219                format!("Generic parameters are not supported in {scope} item {item_kind}.")
220            }
221            SemanticDiagnosticKind::UnexpectedGenericArgs => "Unexpected generic arguments".into(),
222            SemanticDiagnosticKind::UnknownMember => "Unknown member.".into(),
223            SemanticDiagnosticKind::MemberSpecifiedMoreThanOnce => {
224                "Member specified more than once.".into()
225            }
226            SemanticDiagnosticKind::ConstCycle => {
227                "Cycle detected while resolving 'const' items.".into()
228            }
229            SemanticDiagnosticKind::UseCycle => {
230                "Cycle detected while resolving 'use' items.".into()
231            }
232            SemanticDiagnosticKind::TypeAliasCycle => {
233                "Cycle detected while resolving type-alias/impl-type items.".into()
234            }
235            SemanticDiagnosticKind::ImplAliasCycle => {
236                "Cycle detected while resolving 'impls alias' items.".into()
237            }
238            SemanticDiagnosticKind::ImplRequirementCycle => {
239                "Cycle detected while resolving generic param. Try specifying the generic impl \
240                 parameter explicitly to break the cycle."
241                    .into()
242            }
243            SemanticDiagnosticKind::MissingMember(member_name) => {
244                format!(r#"Missing member "{}"."#, member_name.long(db))
245            }
246            SemanticDiagnosticKind::WrongNumberOfParameters {
247                impl_def_id,
248                impl_function_id,
249                trait_id,
250                expected,
251                actual,
252            } => {
253                let function_name = impl_function_id.name(db).long(db);
254                format!(
255                    "The number of parameters in the impl function `{}::{}` is incompatible with \
256                     `{}::{}`. Expected: {}, actual: {}.",
257                    impl_def_id.name(db).long(db),
258                    function_name,
259                    trait_id.name(db).long(db),
260                    function_name,
261                    expected,
262                    actual,
263                )
264            }
265            SemanticDiagnosticKind::WrongNumberOfArguments { expected, actual } => {
266                format!("Wrong number of arguments. Expected {expected}, found: {actual}")
267            }
268            SemanticDiagnosticKind::WrongParameterType {
269                impl_def_id,
270                impl_function_id,
271                trait_id,
272                expected_ty,
273                actual_ty,
274            } => {
275                let function_name = impl_function_id.name(db).long(db);
276                format!(
277                    "Parameter type of impl function `{}::{}` is incompatible with `{}::{}`. \
278                     Expected: `{}`, actual: `{}`.",
279                    impl_def_id.name(db).long(db),
280                    function_name,
281                    trait_id.name(db).long(db),
282                    function_name,
283                    expected_ty.format(db),
284                    actual_ty.format(db)
285                )
286            }
287            SemanticDiagnosticKind::VariantCtorNotImmutable => {
288                "Variant constructor argument must be immutable.".to_string()
289            }
290            SemanticDiagnosticKind::TraitParamMutable { trait_id, function_id } => {
291                format!(
292                    "Parameter of trait function `{}::{}` can't be defined as mutable.",
293                    trait_id.name(db).long(db),
294                    function_id.name(db).long(db),
295                )
296            }
297            SemanticDiagnosticKind::ParameterShouldBeReference {
298                impl_def_id,
299                impl_function_id,
300                trait_id,
301            } => {
302                let function_name = impl_function_id.name(db).long(db);
303                format!(
304                    "Parameter of impl function {}::{} is incompatible with {}::{}. It should be \
305                     a reference.",
306                    impl_def_id.name(db).long(db),
307                    function_name,
308                    trait_id.name(db).long(db),
309                    function_name,
310                )
311            }
312            SemanticDiagnosticKind::ParameterShouldNotBeReference {
313                impl_def_id,
314                impl_function_id,
315                trait_id,
316            } => {
317                let function_name = impl_function_id.name(db).long(db);
318                format!(
319                    "Parameter of impl function {}::{} is incompatible with {}::{}. It should not \
320                     be a reference.",
321                    impl_def_id.name(db).long(db),
322                    function_name,
323                    trait_id.name(db).long(db),
324                    function_name,
325                )
326            }
327            SemanticDiagnosticKind::WrongParameterName {
328                impl_def_id,
329                impl_function_id,
330                trait_id,
331                expected_name,
332            } => {
333                let function_name = impl_function_id.name(db).long(db);
334                format!(
335                    "Parameter name of impl function {}::{function_name} is incompatible with \
336                     {}::{function_name} parameter `{}`.",
337                    impl_def_id.name(db).long(db),
338                    trait_id.name(db).long(db),
339                    expected_name.long(db)
340                )
341            }
342            SemanticDiagnosticKind::WrongType { expected_ty, actual_ty } => {
343                format!(
344                    r#"Expected type "{}", found: "{}"."#,
345                    expected_ty.format(db),
346                    actual_ty.format(db)
347                )
348            }
349            SemanticDiagnosticKind::InconsistentBinding => "variable is bound inconsistently \
350                                                            across alternatives separated by `|` \
351                                                            bound in different ways"
352                .into(),
353            SemanticDiagnosticKind::WrongArgumentType { expected_ty, actual_ty } => {
354                let diagnostic_prefix = format!(
355                    r#"Unexpected argument type. Expected: "{}", found: "{}"."#,
356                    expected_ty.format(db),
357                    actual_ty.format(db)
358                );
359                if (expected_ty.is_fully_concrete(db) && actual_ty.is_fully_concrete(db))
360                    || peel_snapshots(db, *expected_ty).0 == peel_snapshots(db, *actual_ty).0
361                {
362                    diagnostic_prefix
363                } else {
364                    format!(
365                        "{diagnostic_prefix}\nIt is possible that the type inference failed \
366                         because the types differ in the number of snapshots.\nConsider adding or \
367                         removing snapshots."
368                    )
369                }
370            }
371            SemanticDiagnosticKind::WrongReturnType { expected_ty, actual_ty } => {
372                format!(
373                    r#"Unexpected return type. Expected: "{}", found: "{}"."#,
374                    expected_ty.format(db),
375                    actual_ty.format(db)
376                )
377            }
378            SemanticDiagnosticKind::WrongExprType { expected_ty, actual_ty } => {
379                format!(
380                    r#"Unexpected expression type. Expected: "{}", found: "{}"."#,
381                    expected_ty.format(db),
382                    actual_ty.format(db)
383                )
384            }
385            SemanticDiagnosticKind::WrongNumberOfGenericParamsForImplFunction {
386                expected,
387                actual,
388            } => {
389                format!(
390                    "Wrong number of generic parameters for impl function. Expected: {expected}, \
391                     found: {actual}."
392                )
393            }
394            SemanticDiagnosticKind::WrongReturnTypeForImpl {
395                impl_def_id,
396                impl_function_id,
397                trait_id,
398                expected_ty,
399                actual_ty,
400            } => {
401                let function_name = impl_function_id.name(db).long(db);
402                format!(
403                    "Return type of impl function `{}::{}` is incompatible with `{}::{}`. \
404                     Expected: `{}`, actual: `{}`.",
405                    impl_def_id.name(db).long(db),
406                    function_name,
407                    trait_id.name(db).long(db),
408                    function_name,
409                    expected_ty.format(db),
410                    actual_ty.format(db)
411                )
412            }
413            SemanticDiagnosticKind::WrongGenericParamTraitForImplFunction {
414                impl_def_id,
415                impl_function_id,
416                trait_id,
417                expected_trait,
418                actual_trait,
419            } => {
420                let function_name = impl_function_id.name(db).long(db);
421                format!(
422                    "Generic parameter trait of impl function `{}::{}` is incompatible with \
423                     `{}::{}`. Expected: `{:?}`, actual: `{:?}`.",
424                    impl_def_id.name(db).long(db),
425                    function_name,
426                    trait_id.name(db).long(db),
427                    function_name,
428                    expected_trait.debug(db),
429                    actual_trait.debug(db)
430                )
431            }
432            SemanticDiagnosticKind::WrongGenericParamKindForImplFunction {
433                impl_def_id,
434                impl_function_id,
435                trait_id,
436                expected_kind,
437                actual_kind,
438            } => {
439                let function_name = impl_function_id.name(db).long(db);
440                format!(
441                    "Generic parameter kind of impl function `{}::{}` is incompatible with \
442                     `{}::{}`. Expected: `{:?}`, actual: `{:?}`.",
443                    impl_def_id.name(db).long(db),
444                    function_name,
445                    trait_id.name(db).long(db),
446                    function_name,
447                    expected_kind,
448                    actual_kind
449                )
450            }
451            SemanticDiagnosticKind::AmbiguousTrait { trait_function_id0, trait_function_id1 } => {
452                format!(
453                    "Ambiguous method call. More than one applicable trait function with a \
454                     suitable self type was found: {} and {}. Consider adding type annotations or \
455                     explicitly refer to the impl function.",
456                    trait_function_id0
457                        .contextualized_path(db, self.context_module)
458                        .unwrap_or_else(|_| trait_function_id0.full_path(db)),
459                    trait_function_id1
460                        .contextualized_path(db, self.context_module)
461                        .unwrap_or_else(|_| trait_function_id1.full_path(db))
462                )
463            }
464            SemanticDiagnosticKind::VariableNotFound(name) => {
465                format!(r#"Variable "{}" not found."#, name.long(db))
466            }
467            SemanticDiagnosticKind::MissingVariableInPattern => {
468                "Missing variable in pattern.".into()
469            }
470            SemanticDiagnosticKind::VariableDefinedMultipleTimesInPattern(name) => {
471                format!(r#"Redefinition of variable name "{}" in pattern."#, name.long(db))
472            }
473            SemanticDiagnosticKind::StructMemberRedefinition { struct_id, member_name } => {
474                format!(
475                    r#"Redefinition of member "{}" on struct "{}"."#,
476                    member_name.long(db),
477                    struct_id
478                        .contextualized_path(db, self.context_module)
479                        .unwrap_or_else(|_| struct_id.full_path(db))
480                )
481            }
482            SemanticDiagnosticKind::EnumVariantRedefinition { enum_id, variant_name } => {
483                format!(
484                    r#"Redefinition of variant "{}" on enum "{}"."#,
485                    variant_name.long(db),
486                    enum_id
487                        .contextualized_path(db, self.context_module)
488                        .unwrap_or_else(|_| enum_id.full_path(db))
489                )
490            }
491            SemanticDiagnosticKind::InfiniteSizeType(ty) => {
492                format!(r#"Recursive type "{}" has infinite size."#, ty.format(db))
493            }
494            SemanticDiagnosticKind::ArrayOfZeroSizedElements(ty) => {
495                format!(r#"Cannot have array of type "{}" that is zero sized."#, ty.format(db))
496            }
497            SemanticDiagnosticKind::ParamNameRedefinition { function_title_id, param_name } => {
498                format!(
499                    r#"Redefinition of parameter name "{}"{}"#,
500                    param_name.long(db),
501                    function_title_id
502                        .map(|function_title_id| format!(
503                            r#" in function "{}"."#,
504                            function_title_id
505                                .contextualized_path(db, self.context_module)
506                                .unwrap_or_else(|_| function_title_id.full_path(db))
507                        ))
508                        .unwrap_or(".".into()),
509                )
510            }
511            SemanticDiagnosticKind::ConditionNotBool(condition_ty) => {
512                format!(r#"Condition has type "{}", expected bool."#, condition_ty.format(db))
513            }
514            SemanticDiagnosticKind::IncompatibleArms {
515                multi_arm_expr_kind: incompatibility_kind,
516                pending_ty: first_ty,
517                different_ty,
518            } => {
519                let prefix = match incompatibility_kind {
520                    MultiArmExprKind::Match => "Match arms have incompatible types",
521                    MultiArmExprKind::If => "If blocks have incompatible types",
522                    MultiArmExprKind::Loop => "Loop has incompatible return types",
523                };
524                format!(r#"{prefix}: "{}" and "{}""#, first_ty.format(db), different_ty.format(db))
525            }
526            SemanticDiagnosticKind::TypeHasNoMembers { ty, member_name: _ } => {
527                format!(r#"Type "{}" has no members."#, ty.format(db))
528            }
529            SemanticDiagnosticKind::NoSuchStructMember { struct_id, member_name } => {
530                format!(
531                    r#"Struct "{}" has no member "{}""#,
532                    struct_id
533                        .contextualized_path(db, self.context_module)
534                        .unwrap_or_else(|_| struct_id.full_path(db)),
535                    member_name.long(db)
536                )
537            }
538            SemanticDiagnosticKind::NoSuchTypeMember { ty, member_name } => {
539                format!(r#"Type "{}" has no member "{}""#, ty.format(db), member_name.long(db))
540            }
541            SemanticDiagnosticKind::MemberNotVisible(member_name) => {
542                format!(r#"Member "{}" is not visible in this context."#, member_name.long(db))
543            }
544            SemanticDiagnosticKind::NoSuchVariant { enum_id, variant_name } => {
545                format!(
546                    r#"Enum "{}" has no variant "{}""#,
547                    enum_id
548                        .contextualized_path(db, self.context_module)
549                        .unwrap_or_else(|_| enum_id.full_path(db)),
550                    variant_name.long(db)
551                )
552            }
553            SemanticDiagnosticKind::ReturnTypeNotErrorPropagateType => {
554                "`?` can only be used in a function with `Option` or `Result` return type.".into()
555            }
556            SemanticDiagnosticKind::IncompatibleErrorPropagateType { return_ty, err_ty } => {
557                format!(
558                    r#"Return type "{}" does not wrap error "{}""#,
559                    return_ty.format(db),
560                    err_ty.format(db)
561                )
562            }
563            SemanticDiagnosticKind::ErrorPropagateOnNonErrorType(ty) => {
564                format!(r#"Type "{}" cannot error propagate"#, ty.format(db))
565            }
566            SemanticDiagnosticKind::UnhandledMustUseType(ty) => {
567                format!(r#"Unhandled `#[must_use]` type `{}`"#, ty.format(db))
568            }
569            SemanticDiagnosticKind::UnhandledMustUseFunction => {
570                "Unhandled `#[must_use]` function.".into()
571            }
572            SemanticDiagnosticKind::UnstableFeature { feature_name, note } => {
573                format!(
574                    "Usage of unstable feature `{0}` with no `#[feature({0})]` attribute.{1}",
575                    feature_name.long(db),
576                    note.as_ref()
577                        .map(|note| format!(" Note: {}", note.long(db)))
578                        .unwrap_or_default()
579                )
580            }
581            SemanticDiagnosticKind::DeprecatedFeature { feature_name, note } => {
582                format!(
583                    "Usage of deprecated feature `{0}` with no `#[feature({0})]` attribute.{1}",
584                    feature_name.long(db),
585                    note.as_ref()
586                        .map(|note| format!(" Note: {}", note.long(db)))
587                        .unwrap_or_default()
588                )
589            }
590            SemanticDiagnosticKind::InternalFeature { feature_name, note } => {
591                format!(
592                    "Usage of internal feature `{0}` with no `#[feature({0})]` attribute.{1}",
593                    feature_name.long(db),
594                    note.as_ref()
595                        .map(|note| format!(" Note: {}", note.long(db)))
596                        .unwrap_or_default()
597                )
598            }
599            SemanticDiagnosticKind::FeatureMarkerDiagnostic(diagnostic) => match diagnostic {
600                FeatureMarkerDiagnostic::MultipleMarkers => {
601                    "Multiple feature marker attributes.".into()
602                }
603                FeatureMarkerDiagnostic::MissingAllowFeature => {
604                    "Missing `feature` arg for feature marker attribute.".into()
605                }
606                FeatureMarkerDiagnostic::UnsupportedArgument => {
607                    "Unsupported argument for feature marker attribute.".into()
608                }
609                FeatureMarkerDiagnostic::DuplicatedArgument => {
610                    "Duplicated argument for feature marker attribute.".into()
611                }
612            },
613            SemanticDiagnosticKind::UnusedVariable => {
614                "Unused variable. Consider ignoring by prefixing with `_`.".into()
615            }
616            SemanticDiagnosticKind::UnusedConstant => {
617                "Unused constant. Consider ignoring by prefixing with `_`.".into()
618            }
619            SemanticDiagnosticKind::MultipleConstantDefinition(constant_name) => {
620                format!(r#"Multiple definitions of constant "{}"."#, constant_name.long(db))
621            }
622            SemanticDiagnosticKind::UnusedUse => "Unused use.".into(),
623            SemanticDiagnosticKind::MultipleDefinitionforBinding(name) => {
624                format!(
625                    r#"Multiple definitions of identifier '{}' as constant and variable."#,
626                    name.long(db)
627                )
628            }
629            SemanticDiagnosticKind::MultipleGenericItemDefinition(type_name) => {
630                format!(r#"Multiple definitions of an item "{}"."#, type_name.long(db))
631            }
632            SemanticDiagnosticKind::UnsupportedUseItemInStatement => {
633                "Unsupported use item in statement.".into()
634            }
635            SemanticDiagnosticKind::InvalidMemberExpression => "Invalid member expression.".into(),
636            SemanticDiagnosticKind::InvalidPath => "Invalid path.".into(),
637            SemanticDiagnosticKind::RefArgNotAVariable => "ref argument must be a variable.".into(),
638            SemanticDiagnosticKind::RefArgNotMutable => {
639                "ref argument must be a mutable variable.".into()
640            }
641            SemanticDiagnosticKind::RefArgNotExplicit => {
642                "ref argument must be passed with a preceding 'ref'.".into()
643            }
644            SemanticDiagnosticKind::ImmutableArgWithModifiers => {
645                "Argument to immutable parameter cannot have modifiers.".into()
646            }
647            SemanticDiagnosticKind::AssignmentToImmutableVar => {
648                "Cannot assign to an immutable variable.".into()
649            }
650            SemanticDiagnosticKind::InvalidLhsForAssignment => {
651                "Invalid left-hand side of assignment.".into()
652            }
653            SemanticDiagnosticKind::PathNotFound(item_type) => match item_type {
654                NotFoundItemType::Identifier => "Identifier not found.".into(),
655                NotFoundItemType::Function => "Function not found.".into(),
656                NotFoundItemType::Type => "Type not found.".into(),
657                NotFoundItemType::Trait => "Trait not found.".into(),
658                NotFoundItemType::Impl => "Impl not found.".into(),
659                NotFoundItemType::Macro => "Macro not found.".into(),
660            },
661            SemanticDiagnosticKind::AmbiguousPath(module_items) => {
662                format!(
663                    "Ambiguous path. Multiple matching items: {}",
664                    module_items.iter().map(|item| format!("`{}`", item.full_path(db))).join(", ")
665                )
666            }
667            SemanticDiagnosticKind::UseSelfNonMulti => {
668                "`self` in `use` items is not allowed not in multi.".into()
669            }
670            SemanticDiagnosticKind::UseSelfEmptyPath => {
671                "`self` in `use` items is not allowed for empty path.".into()
672            }
673            SemanticDiagnosticKind::UseStarEmptyPath => {
674                "`*` in `use` items is not allowed for empty path.".into()
675            }
676            SemanticDiagnosticKind::GlobalUsesNotSupportedInEdition(edition) => {
677                format!("Global `use` item is not supported in `{edition:?}` edition.")
678            }
679            SemanticDiagnosticKind::TraitInTraitMustBeExplicit => {
680                "In a trait, paths of the same trait must be fully explicit. Either use `Self` if \
681                 this is the intention, or explicitly specify all the generic arguments."
682                    .to_string()
683            }
684            SemanticDiagnosticKind::ImplInImplMustBeExplicit => {
685                "In an impl, paths of the same impl must be fully explicit. Either use `Self` if \
686                 this is the intention, or explicitly specify all the generic arguments."
687                    .to_string()
688            }
689            SemanticDiagnosticKind::TraitItemForbiddenInTheTrait => {
690                "In a trait, paths of the same trait are not allowed. Did you mean to use `Self::`?"
691                    .to_string()
692            }
693            SemanticDiagnosticKind::TraitItemForbiddenInItsImpl => "In an impl, paths of the \
694                                                                    impl's trait are not allowed. \
695                                                                    Did you mean to use `Self::`?"
696                .to_string(),
697            SemanticDiagnosticKind::ImplItemForbiddenInTheImpl => {
698                "In an impl, paths of the same impl are not allowed. Did you mean to use `Self::`?"
699                    .to_string()
700            }
701            SemanticDiagnosticKind::SuperUsedInRootModule => {
702                "'super' cannot be used for the crate's root module.".into()
703            }
704            SemanticDiagnosticKind::SuperUsedInMacroCallTopLevel => {
705                "`super` used in macro call top level.".into()
706            }
707            SemanticDiagnosticKind::ItemNotVisible(item_id, containing_modules) => {
708                format!(
709                    "Item `{}` is not visible in this context{}.",
710                    item_id.full_path(db),
711                    if containing_modules.is_empty() {
712                        "".to_string()
713                    } else if let [module_id] = &containing_modules[..] {
714                        format!(" through module `{}`", module_id.full_path(db))
715                    } else {
716                        format!(
717                            " through any of the modules: {}",
718                            containing_modules
719                                .iter()
720                                .map(|module_id| format!("`{}`", module_id.full_path(db)))
721                                .join(", ")
722                        )
723                    }
724                )
725            }
726            SemanticDiagnosticKind::UnusedImport(use_id) => {
727                format!("Unused import: `{}`", use_id.full_path(db))
728            }
729            SemanticDiagnosticKind::BadPatternForInputType(ty) => {
730                format!(
731                    "Mismatched types: pattern cannot match against type \"{}\".",
732                    ty.format(db),
733                )
734            }
735            SemanticDiagnosticKind::WrongNumberOfTupleElements { expected, actual } => format!(
736                r#"Wrong number of tuple elements in pattern. Expected: {expected}. Got: {actual}."#,
737            ),
738            SemanticDiagnosticKind::WrongNumberOfFixedSizeArrayElements { expected, actual } => {
739                format!(
740                    "Wrong number of fixed size array elements in pattern. Expected: {expected}. \
741                     Got: {actual}.",
742                )
743            }
744            SemanticDiagnosticKind::WrongEnum { expected_enum, actual_enum } => {
745                format!(
746                    r#"Wrong enum in pattern. Expected: "{}". Got: "{}"."#,
747                    expected_enum
748                        .contextualized_path(db, self.context_module)
749                        .unwrap_or_else(|_| expected_enum.full_path(db)),
750                    actual_enum
751                        .contextualized_path(db, self.context_module)
752                        .unwrap_or_else(|_| actual_enum.full_path(db))
753                )
754            }
755            SemanticDiagnosticKind::RedundantModifier { current_modifier, previous_modifier } => {
756                format!(
757                    "`{}` modifier was specified after another modifier (`{}`). Only a single \
758                     modifier is allowed.",
759                    current_modifier.long(db),
760                    previous_modifier.long(db)
761                )
762            }
763            SemanticDiagnosticKind::ReferenceLocalVariable => {
764                "`ref` is only allowed for function parameters, not for local variables."
765                    .to_string()
766            }
767            SemanticDiagnosticKind::InvalidCopyTraitImpl(inference_error) => {
768                format!("Invalid copy trait implementation, {}", inference_error.format(db))
769            }
770            SemanticDiagnosticKind::InvalidDropTraitImpl(inference_error) => {
771                format!("Invalid drop trait implementation, {}", inference_error.format(db))
772            }
773            SemanticDiagnosticKind::InvalidImplItem(item_kw) => {
774                format!("`{}` is not allowed inside impl.", item_kw.long(db))
775            }
776            SemanticDiagnosticKind::MissingItemsInImpl(item_names) => {
777                format!(
778                    "Not all trait items are implemented. Missing: {}.",
779                    item_names.iter().map(|name| format!("'{}'", name.long(db))).join(", ")
780                )
781            }
782            SemanticDiagnosticKind::PassPanicAsNopanic { impl_function_id, trait_id } => {
783                let name = impl_function_id.name(db).long(db);
784                let trait_name = trait_id.name(db).long(db);
785                format!(
786                    "The signature of function `{name}` is incompatible with trait \
787                     `{trait_name}`. The trait function is declared as nopanic."
788                )
789            }
790            SemanticDiagnosticKind::PassConstAsNonConst { impl_function_id, trait_id } => {
791                let name = impl_function_id.name(db).long(db);
792                let trait_name = trait_id.name(db).long(db);
793                format!(
794                    "The signature of function `{name}` is incompatible with trait \
795                     `{trait_name}`. The trait function is declared as const."
796                )
797            }
798            SemanticDiagnosticKind::PanicableFromNonPanicable => {
799                "Function is declared as nopanic but calls a function that may panic.".into()
800            }
801            SemanticDiagnosticKind::PanicableExternFunction => {
802                "An extern function must be marked as nopanic.".into()
803            }
804            SemanticDiagnosticKind::PluginDiagnostic(diagnostic) => {
805                format!("Plugin diagnostic: {}", diagnostic.message)
806            }
807            SemanticDiagnosticKind::MacroGeneratedCodeParserDiagnostic(parser_diagnostic) => {
808                format!("Parser error in macro-expanded code: {}", parser_diagnostic.format(db))
809            }
810            SemanticDiagnosticKind::NameDefinedMultipleTimes(name) => {
811                format!("The name `{}` is defined multiple times.", name.long(db))
812            }
813            SemanticDiagnosticKind::NonPrivateUseStar => {
814                "`pub` not supported for global `use`.".into()
815            }
816            SemanticDiagnosticKind::SelfGlobalUse => {
817                "cannot glob-import a module into itself".into()
818            }
819            SemanticDiagnosticKind::NamedArgumentsAreNotSupported => {
820                "Named arguments are not supported in this context.".into()
821            }
822            SemanticDiagnosticKind::UnnamedArgumentFollowsNamed => {
823                "Unnamed arguments cannot follow named arguments.".into()
824            }
825            SemanticDiagnosticKind::NamedArgumentMismatch { expected, found } => {
826                format!(
827                    "Unexpected argument name. Expected: '{}', found '{}'.",
828                    expected.long(db),
829                    found.long(db)
830                )
831            }
832            SemanticDiagnosticKind::UnsupportedOutsideOfFunction(feature_name) => {
833                let feature_name_str = match feature_name {
834                    UnsupportedOutsideOfFunctionFeatureName::ReturnStatement => "Return statement",
835                    UnsupportedOutsideOfFunctionFeatureName::ErrorPropagate => "The '?' operator",
836                };
837                format!("{feature_name_str} is not supported outside of functions.")
838            }
839            SemanticDiagnosticKind::ConstTypeNotVarFree => {
840                "Constant type must not depend on its value.".into()
841            }
842            SemanticDiagnosticKind::UnsupportedConstant => {
843                "This expression is not supported as constant.".into()
844            }
845            SemanticDiagnosticKind::FailedConstantCalculation => {
846                "Failed to calculate constant.".into()
847            }
848            SemanticDiagnosticKind::ConstantCalculationDepthExceeded => {
849                "Constant calculation depth exceeded.".into()
850            }
851            SemanticDiagnosticKind::InnerFailedConstantCalculation(inner, _) => inner.format(db),
852            SemanticDiagnosticKind::DivisionByZero => "Division by zero.".into(),
853            SemanticDiagnosticKind::ExternTypeWithImplGenericsNotSupported => {
854                "Extern types with impl generics are not supported.".into()
855            }
856            SemanticDiagnosticKind::MissingSemicolon => "Missing semicolon".into(),
857            SemanticDiagnosticKind::TraitMismatch { expected_trt, actual_trt } => {
858                format!(
859                    "Expected an impl of `{:?}`. Got an impl of `{:?}`.",
860                    expected_trt.debug(db),
861                    actual_trt.debug(db),
862                )
863            }
864            SemanticDiagnosticKind::InternalInferenceError(err) => err.format(db),
865            SemanticDiagnosticKind::DerefNonRef { ty } => {
866                format!("Type `{}` cannot be dereferenced", ty.format(db))
867            }
868            SemanticDiagnosticKind::NoImplementationOfIndexOperator { ty, inference_errors } => {
869                if inference_errors.is_empty() {
870                    format!(
871                        "Type `{}` does not implement the `Index` trait nor the `IndexView` trait.",
872                        ty.format(db)
873                    )
874                } else {
875                    format!(
876                        "Type `{}` could not be indexed.\n{}",
877                        ty.format(db),
878                        inference_errors.format(db)
879                    )
880                }
881            }
882            SemanticDiagnosticKind::MultipleImplementationOfIndexOperator(ty) => {
883                format!(
884                    r#"Type "{}" implements both the "Index" trait and the "IndexView" trait."#,
885                    ty.format(db)
886                )
887            }
888            SemanticDiagnosticKind::UnsupportedInlineArguments => {
889                "Unsupported `inline` arguments.".into()
890            }
891            SemanticDiagnosticKind::RedundantInlineAttribute => {
892                "Redundant `inline` attribute.".into()
893            }
894            SemanticDiagnosticKind::InlineAttrForExternFunctionNotAllowed => {
895                "`inline` attribute is not allowed for extern functions.".into()
896            }
897            SemanticDiagnosticKind::InlineAlwaysWithImplGenericArgNotAllowed => {
898                "`#[inline(always)]` is not allowed for functions with impl generic parameters."
899                    .into()
900            }
901            SemanticDiagnosticKind::CannotCallMethod {
902                ty,
903                method_name,
904                inference_errors,
905                relevant_traits,
906            } => {
907                if !inference_errors.is_empty() {
908                    return format!(
909                        "Method `{}` could not be called on type `{}`.\n{}",
910                        method_name.long(db),
911                        ty.format(db),
912                        inference_errors.format(db)
913                    );
914                }
915                if !relevant_traits.is_empty() {
916                    let suggestions = relevant_traits
917                        .iter()
918                        .map(|trait_path| format!("`{trait_path}`"))
919                        .collect::<Vec<_>>()
920                        .join(", ");
921
922                    format!(
923                        "Method `{}` not found on type `{}`. Consider importing one of the \
924                         following traits: {}.",
925                        method_name.long(db),
926                        ty.format(db),
927                        suggestions
928                    )
929                } else {
930                    format!(
931                        "Method `{}` not found on type `{}`. Did you import the correct trait and \
932                         impl?",
933                        method_name.long(db),
934                        ty.format(db)
935                    )
936                }
937            }
938            SemanticDiagnosticKind::TailExpressionNotAllowedInLoop => {
939                "Tail expression not allowed in a `loop` block.".into()
940            }
941            SemanticDiagnosticKind::ContinueOnlyAllowedInsideALoop => {
942                "`continue` only allowed inside a `loop`.".into()
943            }
944            SemanticDiagnosticKind::BreakOnlyAllowedInsideALoop => {
945                "`break` only allowed inside a `loop`.".into()
946            }
947            SemanticDiagnosticKind::BreakWithValueOnlyAllowedInsideALoop => {
948                "Can only break with a value inside a `loop`.".into()
949            }
950            SemanticDiagnosticKind::ErrorPropagateNotAllowedInsideALoop => {
951                "`?` not allowed inside a `loop`.".into()
952            }
953            SemanticDiagnosticKind::ConstGenericParamNotSupported => {
954                "Const generic args are not allowed in this context.".into()
955            }
956            SemanticDiagnosticKind::NegativeImplsNotEnabled => {
957                "Negative impls are not enabled in the current crate.".into()
958            }
959            SemanticDiagnosticKind::NegativeImplsOnlyOnImpls => {
960                "Negative impls supported only in impl definitions.".into()
961            }
962            SemanticDiagnosticKind::ImplicitPrecedenceAttrForExternFunctionNotAllowed => {
963                "`implicit_precedence` attribute is not allowed for extern functions.".into()
964            }
965            SemanticDiagnosticKind::RedundantImplicitPrecedenceAttribute => {
966                "Redundant `implicit_precedence` attribute.".into()
967            }
968            SemanticDiagnosticKind::UnsupportedImplicitPrecedenceArguments => {
969                "Unsupported `implicit_precedence` arguments.".into()
970            }
971            SemanticDiagnosticKind::UnsupportedFeatureAttrArguments => {
972                "`feature` attribute argument should be a single string.".into()
973            }
974            SemanticDiagnosticKind::UnsupportedAllowAttrArguments => {
975                // TODO(orizi): Add information about the allowed arguments.
976                "`allow` attribute argument not supported.".into()
977            }
978            SemanticDiagnosticKind::UnsupportedPubArgument => "Unsupported `pub` argument.".into(),
979            SemanticDiagnosticKind::UnknownStatementAttribute => {
980                "Unknown statement attribute.".into()
981            }
982            SemanticDiagnosticKind::InlineMacroNotFound(macro_name) => {
983                format!("Inline macro `{}` not found.", macro_name.long(db))
984            }
985            SemanticDiagnosticKind::InlineMacroFailed(macro_name) => {
986                format!("Inline macro `{}` failed.", macro_name.long(db))
987            }
988            SemanticDiagnosticKind::InlineMacroNoMatchingRule(macro_name) => {
989                format!("No matching rule found in inline macro `{}`.", macro_name.long(db))
990            }
991            SemanticDiagnosticKind::MacroCallToNotAMacro(name) => {
992                format!("Call to `{}` which is not a macro.", name.long(db))
993            }
994            SemanticDiagnosticKind::UnknownGenericParam(name) => {
995                format!("Unknown generic parameter `{}`.", name.long(db))
996            }
997            SemanticDiagnosticKind::PositionalGenericAfterNamed => {
998                "Positional generic parameters must come before named generic parameters.".into()
999            }
1000            SemanticDiagnosticKind::GenericArgDuplicate(name) => {
1001                format!("Generic argument `{}` is specified more than once.", name.long(db))
1002            }
1003            SemanticDiagnosticKind::TooManyGenericArguments { expected, actual } => {
1004                format!("Expected {expected} generic arguments, found {actual}.")
1005            }
1006            SemanticDiagnosticKind::GenericArgOutOfOrder(name) => {
1007                format!("Generic argument `{}` is out of order.", name.long(db))
1008            }
1009            SemanticDiagnosticKind::ArgPassedToNegativeImpl => {
1010                "Only `_` is valid as a negative impl argument.".into()
1011            }
1012            SemanticDiagnosticKind::CouponForExternFunctionNotAllowed => {
1013                "Coupon cannot be used with extern functions.".into()
1014            }
1015            SemanticDiagnosticKind::CouponArgumentNoModifiers => {
1016                "The __coupon__ argument cannot have modifiers.".into()
1017            }
1018            SemanticDiagnosticKind::CouponsDisabled => {
1019                "Coupons are disabled in the current crate.\nYou can enable them by enabling the \
1020                 coupons experimental feature in the crate config."
1021                    .into()
1022            }
1023            SemanticDiagnosticKind::ReprPtrsDisabled => {
1024                "Representation pointers are disabled in the current crate.\nYou can enable them \
1025                 by enabling the `repr_ptrs` experimental feature in the crate config."
1026                    .into()
1027            }
1028            SemanticDiagnosticKind::AssignmentToReprPtrVariable { .. } => {
1029                "Cannot assign to a variable with a taken pointer".into()
1030            }
1031            SemanticDiagnosticKind::StructBaseStructExpressionNotLast => {
1032                "The base struct must always be the last argument.".into()
1033            }
1034            SemanticDiagnosticKind::StructBaseStructExpressionNoEffect => {
1035                "Base struct has no effect, all the fields in the struct have already been \
1036                 specified."
1037                    .into()
1038            }
1039            SemanticDiagnosticKind::FixedSizeArrayTypeNonSingleType => {
1040                "Fixed size array type must have exactly one type.".into()
1041            }
1042            SemanticDiagnosticKind::FixedSizeArrayTypeEmptySize => {
1043                "Fixed size array type must have a size clause.".into()
1044            }
1045            SemanticDiagnosticKind::FixedSizeArrayNonNumericSize => {
1046                "Fixed size array type must have a positive integer size.".into()
1047            }
1048            SemanticDiagnosticKind::FixedSizeArrayNonSingleValue => {
1049                "Fixed size array with defined size must have exactly one value.".into()
1050            }
1051            SemanticDiagnosticKind::FixedSizeArraySizeTooBig => {
1052                "Fixed size array size must be smaller than 2^15.".into()
1053            }
1054            SemanticDiagnosticKind::SelfNotSupportedInContext => {
1055                "`Self` is not supported in this context.".into()
1056            }
1057            SemanticDiagnosticKind::SelfMustBeFirst => {
1058                "`Self` can only be the first segment of a path.".into()
1059            }
1060            SemanticDiagnosticKind::DollarNotSupportedInContext => {
1061                "`$` is not supported in this context.".into()
1062            }
1063            SemanticDiagnosticKind::UnknownResolverModifier { modifier } => {
1064                format!("`${}` is not supported.", modifier.long(db))
1065            }
1066            SemanticDiagnosticKind::EmptyPathAfterResolverModifier => {
1067                "Expected path after modifier.".into()
1068            }
1069            SemanticDiagnosticKind::CannotCreateInstancesOfPhantomTypes => {
1070                "Can not create instances of phantom types.".into()
1071            }
1072            SemanticDiagnosticKind::NonPhantomTypeContainingPhantomType => {
1073                "Non-phantom type containing phantom type.".into()
1074            }
1075            SemanticDiagnosticKind::DerefCycle { deref_chain } => {
1076                format!("Deref impls cycle detected:\n{deref_chain}")
1077            }
1078            SemanticDiagnosticKind::NoImplementationOfTrait {
1079                ty,
1080                trait_name,
1081                inference_errors,
1082            } => {
1083                if inference_errors.is_empty() {
1084                    format!(
1085                        "Implementation of trait `{}` not found on type `{}`. Did you import the \
1086                         correct trait and impl?",
1087                        trait_name.long(db),
1088                        ty.format(db)
1089                    )
1090                } else {
1091                    format!(
1092                        "Could not find implementation of trait `{}` on type `{}`.\n{}",
1093                        trait_name.long(db),
1094                        ty.format(db),
1095                        inference_errors.format(db)
1096                    )
1097                }
1098            }
1099            SemanticDiagnosticKind::CallExpressionRequiresFunction { ty, inference_errors } => {
1100                if inference_errors.is_empty() {
1101                    format!("Call expression requires a function, found `{}`.", ty.format(db))
1102                } else {
1103                    format!(
1104                        "Call expression requires a function, found `{}`.\n{}",
1105                        ty.format(db),
1106                        inference_errors.format(db)
1107                    )
1108                }
1109            }
1110            SemanticDiagnosticKind::CompilerTraitReImplementation { trait_id } => {
1111                format!(
1112                    "Trait `{}` should not be implemented outside of the corelib.",
1113                    trait_id.full_path(db)
1114                )
1115            }
1116            SemanticDiagnosticKind::ClosureInGlobalScope => {
1117                "Closures are not allowed in this context.".into()
1118            }
1119            SemanticDiagnosticKind::MaybeMissingColonColon => "Are you missing a `::`?.".into(),
1120            SemanticDiagnosticKind::CallingShadowedFunction { shadowed_function_name } => {
1121                format!(
1122                    "Function `{}` is shadowed by a local variable.",
1123                    shadowed_function_name.long(db)
1124                )
1125            }
1126            SemanticDiagnosticKind::RefClosureArgument => {
1127                "Arguments to closure functions cannot be references".into()
1128            }
1129            SemanticDiagnosticKind::RefClosureParam => {
1130                "Closure parameters cannot be references".into()
1131            }
1132            SemanticDiagnosticKind::MustBeNextToTypeOrTrait { trait_id } => {
1133                format!(
1134                    "'{}' implementation must be defined in the same module as either the type \
1135                     being dereferenced or the trait itself",
1136                    trait_id.name(db).long(db)
1137                )
1138            }
1139            SemanticDiagnosticKind::MutableCapturedVariable => {
1140                "Capture of mutable variables in a closure is not supported".into()
1141            }
1142            SemanticDiagnosticKind::NonTraitTypeConstrained { identifier, concrete_trait_id } => {
1143                format!(
1144                    "associated type `{}` not found for `{}`",
1145                    identifier.long(db),
1146                    concrete_trait_id
1147                        .contextualized_path(db, self.context_module)
1148                        .unwrap_or_else(|_| concrete_trait_id.full_path(db))
1149                )
1150            }
1151            SemanticDiagnosticKind::DuplicateTypeConstraint {
1152                concrete_trait_type_id: trait_type_id,
1153            } => {
1154                let concrete_trait = trait_type_id.concrete_trait(db);
1155                format!(
1156                    "the value of the associated type `{}` in trait `{}` is already specified",
1157                    trait_type_id.trait_type(db).name(db).long(db),
1158                    concrete_trait
1159                        .contextualized_path(db, self.context_module)
1160                        .unwrap_or_else(|_| concrete_trait.full_path(db))
1161                )
1162            }
1163            SemanticDiagnosticKind::TypeConstraintsSyntaxNotEnabled => {
1164                "Type constraints syntax is not enabled in the current crate.".into()
1165            }
1166            SemanticDiagnosticKind::PatternMissingArgs(path) => {
1167                format!(
1168                    "Pattern missing subpattern for the payload of variant. Consider using `{}(_)`",
1169                    path.segments(db)
1170                        .elements(db)
1171                        .map(|seg| seg.identifier(db).long(db))
1172                        .join("::")
1173                )
1174            }
1175            SemanticDiagnosticKind::UndefinedMacroPlaceholder(name) => {
1176                format!("Undefined macro placeholder: '{}'.", name.long(db))
1177            }
1178            SemanticDiagnosticKind::MacroPlaceholderRepDepthMismatch { name, required, actual } => {
1179                format!(
1180                    "Macro placeholder '{}' requires {} repetition level(s) in the expansion, but \
1181                     is used at level {}.",
1182                    name.long(db),
1183                    required,
1184                    actual
1185                )
1186            }
1187            SemanticDiagnosticKind::MacroPlaceholderRepDriverMismatch(name) => {
1188                format!(
1189                    "Macro placeholder '{}' is from a different repetition than the one driving \
1190                     this expansion block.",
1191                    name.long(db)
1192                )
1193            }
1194            SemanticDiagnosticKind::UserDefinedInlineMacrosDisabled => {
1195                "User defined inline macros are disabled in the current crate.".into()
1196            }
1197            SemanticDiagnosticKind::NonNeverLetElseType => concat!(
1198                "`else` clause of `let...else` must exit the scope. ",
1199                "Consider using `return`, `continue`, ..."
1200            )
1201            .into(),
1202            SemanticDiagnosticKind::OnlyTypeOrConstParamsInNegImpl => {
1203                "Negative impls may only use type or const generic parameters.".into()
1204            }
1205            SemanticDiagnosticKind::UnsupportedItemInStatement => {
1206                "Item not supported as a statement.".into()
1207            }
1208        }
1209    }
1210    fn location(&self, db: &'db dyn Database) -> SpanInFile<'db> {
1211        if let SemanticDiagnosticKind::MacroGeneratedCodeParserDiagnostic(parser_diagnostic) =
1212            &self.kind
1213        {
1214            return SpanInFile { file_id: parser_diagnostic.file_id, span: parser_diagnostic.span };
1215        };
1216
1217        let mut location = self.stable_location.span_in_file(db);
1218        if self.after {
1219            location = location.after();
1220        }
1221        location
1222    }
1223
1224    fn severity(&self) -> Severity {
1225        match &self.kind {
1226            SemanticDiagnosticKind::UnusedVariable
1227            | SemanticDiagnosticKind::UnhandledMustUseType { .. }
1228            | SemanticDiagnosticKind::UnhandledMustUseFunction
1229            | SemanticDiagnosticKind::TraitInTraitMustBeExplicit
1230            | SemanticDiagnosticKind::ImplInImplMustBeExplicit
1231            | SemanticDiagnosticKind::TraitItemForbiddenInTheTrait
1232            | SemanticDiagnosticKind::TraitItemForbiddenInItsImpl
1233            | SemanticDiagnosticKind::ImplItemForbiddenInTheImpl
1234            | SemanticDiagnosticKind::UnstableFeature { .. }
1235            | SemanticDiagnosticKind::DeprecatedFeature { .. }
1236            | SemanticDiagnosticKind::UnusedImport { .. }
1237            | SemanticDiagnosticKind::CallingShadowedFunction { .. }
1238            | SemanticDiagnosticKind::UnusedConstant
1239            | SemanticDiagnosticKind::UnusedUse
1240            | SemanticDiagnosticKind::PatternMissingArgs(_)
1241            | SemanticDiagnosticKind::UnsupportedAllowAttrArguments => Severity::Warning,
1242            SemanticDiagnosticKind::PluginDiagnostic(diag) => diag.severity,
1243            _ => Severity::Error,
1244        }
1245    }
1246
1247    fn notes(&self, _db: &dyn Database) -> &[DiagnosticNote<'_>] {
1248        match &self.kind {
1249            SemanticDiagnosticKind::InnerFailedConstantCalculation(_, notes) => notes,
1250            SemanticDiagnosticKind::AssignmentToReprPtrVariable(notes) => notes,
1251            _ => &[],
1252        }
1253    }
1254
1255    fn error_code(&self) -> Option<ErrorCode> {
1256        Some(match &self.kind {
1257            SemanticDiagnosticKind::UnusedVariable => error_code!(E0001),
1258            SemanticDiagnosticKind::CannotCallMethod { .. } => error_code!(E0002),
1259            SemanticDiagnosticKind::MissingMember(_) => error_code!(E0003),
1260            SemanticDiagnosticKind::MissingItemsInImpl(_) => error_code!(E0004),
1261            SemanticDiagnosticKind::ModuleFileNotFound(_) => error_code!(E0005),
1262            SemanticDiagnosticKind::PathNotFound(_) => error_code!(E0006),
1263            SemanticDiagnosticKind::NoSuchTypeMember { .. } => error_code!(E0007),
1264            SemanticDiagnosticKind::Unsupported => error_code!(E2000),
1265            SemanticDiagnosticKind::UnknownLiteral => error_code!(E2001),
1266            SemanticDiagnosticKind::UnknownBinaryOperator => error_code!(E2002),
1267            SemanticDiagnosticKind::UnknownTrait => error_code!(E2003),
1268            SemanticDiagnosticKind::UnknownImpl => error_code!(E2004),
1269            SemanticDiagnosticKind::UnexpectedElement { .. } => error_code!(E2005),
1270            SemanticDiagnosticKind::UnknownType => error_code!(E2006),
1271            SemanticDiagnosticKind::UnknownEnum => error_code!(E2007),
1272            SemanticDiagnosticKind::LiteralError(..) => error_code!(E2008),
1273            SemanticDiagnosticKind::NotAVariant => error_code!(E2009),
1274            SemanticDiagnosticKind::NotAStruct => error_code!(E2010),
1275            SemanticDiagnosticKind::NotAType => error_code!(E2011),
1276            SemanticDiagnosticKind::NotATrait => error_code!(E2012),
1277            SemanticDiagnosticKind::NotAnImpl => error_code!(E2013),
1278            SemanticDiagnosticKind::ImplItemNotInTrait { .. } => error_code!(E2014),
1279            SemanticDiagnosticKind::ImplicitImplNotInferred { .. } => error_code!(E2015),
1280            SemanticDiagnosticKind::GenericsNotSupportedInItem { .. } => error_code!(E2016),
1281            SemanticDiagnosticKind::UnexpectedGenericArgs => error_code!(E2017),
1282            SemanticDiagnosticKind::UnknownMember => error_code!(E2018),
1283            SemanticDiagnosticKind::CannotCreateInstancesOfPhantomTypes => error_code!(E2019),
1284            SemanticDiagnosticKind::NonPhantomTypeContainingPhantomType => error_code!(E2020),
1285            SemanticDiagnosticKind::MemberSpecifiedMoreThanOnce => error_code!(E2021),
1286            SemanticDiagnosticKind::StructBaseStructExpressionNotLast => error_code!(E2022),
1287            SemanticDiagnosticKind::StructBaseStructExpressionNoEffect => error_code!(E2023),
1288            SemanticDiagnosticKind::ConstCycle => error_code!(E2024),
1289            SemanticDiagnosticKind::UseCycle => error_code!(E2025),
1290            SemanticDiagnosticKind::TypeAliasCycle => error_code!(E2026),
1291            SemanticDiagnosticKind::ImplAliasCycle => error_code!(E2027),
1292            SemanticDiagnosticKind::ImplRequirementCycle => error_code!(E2028),
1293            SemanticDiagnosticKind::WrongNumberOfParameters { .. } => error_code!(E2029),
1294            SemanticDiagnosticKind::WrongNumberOfArguments { .. } => error_code!(E2030),
1295            SemanticDiagnosticKind::WrongParameterType { .. } => error_code!(E2031),
1296            SemanticDiagnosticKind::VariantCtorNotImmutable => error_code!(E2032),
1297            SemanticDiagnosticKind::TraitParamMutable { .. } => error_code!(E2033),
1298            SemanticDiagnosticKind::ParameterShouldBeReference { .. } => error_code!(E2034),
1299            SemanticDiagnosticKind::ParameterShouldNotBeReference { .. } => error_code!(E2035),
1300            SemanticDiagnosticKind::WrongParameterName { .. } => error_code!(E2036),
1301            SemanticDiagnosticKind::WrongGenericParamTraitForImplFunction { .. } => {
1302                error_code!(E2037)
1303            }
1304            SemanticDiagnosticKind::WrongGenericParamKindForImplFunction { .. } => {
1305                error_code!(E2038)
1306            }
1307            SemanticDiagnosticKind::WrongType { .. } => error_code!(E2039),
1308            SemanticDiagnosticKind::InconsistentBinding => error_code!(E2040),
1309            SemanticDiagnosticKind::WrongArgumentType { .. } => error_code!(E2041),
1310            SemanticDiagnosticKind::WrongReturnType { .. } => error_code!(E2042),
1311            SemanticDiagnosticKind::WrongExprType { .. } => error_code!(E2043),
1312            SemanticDiagnosticKind::WrongNumberOfGenericParamsForImplFunction { .. } => {
1313                error_code!(E2044)
1314            }
1315            SemanticDiagnosticKind::WrongReturnTypeForImpl { .. } => error_code!(E2045),
1316            SemanticDiagnosticKind::AmbiguousTrait { .. } => error_code!(E2046),
1317            SemanticDiagnosticKind::VariableNotFound(..) => error_code!(E2047),
1318            SemanticDiagnosticKind::MissingVariableInPattern => error_code!(E2048),
1319            SemanticDiagnosticKind::VariableDefinedMultipleTimesInPattern(..) => error_code!(E2049),
1320            SemanticDiagnosticKind::StructMemberRedefinition { .. } => error_code!(E2050),
1321            SemanticDiagnosticKind::EnumVariantRedefinition { .. } => error_code!(E2051),
1322            SemanticDiagnosticKind::InfiniteSizeType(..) => error_code!(E2052),
1323            SemanticDiagnosticKind::ArrayOfZeroSizedElements(..) => error_code!(E2053),
1324            SemanticDiagnosticKind::ParamNameRedefinition { .. } => error_code!(E2054),
1325            SemanticDiagnosticKind::ConditionNotBool(..) => error_code!(E2055),
1326            SemanticDiagnosticKind::IncompatibleArms { .. } => error_code!(E2056),
1327            SemanticDiagnosticKind::TypeHasNoMembers { .. } => error_code!(E2057),
1328            SemanticDiagnosticKind::NoSuchStructMember { .. } => error_code!(E2058),
1329            SemanticDiagnosticKind::MemberNotVisible(..) => error_code!(E2059),
1330            SemanticDiagnosticKind::NoSuchVariant { .. } => error_code!(E2060),
1331            SemanticDiagnosticKind::ReturnTypeNotErrorPropagateType => error_code!(E2061),
1332            SemanticDiagnosticKind::IncompatibleErrorPropagateType { .. } => error_code!(E2062),
1333            SemanticDiagnosticKind::ErrorPropagateOnNonErrorType(_) => error_code!(E2063),
1334            SemanticDiagnosticKind::UnhandledMustUseType(_) => error_code!(E2064),
1335            SemanticDiagnosticKind::UnstableFeature { .. } => error_code!(E2065),
1336            SemanticDiagnosticKind::DeprecatedFeature { .. } => error_code!(E2066),
1337            SemanticDiagnosticKind::InternalFeature { .. } => error_code!(E2067),
1338            SemanticDiagnosticKind::FeatureMarkerDiagnostic(_) => error_code!(E2068),
1339            SemanticDiagnosticKind::UnhandledMustUseFunction => error_code!(E2069),
1340            SemanticDiagnosticKind::UnusedConstant => error_code!(E2070),
1341            SemanticDiagnosticKind::UnusedUse => error_code!(E2071),
1342            SemanticDiagnosticKind::MultipleConstantDefinition(_) => error_code!(E2072),
1343            SemanticDiagnosticKind::MultipleDefinitionforBinding(_) => error_code!(E2073),
1344            SemanticDiagnosticKind::MultipleGenericItemDefinition(_) => error_code!(E2074),
1345            SemanticDiagnosticKind::UnsupportedUseItemInStatement => error_code!(E2075),
1346            SemanticDiagnosticKind::ConstGenericParamNotSupported => error_code!(E2076),
1347            SemanticDiagnosticKind::NegativeImplsNotEnabled => error_code!(E2077),
1348            SemanticDiagnosticKind::NegativeImplsOnlyOnImpls => error_code!(E2078),
1349            SemanticDiagnosticKind::RefArgNotAVariable => error_code!(E2079),
1350            SemanticDiagnosticKind::RefArgNotMutable => error_code!(E2080),
1351            SemanticDiagnosticKind::RefArgNotExplicit => error_code!(E2081),
1352            SemanticDiagnosticKind::ImmutableArgWithModifiers => error_code!(E2082),
1353            SemanticDiagnosticKind::AssignmentToImmutableVar => error_code!(E2083),
1354            SemanticDiagnosticKind::InvalidLhsForAssignment => error_code!(E2084),
1355            SemanticDiagnosticKind::InvalidMemberExpression => error_code!(E2085),
1356            SemanticDiagnosticKind::InvalidPath => error_code!(E2086),
1357            SemanticDiagnosticKind::AmbiguousPath(_) => error_code!(E2087),
1358            SemanticDiagnosticKind::UseSelfNonMulti => error_code!(E2088),
1359            SemanticDiagnosticKind::UseSelfEmptyPath => error_code!(E2089),
1360            SemanticDiagnosticKind::UseStarEmptyPath => error_code!(E2090),
1361            SemanticDiagnosticKind::GlobalUsesNotSupportedInEdition(_) => error_code!(E2091),
1362            SemanticDiagnosticKind::TraitInTraitMustBeExplicit => error_code!(E2092),
1363            SemanticDiagnosticKind::ImplInImplMustBeExplicit => error_code!(E2093),
1364            SemanticDiagnosticKind::TraitItemForbiddenInTheTrait => error_code!(E2094),
1365            SemanticDiagnosticKind::TraitItemForbiddenInItsImpl => error_code!(E2095),
1366            SemanticDiagnosticKind::ImplItemForbiddenInTheImpl => error_code!(E2096),
1367            SemanticDiagnosticKind::SuperUsedInRootModule => error_code!(E2097),
1368            SemanticDiagnosticKind::SuperUsedInMacroCallTopLevel => error_code!(E2098),
1369            SemanticDiagnosticKind::ItemNotVisible(..) => error_code!(E2099),
1370            SemanticDiagnosticKind::UnusedImport(_) => error_code!(E2100),
1371            SemanticDiagnosticKind::RedundantModifier { .. } => error_code!(E2101),
1372            SemanticDiagnosticKind::ReferenceLocalVariable => error_code!(E2102),
1373            SemanticDiagnosticKind::BadPatternForInputType(_) => error_code!(E2103),
1374            SemanticDiagnosticKind::WrongNumberOfTupleElements { .. } => error_code!(E2107),
1375            SemanticDiagnosticKind::WrongNumberOfFixedSizeArrayElements { .. } => {
1376                error_code!(E2108)
1377            }
1378            SemanticDiagnosticKind::WrongEnum { .. } => error_code!(E2109),
1379            SemanticDiagnosticKind::InvalidCopyTraitImpl(_) => error_code!(E2110),
1380            SemanticDiagnosticKind::InvalidDropTraitImpl(_) => error_code!(E2111),
1381            SemanticDiagnosticKind::InvalidImplItem(_) => error_code!(E2112),
1382            SemanticDiagnosticKind::PassPanicAsNopanic { .. } => error_code!(E2113),
1383            SemanticDiagnosticKind::PassConstAsNonConst { .. } => error_code!(E2114),
1384            SemanticDiagnosticKind::PanicableFromNonPanicable => error_code!(E2115),
1385            SemanticDiagnosticKind::PanicableExternFunction => error_code!(E2116),
1386            SemanticDiagnosticKind::MacroGeneratedCodeParserDiagnostic(_) => error_code!(E2117),
1387            SemanticDiagnosticKind::NameDefinedMultipleTimes(_) => error_code!(E2118),
1388            SemanticDiagnosticKind::NonPrivateUseStar => error_code!(E2119),
1389            SemanticDiagnosticKind::SelfGlobalUse => error_code!(E2120),
1390            SemanticDiagnosticKind::NamedArgumentsAreNotSupported => error_code!(E2121),
1391            SemanticDiagnosticKind::ArgPassedToNegativeImpl => error_code!(E2122),
1392            SemanticDiagnosticKind::UnnamedArgumentFollowsNamed => error_code!(E2123),
1393            SemanticDiagnosticKind::NamedArgumentMismatch { .. } => error_code!(E2124),
1394            SemanticDiagnosticKind::UnsupportedOutsideOfFunction(_) => error_code!(E2125),
1395            SemanticDiagnosticKind::ConstTypeNotVarFree => error_code!(E2126),
1396            SemanticDiagnosticKind::UnsupportedConstant => error_code!(E2127),
1397            SemanticDiagnosticKind::FailedConstantCalculation => error_code!(E2128),
1398            SemanticDiagnosticKind::ConstantCalculationDepthExceeded => error_code!(E2129),
1399            SemanticDiagnosticKind::InnerFailedConstantCalculation(..) => error_code!(E2130),
1400            SemanticDiagnosticKind::DivisionByZero => error_code!(E2131),
1401            SemanticDiagnosticKind::ExternTypeWithImplGenericsNotSupported => error_code!(E2132),
1402            SemanticDiagnosticKind::MissingSemicolon => error_code!(E2133),
1403            SemanticDiagnosticKind::TraitMismatch { .. } => error_code!(E2134),
1404            SemanticDiagnosticKind::DerefNonRef { .. } => error_code!(E2135),
1405            SemanticDiagnosticKind::NoImplementationOfIndexOperator { .. } => error_code!(E2136),
1406            SemanticDiagnosticKind::NoImplementationOfTrait { .. } => error_code!(E2137),
1407            SemanticDiagnosticKind::CallExpressionRequiresFunction { .. } => error_code!(E2138),
1408            SemanticDiagnosticKind::MultipleImplementationOfIndexOperator(_) => error_code!(E2139),
1409            SemanticDiagnosticKind::UnsupportedInlineArguments => error_code!(E2140),
1410            SemanticDiagnosticKind::RedundantInlineAttribute => error_code!(E2141),
1411            SemanticDiagnosticKind::InlineAttrForExternFunctionNotAllowed => error_code!(E2142),
1412            SemanticDiagnosticKind::InlineAlwaysWithImplGenericArgNotAllowed => error_code!(E2143),
1413            SemanticDiagnosticKind::TailExpressionNotAllowedInLoop => error_code!(E2144),
1414            SemanticDiagnosticKind::ContinueOnlyAllowedInsideALoop => error_code!(E2145),
1415            SemanticDiagnosticKind::BreakOnlyAllowedInsideALoop => error_code!(E2146),
1416            SemanticDiagnosticKind::BreakWithValueOnlyAllowedInsideALoop => error_code!(E2147),
1417            SemanticDiagnosticKind::ErrorPropagateNotAllowedInsideALoop => error_code!(E2148),
1418            SemanticDiagnosticKind::ImplicitPrecedenceAttrForExternFunctionNotAllowed => {
1419                error_code!(E2149)
1420            }
1421            SemanticDiagnosticKind::RedundantImplicitPrecedenceAttribute => error_code!(E2150),
1422            SemanticDiagnosticKind::UnsupportedImplicitPrecedenceArguments => error_code!(E2151),
1423            SemanticDiagnosticKind::UnsupportedFeatureAttrArguments => error_code!(E2152),
1424            SemanticDiagnosticKind::UnsupportedAllowAttrArguments => error_code!(E2153),
1425            SemanticDiagnosticKind::UnsupportedPubArgument => error_code!(E2154),
1426            SemanticDiagnosticKind::UnknownStatementAttribute => error_code!(E2155),
1427            SemanticDiagnosticKind::InlineMacroNotFound(_) => error_code!(E2156),
1428            SemanticDiagnosticKind::InlineMacroFailed(_) => error_code!(E2157),
1429            SemanticDiagnosticKind::InlineMacroNoMatchingRule(_) => error_code!(E2158),
1430            SemanticDiagnosticKind::MacroCallToNotAMacro(_) => error_code!(E2159),
1431            SemanticDiagnosticKind::UnknownGenericParam(_) => error_code!(E2160),
1432            SemanticDiagnosticKind::PositionalGenericAfterNamed => error_code!(E2161),
1433            SemanticDiagnosticKind::GenericArgDuplicate(_) => error_code!(E2162),
1434            SemanticDiagnosticKind::TooManyGenericArguments { .. } => error_code!(E2163),
1435            SemanticDiagnosticKind::GenericArgOutOfOrder(_) => error_code!(E2164),
1436            SemanticDiagnosticKind::CouponForExternFunctionNotAllowed => error_code!(E2165),
1437            SemanticDiagnosticKind::CouponArgumentNoModifiers => error_code!(E2166),
1438            SemanticDiagnosticKind::CouponsDisabled => error_code!(E2167),
1439            SemanticDiagnosticKind::ReprPtrsDisabled => error_code!(E2168),
1440            SemanticDiagnosticKind::AssignmentToReprPtrVariable(_) => error_code!(E2169),
1441            SemanticDiagnosticKind::FixedSizeArrayTypeNonSingleType => error_code!(E2170),
1442            SemanticDiagnosticKind::FixedSizeArrayTypeEmptySize => error_code!(E2171),
1443            SemanticDiagnosticKind::FixedSizeArrayNonNumericSize => error_code!(E2172),
1444            SemanticDiagnosticKind::FixedSizeArrayNonSingleValue => error_code!(E2173),
1445            SemanticDiagnosticKind::FixedSizeArraySizeTooBig => error_code!(E2174),
1446            SemanticDiagnosticKind::SelfNotSupportedInContext => error_code!(E2175),
1447            SemanticDiagnosticKind::SelfMustBeFirst => error_code!(E2176),
1448            SemanticDiagnosticKind::DollarNotSupportedInContext => error_code!(E2177),
1449            SemanticDiagnosticKind::UnknownResolverModifier { .. } => error_code!(E2178),
1450            SemanticDiagnosticKind::EmptyPathAfterResolverModifier => error_code!(E2179),
1451            SemanticDiagnosticKind::DerefCycle { .. } => error_code!(E2180),
1452            SemanticDiagnosticKind::CompilerTraitReImplementation { .. } => error_code!(E2181),
1453            SemanticDiagnosticKind::ClosureInGlobalScope => error_code!(E2182),
1454            SemanticDiagnosticKind::MaybeMissingColonColon => error_code!(E2183),
1455            SemanticDiagnosticKind::CallingShadowedFunction { .. } => error_code!(E2184),
1456            SemanticDiagnosticKind::RefClosureArgument => error_code!(E2185),
1457            SemanticDiagnosticKind::RefClosureParam => error_code!(E2186),
1458            SemanticDiagnosticKind::MustBeNextToTypeOrTrait { .. } => error_code!(E2187),
1459            SemanticDiagnosticKind::MutableCapturedVariable => error_code!(E2188),
1460            SemanticDiagnosticKind::NonTraitTypeConstrained { .. } => error_code!(E2189),
1461            SemanticDiagnosticKind::DuplicateTypeConstraint { .. } => error_code!(E2190),
1462            SemanticDiagnosticKind::TypeConstraintsSyntaxNotEnabled => error_code!(E2191),
1463            SemanticDiagnosticKind::PatternMissingArgs(_) => error_code!(E2192),
1464            SemanticDiagnosticKind::UndefinedMacroPlaceholder(_) => error_code!(E2193),
1465            SemanticDiagnosticKind::MacroPlaceholderRepDepthMismatch { .. } => error_code!(E2198),
1466            SemanticDiagnosticKind::MacroPlaceholderRepDriverMismatch(_) => error_code!(E2199),
1467            SemanticDiagnosticKind::UserDefinedInlineMacrosDisabled => error_code!(E2194),
1468            SemanticDiagnosticKind::NonNeverLetElseType => error_code!(E2195),
1469            SemanticDiagnosticKind::OnlyTypeOrConstParamsInNegImpl => error_code!(E2196),
1470            SemanticDiagnosticKind::UnsupportedItemInStatement => error_code!(E2197),
1471            SemanticDiagnosticKind::PluginDiagnostic(diag) => {
1472                diag.error_code.unwrap_or(error_code!(E2200))
1473            }
1474            SemanticDiagnosticKind::InternalInferenceError(inference_error) => {
1475                match inference_error {
1476                    InferenceError::Reported(_) => error_code!(E2300),
1477                    InferenceError::Cycle(_) => error_code!(E2301),
1478                    InferenceError::TypeKindMismatch { .. } => error_code!(E2302),
1479                    InferenceError::ConstKindMismatch { .. } => error_code!(E2303),
1480                    InferenceError::ImplKindMismatch { .. } => error_code!(E2304),
1481                    InferenceError::NegativeImplKindMismatch { .. } => error_code!(E2305),
1482                    InferenceError::GenericArgMismatch { .. } => error_code!(E2306),
1483                    InferenceError::TraitMismatch { .. } => error_code!(E2307),
1484                    InferenceError::ImplTypeMismatch { .. } => error_code!(E2308),
1485                    InferenceError::GenericFunctionMismatch { .. } => error_code!(E2309),
1486                    InferenceError::ConstNotInferred => error_code!(E2310),
1487                    InferenceError::NoImplsFound(_) => error_code!(E2311),
1488                    InferenceError::NoNegativeImplsFound(_) => error_code!(E2312),
1489                    InferenceError::Ambiguity(_) => error_code!(E2313),
1490                    InferenceError::TypeNotInferred(_) => error_code!(E2314),
1491                }
1492            }
1493        })
1494    }
1495
1496    fn is_same_kind(&self, other: &Self) -> bool {
1497        other.kind == self.kind
1498    }
1499}
1500
1501#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1502pub enum SemanticDiagnosticKind<'db> {
1503    ModuleFileNotFound(String),
1504    Unsupported,
1505    UnknownLiteral,
1506    UnknownBinaryOperator,
1507    UnknownTrait,
1508    UnknownImpl,
1509    UnexpectedElement {
1510        expected: Vec<ElementKind>,
1511        actual: ElementKind,
1512    },
1513    UnknownType,
1514    UnknownEnum,
1515    LiteralError(LiteralError<'db>),
1516    NotAVariant,
1517    NotAStruct,
1518    NotAType,
1519    NotATrait,
1520    NotAnImpl,
1521    ImplItemNotInTrait {
1522        impl_def_id: ImplDefId<'db>,
1523        impl_item_name: SmolStrId<'db>,
1524        trait_id: TraitId<'db>,
1525        item_kind: String,
1526    },
1527    ImplicitImplNotInferred {
1528        trait_impl_id: TraitImplId<'db>,
1529        concrete_trait_id: ConcreteTraitId<'db>,
1530    },
1531    GenericsNotSupportedInItem {
1532        scope: String,
1533        item_kind: String,
1534    },
1535    UnexpectedGenericArgs,
1536    UnknownMember,
1537    CannotCreateInstancesOfPhantomTypes,
1538    NonPhantomTypeContainingPhantomType,
1539    MemberSpecifiedMoreThanOnce,
1540    StructBaseStructExpressionNotLast,
1541    StructBaseStructExpressionNoEffect,
1542    ConstCycle,
1543    UseCycle,
1544    TypeAliasCycle,
1545    ImplAliasCycle,
1546    ImplRequirementCycle,
1547    MissingMember(SmolStrId<'db>),
1548    WrongNumberOfParameters {
1549        impl_def_id: ImplDefId<'db>,
1550        impl_function_id: ImplFunctionId<'db>,
1551        trait_id: TraitId<'db>,
1552        expected: usize,
1553        actual: usize,
1554    },
1555    WrongNumberOfArguments {
1556        expected: usize,
1557        actual: usize,
1558    },
1559    WrongParameterType {
1560        impl_def_id: ImplDefId<'db>,
1561        impl_function_id: ImplFunctionId<'db>,
1562        trait_id: TraitId<'db>,
1563        expected_ty: semantic::TypeId<'db>,
1564        actual_ty: semantic::TypeId<'db>,
1565    },
1566    VariantCtorNotImmutable,
1567    TraitParamMutable {
1568        trait_id: TraitId<'db>,
1569        function_id: TraitFunctionId<'db>,
1570    },
1571    ParameterShouldBeReference {
1572        impl_def_id: ImplDefId<'db>,
1573        impl_function_id: ImplFunctionId<'db>,
1574        trait_id: TraitId<'db>,
1575    },
1576    ParameterShouldNotBeReference {
1577        impl_def_id: ImplDefId<'db>,
1578        impl_function_id: ImplFunctionId<'db>,
1579        trait_id: TraitId<'db>,
1580    },
1581    WrongParameterName {
1582        impl_def_id: ImplDefId<'db>,
1583        impl_function_id: ImplFunctionId<'db>,
1584        trait_id: TraitId<'db>,
1585        expected_name: SmolStrId<'db>,
1586    },
1587    WrongGenericParamTraitForImplFunction {
1588        impl_def_id: ImplDefId<'db>,
1589        impl_function_id: ImplFunctionId<'db>,
1590        trait_id: TraitId<'db>,
1591        expected_trait: ConcreteTraitId<'db>,
1592        actual_trait: ConcreteTraitId<'db>,
1593    },
1594    WrongGenericParamKindForImplFunction {
1595        impl_def_id: ImplDefId<'db>,
1596        impl_function_id: ImplFunctionId<'db>,
1597        trait_id: TraitId<'db>,
1598        expected_kind: GenericKind,
1599        actual_kind: GenericKind,
1600    },
1601    WrongType {
1602        expected_ty: semantic::TypeId<'db>,
1603        actual_ty: semantic::TypeId<'db>,
1604    },
1605    InconsistentBinding,
1606    WrongArgumentType {
1607        expected_ty: semantic::TypeId<'db>,
1608        actual_ty: semantic::TypeId<'db>,
1609    },
1610    WrongReturnType {
1611        expected_ty: semantic::TypeId<'db>,
1612        actual_ty: semantic::TypeId<'db>,
1613    },
1614    WrongExprType {
1615        expected_ty: semantic::TypeId<'db>,
1616        actual_ty: semantic::TypeId<'db>,
1617    },
1618    WrongNumberOfGenericParamsForImplFunction {
1619        expected: usize,
1620        actual: usize,
1621    },
1622    WrongReturnTypeForImpl {
1623        impl_def_id: ImplDefId<'db>,
1624        impl_function_id: ImplFunctionId<'db>,
1625        trait_id: TraitId<'db>,
1626        expected_ty: semantic::TypeId<'db>,
1627        actual_ty: semantic::TypeId<'db>,
1628    },
1629    AmbiguousTrait {
1630        trait_function_id0: TraitFunctionId<'db>,
1631        trait_function_id1: TraitFunctionId<'db>,
1632    },
1633    VariableNotFound(SmolStrId<'db>),
1634    MissingVariableInPattern,
1635    VariableDefinedMultipleTimesInPattern(SmolStrId<'db>),
1636    StructMemberRedefinition {
1637        struct_id: StructId<'db>,
1638        member_name: SmolStrId<'db>,
1639    },
1640    EnumVariantRedefinition {
1641        enum_id: EnumId<'db>,
1642        variant_name: SmolStrId<'db>,
1643    },
1644    InfiniteSizeType(semantic::TypeId<'db>),
1645    ArrayOfZeroSizedElements(semantic::TypeId<'db>),
1646    ParamNameRedefinition {
1647        function_title_id: Option<FunctionTitleId<'db>>,
1648        param_name: SmolStrId<'db>,
1649    },
1650    ConditionNotBool(semantic::TypeId<'db>),
1651    IncompatibleArms {
1652        multi_arm_expr_kind: MultiArmExprKind,
1653        pending_ty: semantic::TypeId<'db>,
1654        different_ty: semantic::TypeId<'db>,
1655    },
1656    TypeHasNoMembers {
1657        ty: semantic::TypeId<'db>,
1658        member_name: SmolStrId<'db>,
1659    },
1660    CannotCallMethod {
1661        ty: semantic::TypeId<'db>,
1662        method_name: SmolStrId<'db>,
1663        inference_errors: TraitInferenceErrors<'db>,
1664        relevant_traits: Vec<String>,
1665    },
1666    NoSuchStructMember {
1667        struct_id: StructId<'db>,
1668        member_name: SmolStrId<'db>,
1669    },
1670    NoSuchTypeMember {
1671        ty: semantic::TypeId<'db>,
1672        member_name: SmolStrId<'db>,
1673    },
1674    MemberNotVisible(SmolStrId<'db>),
1675    NoSuchVariant {
1676        enum_id: EnumId<'db>,
1677        variant_name: SmolStrId<'db>,
1678    },
1679    ReturnTypeNotErrorPropagateType,
1680    IncompatibleErrorPropagateType {
1681        return_ty: semantic::TypeId<'db>,
1682        err_ty: semantic::TypeId<'db>,
1683    },
1684    ErrorPropagateOnNonErrorType(semantic::TypeId<'db>),
1685    UnhandledMustUseType(semantic::TypeId<'db>),
1686    UnstableFeature {
1687        feature_name: SmolStrId<'db>,
1688        note: Option<SmolStrId<'db>>,
1689    },
1690    DeprecatedFeature {
1691        feature_name: SmolStrId<'db>,
1692        note: Option<SmolStrId<'db>>,
1693    },
1694    InternalFeature {
1695        feature_name: SmolStrId<'db>,
1696        note: Option<SmolStrId<'db>>,
1697    },
1698    FeatureMarkerDiagnostic(FeatureMarkerDiagnostic),
1699    UnhandledMustUseFunction,
1700    UnusedVariable,
1701    UnusedConstant,
1702    UnusedUse,
1703    MultipleConstantDefinition(SmolStrId<'db>),
1704    MultipleDefinitionforBinding(SmolStrId<'db>),
1705    MultipleGenericItemDefinition(SmolStrId<'db>),
1706    UnsupportedUseItemInStatement,
1707    ConstGenericParamNotSupported,
1708    NegativeImplsNotEnabled,
1709    NegativeImplsOnlyOnImpls,
1710    RefArgNotAVariable,
1711    RefArgNotMutable,
1712    RefArgNotExplicit,
1713    ImmutableArgWithModifiers,
1714    AssignmentToImmutableVar,
1715    InvalidLhsForAssignment,
1716    InvalidMemberExpression,
1717    InvalidPath,
1718    PathNotFound(NotFoundItemType),
1719    AmbiguousPath(Vec<ModuleItemId<'db>>),
1720    UseSelfNonMulti,
1721    UseSelfEmptyPath,
1722    UseStarEmptyPath,
1723    GlobalUsesNotSupportedInEdition(Edition),
1724    TraitInTraitMustBeExplicit,
1725    ImplInImplMustBeExplicit,
1726    TraitItemForbiddenInTheTrait,
1727    TraitItemForbiddenInItsImpl,
1728    ImplItemForbiddenInTheImpl,
1729    SuperUsedInRootModule,
1730    SuperUsedInMacroCallTopLevel,
1731    ItemNotVisible(ModuleItemId<'db>, Vec<ModuleId<'db>>),
1732    UnusedImport(UseId<'db>),
1733    RedundantModifier {
1734        current_modifier: SmolStrId<'db>,
1735        previous_modifier: SmolStrId<'db>,
1736    },
1737    ReferenceLocalVariable,
1738    BadPatternForInputType(semantic::TypeId<'db>),
1739    WrongNumberOfTupleElements {
1740        expected: usize,
1741        actual: usize,
1742    },
1743    WrongNumberOfFixedSizeArrayElements {
1744        expected: usize,
1745        actual: usize,
1746    },
1747    WrongEnum {
1748        expected_enum: EnumId<'db>,
1749        actual_enum: EnumId<'db>,
1750    },
1751    InvalidCopyTraitImpl(InferenceError<'db>),
1752    InvalidDropTraitImpl(InferenceError<'db>),
1753    InvalidImplItem(SmolStrId<'db>),
1754    MissingItemsInImpl(Vec<SmolStrId<'db>>),
1755    PassPanicAsNopanic {
1756        impl_function_id: ImplFunctionId<'db>,
1757        trait_id: TraitId<'db>,
1758    },
1759    PassConstAsNonConst {
1760        impl_function_id: ImplFunctionId<'db>,
1761        trait_id: TraitId<'db>,
1762    },
1763    PanicableFromNonPanicable,
1764    PanicableExternFunction,
1765    MacroGeneratedCodeParserDiagnostic(ParserDiagnostic<'db>),
1766    PluginDiagnostic(PluginDiagnostic<'db>),
1767    NameDefinedMultipleTimes(SmolStrId<'db>),
1768    NonPrivateUseStar,
1769    SelfGlobalUse,
1770    NamedArgumentsAreNotSupported,
1771    ArgPassedToNegativeImpl,
1772    UnnamedArgumentFollowsNamed,
1773    NamedArgumentMismatch {
1774        expected: SmolStrId<'db>,
1775        found: SmolStrId<'db>,
1776    },
1777    UnsupportedOutsideOfFunction(UnsupportedOutsideOfFunctionFeatureName),
1778    ConstTypeNotVarFree,
1779    UnsupportedConstant,
1780    FailedConstantCalculation,
1781    ConstantCalculationDepthExceeded,
1782    InnerFailedConstantCalculation(Box<SemanticDiagnostic<'db>>, Vec<DiagnosticNote<'db>>),
1783    DivisionByZero,
1784    ExternTypeWithImplGenericsNotSupported,
1785    MissingSemicolon,
1786    TraitMismatch {
1787        expected_trt: semantic::ConcreteTraitId<'db>,
1788        actual_trt: semantic::ConcreteTraitId<'db>,
1789    },
1790    DerefNonRef {
1791        ty: semantic::TypeId<'db>,
1792    },
1793    InternalInferenceError(InferenceError<'db>),
1794    NoImplementationOfIndexOperator {
1795        ty: semantic::TypeId<'db>,
1796        inference_errors: TraitInferenceErrors<'db>,
1797    },
1798    NoImplementationOfTrait {
1799        ty: semantic::TypeId<'db>,
1800        trait_name: SmolStrId<'db>,
1801        inference_errors: TraitInferenceErrors<'db>,
1802    },
1803    CallExpressionRequiresFunction {
1804        ty: semantic::TypeId<'db>,
1805        inference_errors: TraitInferenceErrors<'db>,
1806    },
1807    MultipleImplementationOfIndexOperator(semantic::TypeId<'db>),
1808
1809    UnsupportedInlineArguments,
1810    RedundantInlineAttribute,
1811    InlineAttrForExternFunctionNotAllowed,
1812    InlineAlwaysWithImplGenericArgNotAllowed,
1813    TailExpressionNotAllowedInLoop,
1814    ContinueOnlyAllowedInsideALoop,
1815    BreakOnlyAllowedInsideALoop,
1816    BreakWithValueOnlyAllowedInsideALoop,
1817    ErrorPropagateNotAllowedInsideALoop,
1818    ImplicitPrecedenceAttrForExternFunctionNotAllowed,
1819    RedundantImplicitPrecedenceAttribute,
1820    UnsupportedImplicitPrecedenceArguments,
1821    UnsupportedFeatureAttrArguments,
1822    UnsupportedAllowAttrArguments,
1823    UnsupportedPubArgument,
1824    UnknownStatementAttribute,
1825    InlineMacroNotFound(SmolStrId<'db>),
1826    InlineMacroFailed(SmolStrId<'db>),
1827    InlineMacroNoMatchingRule(SmolStrId<'db>),
1828    MacroCallToNotAMacro(SmolStrId<'db>),
1829    UnknownGenericParam(SmolStrId<'db>),
1830    PositionalGenericAfterNamed,
1831    GenericArgDuplicate(SmolStrId<'db>),
1832    TooManyGenericArguments {
1833        expected: usize,
1834        actual: usize,
1835    },
1836    GenericArgOutOfOrder(SmolStrId<'db>),
1837    CouponForExternFunctionNotAllowed,
1838    CouponArgumentNoModifiers,
1839    /// Coupons are disabled in the current crate.
1840    CouponsDisabled,
1841    /// Representation pointers are disabled in the current crate.
1842    ReprPtrsDisabled,
1843    /// Cannot assign to a variable with a taken pointer.
1844    AssignmentToReprPtrVariable(Vec<DiagnosticNote<'db>>),
1845    FixedSizeArrayTypeNonSingleType,
1846    FixedSizeArrayTypeEmptySize,
1847    FixedSizeArrayNonNumericSize,
1848    FixedSizeArrayNonSingleValue,
1849    FixedSizeArraySizeTooBig,
1850    SelfNotSupportedInContext,
1851    SelfMustBeFirst,
1852    DollarNotSupportedInContext,
1853    UnknownResolverModifier {
1854        modifier: SmolStrId<'db>,
1855    },
1856    EmptyPathAfterResolverModifier,
1857    DerefCycle {
1858        deref_chain: String,
1859    },
1860    CompilerTraitReImplementation {
1861        trait_id: TraitId<'db>,
1862    },
1863    ClosureInGlobalScope,
1864    MaybeMissingColonColon,
1865    CallingShadowedFunction {
1866        shadowed_function_name: SmolStrId<'db>,
1867    },
1868    RefClosureArgument,
1869    RefClosureParam,
1870    MustBeNextToTypeOrTrait {
1871        trait_id: TraitId<'db>,
1872    },
1873    MutableCapturedVariable,
1874    NonTraitTypeConstrained {
1875        identifier: SmolStrId<'db>,
1876        concrete_trait_id: ConcreteTraitId<'db>,
1877    },
1878    DuplicateTypeConstraint {
1879        concrete_trait_type_id: ConcreteTraitTypeId<'db>,
1880    },
1881    TypeConstraintsSyntaxNotEnabled,
1882    PatternMissingArgs(ast::ExprPath<'db>),
1883    UndefinedMacroPlaceholder(SmolStrId<'db>),
1884    MacroPlaceholderRepDepthMismatch {
1885        name: SmolStrId<'db>,
1886        required: usize,
1887        actual: usize,
1888    },
1889    MacroPlaceholderRepDriverMismatch(SmolStrId<'db>),
1890    UserDefinedInlineMacrosDisabled,
1891    NonNeverLetElseType,
1892    OnlyTypeOrConstParamsInNegImpl,
1893    UnsupportedItemInStatement,
1894}
1895
1896/// The kind of an expression with multiple possible return types.
1897#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1898pub enum MultiArmExprKind {
1899    If,
1900    Match,
1901    Loop,
1902}
1903
1904// TODO(Gil): It seems to have the same functionality as ElementKind, maybe we can merge them.
1905#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1906pub enum NotFoundItemType {
1907    Identifier,
1908    Function,
1909    Type,
1910    Trait,
1911    Impl,
1912    Macro,
1913}
1914
1915#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1916pub enum UnsupportedOutsideOfFunctionFeatureName {
1917    ReturnStatement,
1918    ErrorPropagate,
1919}
1920
1921#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1922pub enum ElementKind {
1923    Constant,
1924    Variable,
1925    Module,
1926    Function,
1927    Type,
1928    Variant,
1929    Trait,
1930    Impl,
1931    Macro,
1932}
1933impl<'db> From<&ResolvedConcreteItem<'db>> for ElementKind {
1934    fn from(val: &ResolvedConcreteItem<'db>) -> Self {
1935        match val {
1936            ResolvedConcreteItem::Constant(_) => ElementKind::Constant,
1937            ResolvedConcreteItem::Module(_) => ElementKind::Module,
1938            ResolvedConcreteItem::Function(_) => ElementKind::Function,
1939            ResolvedConcreteItem::Type(_) => ElementKind::Type,
1940            ResolvedConcreteItem::Variant(_) => ElementKind::Variant,
1941            ResolvedConcreteItem::Trait(_) | ResolvedConcreteItem::SelfTrait(_) => {
1942                ElementKind::Trait
1943            }
1944            ResolvedConcreteItem::Impl(_) => ElementKind::Impl,
1945            ResolvedConcreteItem::Macro(_) => ElementKind::Macro,
1946        }
1947    }
1948}
1949impl<'db> From<&ResolvedGenericItem<'db>> for ElementKind {
1950    fn from(val: &ResolvedGenericItem<'db>) -> Self {
1951        match val {
1952            ResolvedGenericItem::GenericConstant(_)
1953            | ResolvedGenericItem::TraitItem(TraitItemId::Constant(_)) => ElementKind::Constant,
1954            ResolvedGenericItem::Module(_) => ElementKind::Module,
1955            ResolvedGenericItem::GenericFunction(_)
1956            | ResolvedGenericItem::TraitItem(TraitItemId::Function(_)) => ElementKind::Function,
1957            ResolvedGenericItem::GenericType(_)
1958            | ResolvedGenericItem::GenericTypeAlias(_)
1959            | ResolvedGenericItem::TraitItem(TraitItemId::Type(_)) => ElementKind::Type,
1960            ResolvedGenericItem::Variant(_) => ElementKind::Variant,
1961            ResolvedGenericItem::Trait(_) => ElementKind::Trait,
1962            ResolvedGenericItem::Impl(_)
1963            | ResolvedGenericItem::GenericImplAlias(_)
1964            | ResolvedGenericItem::TraitItem(TraitItemId::Impl(_)) => ElementKind::Impl,
1965            ResolvedGenericItem::Variable(_) => ElementKind::Variable,
1966            ResolvedGenericItem::Macro(_) => ElementKind::Macro,
1967        }
1968    }
1969}
1970impl Display for ElementKind {
1971    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1972        let res = match self {
1973            ElementKind::Constant => "constant",
1974            ElementKind::Variable => "variable",
1975            ElementKind::Module => "module",
1976            ElementKind::Function => "function",
1977            ElementKind::Type => "type",
1978            ElementKind::Variant => "variant",
1979            ElementKind::Trait => "trait",
1980            ElementKind::Impl => "impl",
1981            ElementKind::Macro => "macro",
1982        };
1983        write!(f, "{res}")
1984    }
1985}
1986
1987/// A list of trait functions and the inference errors that occurred while trying to infer them.
1988#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1989pub struct TraitInferenceErrors<'db> {
1990    pub traits_and_errors: Vec<(TraitFunctionId<'db>, InferenceError<'db>)>,
1991}
1992impl<'db> TraitInferenceErrors<'db> {
1993    /// Is the error list empty.
1994    pub fn is_empty(&self) -> bool {
1995        self.traits_and_errors.is_empty()
1996    }
1997    /// Format the list of errors.
1998    fn format(&self, db: &dyn Database) -> String {
1999        self.traits_and_errors
2000            .iter()
2001            .map(|(trait_function_id, inference_error)| {
2002                format!(
2003                    "Candidate `{}` inference failed with: {}",
2004                    trait_function_id.full_path(db),
2005                    inference_error.format(db)
2006                )
2007            })
2008            .join("\n")
2009    }
2010}