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