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                    InferenceError::InvalidLiteralType(_) => error_code!(E2315),
1492                }
1493            }
1494        })
1495    }
1496
1497    fn is_same_kind(&self, other: &Self) -> bool {
1498        other.kind == self.kind
1499    }
1500}
1501
1502#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1503pub enum SemanticDiagnosticKind<'db> {
1504    ModuleFileNotFound(String),
1505    Unsupported,
1506    UnknownLiteral,
1507    UnknownBinaryOperator,
1508    UnknownTrait,
1509    UnknownImpl,
1510    UnexpectedElement {
1511        expected: Vec<ElementKind>,
1512        actual: ElementKind,
1513    },
1514    UnknownType,
1515    UnknownEnum,
1516    LiteralError(LiteralError<'db>),
1517    NotAVariant,
1518    NotAStruct,
1519    NotAType,
1520    NotATrait,
1521    NotAnImpl,
1522    ImplItemNotInTrait {
1523        impl_def_id: ImplDefId<'db>,
1524        impl_item_name: SmolStrId<'db>,
1525        trait_id: TraitId<'db>,
1526        item_kind: String,
1527    },
1528    ImplicitImplNotInferred {
1529        trait_impl_id: TraitImplId<'db>,
1530        concrete_trait_id: ConcreteTraitId<'db>,
1531    },
1532    GenericsNotSupportedInItem {
1533        scope: String,
1534        item_kind: String,
1535    },
1536    UnexpectedGenericArgs,
1537    UnknownMember,
1538    CannotCreateInstancesOfPhantomTypes,
1539    NonPhantomTypeContainingPhantomType,
1540    MemberSpecifiedMoreThanOnce,
1541    StructBaseStructExpressionNotLast,
1542    StructBaseStructExpressionNoEffect,
1543    ConstCycle,
1544    UseCycle,
1545    TypeAliasCycle,
1546    ImplAliasCycle,
1547    ImplRequirementCycle,
1548    MissingMember(SmolStrId<'db>),
1549    WrongNumberOfParameters {
1550        impl_def_id: ImplDefId<'db>,
1551        impl_function_id: ImplFunctionId<'db>,
1552        trait_id: TraitId<'db>,
1553        expected: usize,
1554        actual: usize,
1555    },
1556    WrongNumberOfArguments {
1557        expected: usize,
1558        actual: usize,
1559    },
1560    WrongParameterType {
1561        impl_def_id: ImplDefId<'db>,
1562        impl_function_id: ImplFunctionId<'db>,
1563        trait_id: TraitId<'db>,
1564        expected_ty: semantic::TypeId<'db>,
1565        actual_ty: semantic::TypeId<'db>,
1566    },
1567    VariantCtorNotImmutable,
1568    TraitParamMutable {
1569        trait_id: TraitId<'db>,
1570        function_id: TraitFunctionId<'db>,
1571    },
1572    ParameterShouldBeReference {
1573        impl_def_id: ImplDefId<'db>,
1574        impl_function_id: ImplFunctionId<'db>,
1575        trait_id: TraitId<'db>,
1576    },
1577    ParameterShouldNotBeReference {
1578        impl_def_id: ImplDefId<'db>,
1579        impl_function_id: ImplFunctionId<'db>,
1580        trait_id: TraitId<'db>,
1581    },
1582    WrongParameterName {
1583        impl_def_id: ImplDefId<'db>,
1584        impl_function_id: ImplFunctionId<'db>,
1585        trait_id: TraitId<'db>,
1586        expected_name: SmolStrId<'db>,
1587    },
1588    WrongGenericParamTraitForImplFunction {
1589        impl_def_id: ImplDefId<'db>,
1590        impl_function_id: ImplFunctionId<'db>,
1591        trait_id: TraitId<'db>,
1592        expected_trait: ConcreteTraitId<'db>,
1593        actual_trait: ConcreteTraitId<'db>,
1594    },
1595    WrongGenericParamKindForImplFunction {
1596        impl_def_id: ImplDefId<'db>,
1597        impl_function_id: ImplFunctionId<'db>,
1598        trait_id: TraitId<'db>,
1599        expected_kind: GenericKind,
1600        actual_kind: GenericKind,
1601    },
1602    WrongType {
1603        expected_ty: semantic::TypeId<'db>,
1604        actual_ty: semantic::TypeId<'db>,
1605    },
1606    InconsistentBinding,
1607    WrongArgumentType {
1608        expected_ty: semantic::TypeId<'db>,
1609        actual_ty: semantic::TypeId<'db>,
1610    },
1611    WrongReturnType {
1612        expected_ty: semantic::TypeId<'db>,
1613        actual_ty: semantic::TypeId<'db>,
1614    },
1615    WrongExprType {
1616        expected_ty: semantic::TypeId<'db>,
1617        actual_ty: semantic::TypeId<'db>,
1618    },
1619    WrongNumberOfGenericParamsForImplFunction {
1620        expected: usize,
1621        actual: usize,
1622    },
1623    WrongReturnTypeForImpl {
1624        impl_def_id: ImplDefId<'db>,
1625        impl_function_id: ImplFunctionId<'db>,
1626        trait_id: TraitId<'db>,
1627        expected_ty: semantic::TypeId<'db>,
1628        actual_ty: semantic::TypeId<'db>,
1629    },
1630    AmbiguousTrait {
1631        trait_function_id0: TraitFunctionId<'db>,
1632        trait_function_id1: TraitFunctionId<'db>,
1633    },
1634    VariableNotFound(SmolStrId<'db>),
1635    MissingVariableInPattern,
1636    VariableDefinedMultipleTimesInPattern(SmolStrId<'db>),
1637    StructMemberRedefinition {
1638        struct_id: StructId<'db>,
1639        member_name: SmolStrId<'db>,
1640    },
1641    EnumVariantRedefinition {
1642        enum_id: EnumId<'db>,
1643        variant_name: SmolStrId<'db>,
1644    },
1645    InfiniteSizeType(semantic::TypeId<'db>),
1646    ArrayOfZeroSizedElements(semantic::TypeId<'db>),
1647    ParamNameRedefinition {
1648        function_title_id: Option<FunctionTitleId<'db>>,
1649        param_name: SmolStrId<'db>,
1650    },
1651    ConditionNotBool(semantic::TypeId<'db>),
1652    IncompatibleArms {
1653        multi_arm_expr_kind: MultiArmExprKind,
1654        pending_ty: semantic::TypeId<'db>,
1655        different_ty: semantic::TypeId<'db>,
1656    },
1657    TypeHasNoMembers {
1658        ty: semantic::TypeId<'db>,
1659        member_name: SmolStrId<'db>,
1660    },
1661    CannotCallMethod {
1662        ty: semantic::TypeId<'db>,
1663        method_name: SmolStrId<'db>,
1664        inference_errors: TraitInferenceErrors<'db>,
1665        relevant_traits: Vec<String>,
1666    },
1667    NoSuchStructMember {
1668        struct_id: StructId<'db>,
1669        member_name: SmolStrId<'db>,
1670    },
1671    NoSuchTypeMember {
1672        ty: semantic::TypeId<'db>,
1673        member_name: SmolStrId<'db>,
1674    },
1675    MemberNotVisible(SmolStrId<'db>),
1676    NoSuchVariant {
1677        enum_id: EnumId<'db>,
1678        variant_name: SmolStrId<'db>,
1679    },
1680    ReturnTypeNotErrorPropagateType,
1681    IncompatibleErrorPropagateType {
1682        return_ty: semantic::TypeId<'db>,
1683        err_ty: semantic::TypeId<'db>,
1684    },
1685    ErrorPropagateOnNonErrorType(semantic::TypeId<'db>),
1686    UnhandledMustUseType(semantic::TypeId<'db>),
1687    UnstableFeature {
1688        feature_name: SmolStrId<'db>,
1689        note: Option<SmolStrId<'db>>,
1690    },
1691    DeprecatedFeature {
1692        feature_name: SmolStrId<'db>,
1693        note: Option<SmolStrId<'db>>,
1694    },
1695    InternalFeature {
1696        feature_name: SmolStrId<'db>,
1697        note: Option<SmolStrId<'db>>,
1698    },
1699    FeatureMarkerDiagnostic(FeatureMarkerDiagnostic),
1700    UnhandledMustUseFunction,
1701    UnusedVariable,
1702    UnusedConstant,
1703    UnusedUse,
1704    MultipleConstantDefinition(SmolStrId<'db>),
1705    MultipleDefinitionforBinding(SmolStrId<'db>),
1706    MultipleGenericItemDefinition(SmolStrId<'db>),
1707    UnsupportedUseItemInStatement,
1708    ConstGenericParamNotSupported,
1709    NegativeImplsNotEnabled,
1710    NegativeImplsOnlyOnImpls,
1711    RefArgNotAVariable,
1712    RefArgNotMutable,
1713    RefArgNotExplicit,
1714    ImmutableArgWithModifiers,
1715    AssignmentToImmutableVar,
1716    InvalidLhsForAssignment,
1717    InvalidMemberExpression,
1718    InvalidPath,
1719    PathNotFound(NotFoundItemType),
1720    AmbiguousPath(Vec<ModuleItemId<'db>>),
1721    UseSelfNonMulti,
1722    UseSelfEmptyPath,
1723    UseStarEmptyPath,
1724    GlobalUsesNotSupportedInEdition(Edition),
1725    TraitInTraitMustBeExplicit,
1726    ImplInImplMustBeExplicit,
1727    TraitItemForbiddenInTheTrait,
1728    TraitItemForbiddenInItsImpl,
1729    ImplItemForbiddenInTheImpl,
1730    SuperUsedInRootModule,
1731    SuperUsedInMacroCallTopLevel,
1732    ItemNotVisible(ModuleItemId<'db>, Vec<ModuleId<'db>>),
1733    UnusedImport(UseId<'db>),
1734    RedundantModifier {
1735        current_modifier: SmolStrId<'db>,
1736        previous_modifier: SmolStrId<'db>,
1737    },
1738    ReferenceLocalVariable,
1739    BadPatternForInputType(semantic::TypeId<'db>),
1740    WrongNumberOfTupleElements {
1741        expected: usize,
1742        actual: usize,
1743    },
1744    WrongNumberOfFixedSizeArrayElements {
1745        expected: usize,
1746        actual: usize,
1747    },
1748    WrongEnum {
1749        expected_enum: EnumId<'db>,
1750        actual_enum: EnumId<'db>,
1751    },
1752    InvalidCopyTraitImpl(InferenceError<'db>),
1753    InvalidDropTraitImpl(InferenceError<'db>),
1754    InvalidImplItem(SmolStrId<'db>),
1755    MissingItemsInImpl(Vec<SmolStrId<'db>>),
1756    PassPanicAsNopanic {
1757        impl_function_id: ImplFunctionId<'db>,
1758        trait_id: TraitId<'db>,
1759    },
1760    PassConstAsNonConst {
1761        impl_function_id: ImplFunctionId<'db>,
1762        trait_id: TraitId<'db>,
1763    },
1764    PanicableFromNonPanicable,
1765    PanicableExternFunction,
1766    MacroGeneratedCodeParserDiagnostic(ParserDiagnostic<'db>),
1767    PluginDiagnostic(PluginDiagnostic<'db>),
1768    NameDefinedMultipleTimes(SmolStrId<'db>),
1769    NonPrivateUseStar,
1770    SelfGlobalUse,
1771    NamedArgumentsAreNotSupported,
1772    ArgPassedToNegativeImpl,
1773    UnnamedArgumentFollowsNamed,
1774    NamedArgumentMismatch {
1775        expected: SmolStrId<'db>,
1776        found: SmolStrId<'db>,
1777    },
1778    UnsupportedOutsideOfFunction(UnsupportedOutsideOfFunctionFeatureName),
1779    ConstTypeNotVarFree,
1780    UnsupportedConstant,
1781    FailedConstantCalculation,
1782    ConstantCalculationDepthExceeded,
1783    InnerFailedConstantCalculation(Box<SemanticDiagnostic<'db>>, Vec<DiagnosticNote<'db>>),
1784    DivisionByZero,
1785    ExternTypeWithImplGenericsNotSupported,
1786    MissingSemicolon,
1787    TraitMismatch {
1788        expected_trt: semantic::ConcreteTraitId<'db>,
1789        actual_trt: semantic::ConcreteTraitId<'db>,
1790    },
1791    DerefNonRef {
1792        ty: semantic::TypeId<'db>,
1793    },
1794    InternalInferenceError(InferenceError<'db>),
1795    NoImplementationOfIndexOperator {
1796        ty: semantic::TypeId<'db>,
1797        inference_errors: TraitInferenceErrors<'db>,
1798    },
1799    NoImplementationOfTrait {
1800        ty: semantic::TypeId<'db>,
1801        trait_name: SmolStrId<'db>,
1802        inference_errors: TraitInferenceErrors<'db>,
1803    },
1804    CallExpressionRequiresFunction {
1805        ty: semantic::TypeId<'db>,
1806        inference_errors: TraitInferenceErrors<'db>,
1807    },
1808    MultipleImplementationOfIndexOperator(semantic::TypeId<'db>),
1809
1810    UnsupportedInlineArguments,
1811    RedundantInlineAttribute,
1812    InlineAttrForExternFunctionNotAllowed,
1813    InlineAlwaysWithImplGenericArgNotAllowed,
1814    TailExpressionNotAllowedInLoop,
1815    ContinueOnlyAllowedInsideALoop,
1816    BreakOnlyAllowedInsideALoop,
1817    BreakWithValueOnlyAllowedInsideALoop,
1818    ErrorPropagateNotAllowedInsideALoop,
1819    ImplicitPrecedenceAttrForExternFunctionNotAllowed,
1820    RedundantImplicitPrecedenceAttribute,
1821    UnsupportedImplicitPrecedenceArguments,
1822    UnsupportedFeatureAttrArguments,
1823    UnsupportedAllowAttrArguments,
1824    UnsupportedPubArgument,
1825    UnknownStatementAttribute,
1826    InlineMacroNotFound(SmolStrId<'db>),
1827    InlineMacroFailed(SmolStrId<'db>),
1828    InlineMacroNoMatchingRule(SmolStrId<'db>),
1829    MacroCallToNotAMacro(SmolStrId<'db>),
1830    UnknownGenericParam(SmolStrId<'db>),
1831    PositionalGenericAfterNamed,
1832    GenericArgDuplicate(SmolStrId<'db>),
1833    TooManyGenericArguments {
1834        expected: usize,
1835        actual: usize,
1836    },
1837    GenericArgOutOfOrder(SmolStrId<'db>),
1838    CouponForExternFunctionNotAllowed,
1839    CouponArgumentNoModifiers,
1840    /// Coupons are disabled in the current crate.
1841    CouponsDisabled,
1842    /// Representation pointers are disabled in the current crate.
1843    ReprPtrsDisabled,
1844    /// Cannot assign to a variable with a taken pointer.
1845    AssignmentToReprPtrVariable(Vec<DiagnosticNote<'db>>),
1846    FixedSizeArrayTypeNonSingleType,
1847    FixedSizeArrayTypeEmptySize,
1848    FixedSizeArrayNonNumericSize,
1849    FixedSizeArrayNonSingleValue,
1850    FixedSizeArraySizeTooBig,
1851    SelfNotSupportedInContext,
1852    SelfMustBeFirst,
1853    DollarNotSupportedInContext,
1854    UnknownResolverModifier {
1855        modifier: SmolStrId<'db>,
1856    },
1857    EmptyPathAfterResolverModifier,
1858    DerefCycle {
1859        deref_chain: String,
1860    },
1861    CompilerTraitReImplementation {
1862        trait_id: TraitId<'db>,
1863    },
1864    ClosureInGlobalScope,
1865    MaybeMissingColonColon,
1866    CallingShadowedFunction {
1867        shadowed_function_name: SmolStrId<'db>,
1868    },
1869    RefClosureArgument,
1870    RefClosureParam,
1871    MustBeNextToTypeOrTrait {
1872        trait_id: TraitId<'db>,
1873    },
1874    MutableCapturedVariable,
1875    NonTraitTypeConstrained {
1876        identifier: SmolStrId<'db>,
1877        concrete_trait_id: ConcreteTraitId<'db>,
1878    },
1879    DuplicateTypeConstraint {
1880        concrete_trait_type_id: ConcreteTraitTypeId<'db>,
1881    },
1882    TypeConstraintsSyntaxNotEnabled,
1883    PatternMissingArgs(ast::ExprPath<'db>),
1884    UndefinedMacroPlaceholder(SmolStrId<'db>),
1885    MacroPlaceholderRepDepthMismatch {
1886        name: SmolStrId<'db>,
1887        required: usize,
1888        actual: usize,
1889    },
1890    MacroPlaceholderRepDriverMismatch(SmolStrId<'db>),
1891    UserDefinedInlineMacrosDisabled,
1892    NonNeverLetElseType,
1893    OnlyTypeOrConstParamsInNegImpl,
1894    UnsupportedItemInStatement,
1895}
1896
1897/// The kind of an expression with multiple possible return types.
1898#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1899pub enum MultiArmExprKind {
1900    If,
1901    Match,
1902    Loop,
1903}
1904
1905// TODO(Gil): It seems to have the same functionality as ElementKind, maybe we can merge them.
1906#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1907pub enum NotFoundItemType {
1908    Identifier,
1909    Function,
1910    Type,
1911    Trait,
1912    Impl,
1913    Macro,
1914}
1915
1916#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1917pub enum UnsupportedOutsideOfFunctionFeatureName {
1918    ReturnStatement,
1919    ErrorPropagate,
1920}
1921
1922#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1923pub enum ElementKind {
1924    Constant,
1925    Variable,
1926    Module,
1927    Function,
1928    Type,
1929    Variant,
1930    Trait,
1931    Impl,
1932    Macro,
1933}
1934impl<'db> From<&ResolvedConcreteItem<'db>> for ElementKind {
1935    fn from(val: &ResolvedConcreteItem<'db>) -> Self {
1936        match val {
1937            ResolvedConcreteItem::Constant(_) => ElementKind::Constant,
1938            ResolvedConcreteItem::Module(_) => ElementKind::Module,
1939            ResolvedConcreteItem::Function(_) => ElementKind::Function,
1940            ResolvedConcreteItem::Type(_) => ElementKind::Type,
1941            ResolvedConcreteItem::Variant(_) => ElementKind::Variant,
1942            ResolvedConcreteItem::Trait(_) | ResolvedConcreteItem::SelfTrait(_) => {
1943                ElementKind::Trait
1944            }
1945            ResolvedConcreteItem::Impl(_) => ElementKind::Impl,
1946            ResolvedConcreteItem::Macro(_) => ElementKind::Macro,
1947        }
1948    }
1949}
1950impl<'db> From<&ResolvedGenericItem<'db>> for ElementKind {
1951    fn from(val: &ResolvedGenericItem<'db>) -> Self {
1952        match val {
1953            ResolvedGenericItem::GenericConstant(_)
1954            | ResolvedGenericItem::TraitItem(TraitItemId::Constant(_)) => ElementKind::Constant,
1955            ResolvedGenericItem::Module(_) => ElementKind::Module,
1956            ResolvedGenericItem::GenericFunction(_)
1957            | ResolvedGenericItem::TraitItem(TraitItemId::Function(_)) => ElementKind::Function,
1958            ResolvedGenericItem::GenericType(_)
1959            | ResolvedGenericItem::GenericTypeAlias(_)
1960            | ResolvedGenericItem::TraitItem(TraitItemId::Type(_)) => ElementKind::Type,
1961            ResolvedGenericItem::Variant(_) => ElementKind::Variant,
1962            ResolvedGenericItem::Trait(_) => ElementKind::Trait,
1963            ResolvedGenericItem::Impl(_)
1964            | ResolvedGenericItem::GenericImplAlias(_)
1965            | ResolvedGenericItem::TraitItem(TraitItemId::Impl(_)) => ElementKind::Impl,
1966            ResolvedGenericItem::Variable(_) => ElementKind::Variable,
1967            ResolvedGenericItem::Macro(_) => ElementKind::Macro,
1968        }
1969    }
1970}
1971impl Display for ElementKind {
1972    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1973        let res = match self {
1974            ElementKind::Constant => "constant",
1975            ElementKind::Variable => "variable",
1976            ElementKind::Module => "module",
1977            ElementKind::Function => "function",
1978            ElementKind::Type => "type",
1979            ElementKind::Variant => "variant",
1980            ElementKind::Trait => "trait",
1981            ElementKind::Impl => "impl",
1982            ElementKind::Macro => "macro",
1983        };
1984        write!(f, "{res}")
1985    }
1986}
1987
1988/// A list of trait functions and the inference errors that occurred while trying to infer them.
1989#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1990pub struct TraitInferenceErrors<'db> {
1991    pub traits_and_errors: Vec<(TraitFunctionId<'db>, InferenceError<'db>)>,
1992}
1993impl<'db> TraitInferenceErrors<'db> {
1994    /// Is the error list empty.
1995    pub fn is_empty(&self) -> bool {
1996        self.traits_and_errors.is_empty()
1997    }
1998    /// Format the list of errors.
1999    fn format(&self, db: &dyn Database) -> String {
2000        self.traits_and_errors
2001            .iter()
2002            .map(|(trait_function_id, inference_error)| {
2003                format!(
2004                    "Candidate `{}` inference failed with: {}",
2005                    trait_function_id.full_path(db),
2006                    inference_error.format(db)
2007                )
2008            })
2009            .join("\n")
2010    }
2011}