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 => Severity::Warning,
1059 SemanticDiagnosticKind::PluginDiagnostic(diag) => diag.severity,
1060 _ => Severity::Error,
1061 }
1062 }
1063
1064 fn notes(&self, _db: &Self::DbType) -> &[DiagnosticNote] {
1065 if let SemanticDiagnosticKind::InnerFailedConstantCalculation(_, notes) = &self.kind {
1066 notes
1067 } else {
1068 &[]
1069 }
1070 }
1071
1072 fn error_code(&self) -> Option<ErrorCode> {
1073 self.kind.error_code()
1074 }
1075
1076 fn is_same_kind(&self, other: &Self) -> bool {
1077 other.kind == self.kind
1078 }
1079}
1080
1081#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1082pub enum SemanticDiagnosticKind {
1083 ModuleFileNotFound(String),
1084 Unsupported,
1085 UnknownLiteral,
1086 UnknownBinaryOperator,
1087 UnknownTrait,
1088 UnknownImpl,
1089 UnexpectedElement {
1090 expected: Vec<ElementKind>,
1091 actual: ElementKind,
1092 },
1093 UnknownType,
1094 UnknownEnum,
1095 LiteralError(LiteralError),
1096 NotAVariant,
1097 NotAStruct,
1098 NotAType,
1099 NotATrait,
1100 NotAnImpl,
1101 ImplItemNotInTrait {
1102 impl_def_id: ImplDefId,
1103 impl_item_name: SmolStr,
1104 trait_id: TraitId,
1105 item_kind: String,
1106 },
1107 ImplicitImplNotInferred {
1108 trait_impl_id: TraitImplId,
1109 concrete_trait_id: ConcreteTraitId,
1110 },
1111 GenericsNotSupportedInItem {
1112 scope: String,
1113 item_kind: String,
1114 },
1115 UnexpectedGenericArgs,
1116 UnknownMember,
1117 CannotCreateInstancesOfPhantomTypes,
1118 NonPhantomTypeContainingPhantomType,
1119 MemberSpecifiedMoreThanOnce,
1120 StructBaseStructExpressionNotLast,
1121 StructBaseStructExpressionNoEffect,
1122 ConstCycle,
1123 UseCycle,
1124 TypeAliasCycle,
1125 ImplAliasCycle,
1126 ImplRequirementCycle,
1127 MissingMember(SmolStr),
1128 WrongNumberOfParameters {
1129 impl_def_id: ImplDefId,
1130 impl_function_id: ImplFunctionId,
1131 trait_id: TraitId,
1132 expected: usize,
1133 actual: usize,
1134 },
1135 WrongNumberOfArguments {
1136 expected: usize,
1137 actual: usize,
1138 },
1139 WrongParameterType {
1140 impl_def_id: ImplDefId,
1141 impl_function_id: ImplFunctionId,
1142 trait_id: TraitId,
1143 expected_ty: semantic::TypeId,
1144 actual_ty: semantic::TypeId,
1145 },
1146 VariantCtorNotImmutable,
1147 TraitParamMutable {
1148 trait_id: TraitId,
1149 function_id: TraitFunctionId,
1150 },
1151 ParameterShouldBeReference {
1152 impl_def_id: ImplDefId,
1153 impl_function_id: ImplFunctionId,
1154 trait_id: TraitId,
1155 },
1156 ParameterShouldNotBeReference {
1157 impl_def_id: ImplDefId,
1158 impl_function_id: ImplFunctionId,
1159 trait_id: TraitId,
1160 },
1161 WrongParameterName {
1162 impl_def_id: ImplDefId,
1163 impl_function_id: ImplFunctionId,
1164 trait_id: TraitId,
1165 expected_name: SmolStr,
1166 },
1167 WrongGenericParamTraitForImplFunction {
1168 impl_def_id: ImplDefId,
1169 impl_function_id: ImplFunctionId,
1170 trait_id: TraitId,
1171 expected_trait: ConcreteTraitId,
1172 actual_trait: ConcreteTraitId,
1173 },
1174 WrongGenericParamKindForImplFunction {
1175 impl_def_id: ImplDefId,
1176 impl_function_id: ImplFunctionId,
1177 trait_id: TraitId,
1178 expected_kind: GenericKind,
1179 actual_kind: GenericKind,
1180 },
1181 WrongType {
1182 expected_ty: semantic::TypeId,
1183 actual_ty: semantic::TypeId,
1184 },
1185 InconsistentBinding,
1186 WrongArgumentType {
1187 expected_ty: semantic::TypeId,
1188 actual_ty: semantic::TypeId,
1189 },
1190 WrongReturnType {
1191 expected_ty: semantic::TypeId,
1192 actual_ty: semantic::TypeId,
1193 },
1194 WrongExprType {
1195 expected_ty: semantic::TypeId,
1196 actual_ty: semantic::TypeId,
1197 },
1198 WrongNumberOfGenericParamsForImplFunction {
1199 expected: usize,
1200 actual: usize,
1201 },
1202 WrongReturnTypeForImpl {
1203 impl_def_id: ImplDefId,
1204 impl_function_id: ImplFunctionId,
1205 trait_id: TraitId,
1206 expected_ty: semantic::TypeId,
1207 actual_ty: semantic::TypeId,
1208 },
1209 AmbiguousTrait {
1210 trait_function_id0: TraitFunctionId,
1211 trait_function_id1: TraitFunctionId,
1212 },
1213 VariableNotFound(SmolStr),
1214 MissingVariableInPattern,
1215 StructMemberRedefinition {
1216 struct_id: StructId,
1217 member_name: SmolStr,
1218 },
1219 EnumVariantRedefinition {
1220 enum_id: EnumId,
1221 variant_name: SmolStr,
1222 },
1223 InfiniteSizeType(semantic::TypeId),
1224 ArrayOfZeroSizedElements(semantic::TypeId),
1225 ParamNameRedefinition {
1226 function_title_id: Option<FunctionTitleId>,
1227 param_name: SmolStr,
1228 },
1229 ConditionNotBool(semantic::TypeId),
1230 IncompatibleArms {
1231 multi_arm_expr_kind: MultiArmExprKind,
1232 pending_ty: semantic::TypeId,
1233 different_ty: semantic::TypeId,
1234 },
1235 LogicalOperatorNotAllowedInIfLet,
1236 LogicalOperatorNotAllowedInWhileLet,
1237 TypeHasNoMembers {
1238 ty: semantic::TypeId,
1239 member_name: SmolStr,
1240 },
1241 CannotCallMethod {
1242 ty: semantic::TypeId,
1243 method_name: SmolStr,
1244 inference_errors: TraitInferenceErrors,
1245 relevant_traits: Vec<String>,
1246 },
1247 NoSuchStructMember {
1248 struct_id: StructId,
1249 member_name: SmolStr,
1250 },
1251 NoSuchTypeMember {
1252 ty: semantic::TypeId,
1253 member_name: SmolStr,
1254 },
1255 MemberNotVisible(SmolStr),
1256 NoSuchVariant {
1257 enum_id: EnumId,
1258 variant_name: SmolStr,
1259 },
1260 ReturnTypeNotErrorPropagateType,
1261 IncompatibleErrorPropagateType {
1262 return_ty: semantic::TypeId,
1263 err_ty: semantic::TypeId,
1264 },
1265 ErrorPropagateOnNonErrorType(semantic::TypeId),
1266 UnhandledMustUseType(semantic::TypeId),
1267 UnstableFeature {
1268 feature_name: SmolStr,
1269 note: Option<SmolStr>,
1270 },
1271 DeprecatedFeature {
1272 feature_name: SmolStr,
1273 note: Option<SmolStr>,
1274 },
1275 InternalFeature {
1276 feature_name: SmolStr,
1277 note: Option<SmolStr>,
1278 },
1279 FeatureMarkerDiagnostic(FeatureMarkerDiagnostic),
1280 UnhandledMustUseFunction,
1281 UnusedVariable,
1282 UnusedConstant,
1283 UnusedUse,
1284 MultipleConstantDefinition(SmolStr),
1285 MultipleDefinitionforBinding(SmolStr),
1286 MultipleGenericItemDefinition(SmolStr),
1287 UnsupportedUseItemInStatement,
1288 ConstGenericParamNotSupported,
1289 NegativeImplsNotEnabled,
1290 NegativeImplsOnlyOnImpls,
1291 RefArgNotAVariable,
1292 RefArgNotMutable,
1293 RefArgNotExplicit,
1294 ImmutableArgWithModifiers,
1295 AssignmentToImmutableVar,
1296 InvalidLhsForAssignment,
1297 InvalidMemberExpression,
1298 InvalidPath,
1299 PathNotFound(NotFoundItemType),
1300 AmbiguousPath(Vec<ModuleItemId>),
1301 UseStarEmptyPath,
1302 GlobalUsesNotSupportedInEdition(Edition),
1303 TraitInTraitMustBeExplicit,
1304 ImplInImplMustBeExplicit,
1305 TraitItemForbiddenInTheTrait,
1306 TraitItemForbiddenInItsImpl,
1307 ImplItemForbiddenInTheImpl,
1308 SuperUsedInRootModule,
1309 ItemNotVisible(ModuleItemId, Vec<ModuleId>),
1310 UnusedImport(UseId),
1311 RedundantModifier {
1312 current_modifier: SmolStr,
1313 previous_modifier: SmolStr,
1314 },
1315 ReferenceLocalVariable,
1316 UnexpectedEnumPattern(semantic::TypeId),
1317 UnexpectedStructPattern(semantic::TypeId),
1318 UnexpectedTuplePattern(semantic::TypeId),
1319 UnexpectedFixedSizeArrayPattern(semantic::TypeId),
1320 WrongNumberOfTupleElements {
1321 expected: usize,
1322 actual: usize,
1323 },
1324 WrongNumberOfFixedSizeArrayElements {
1325 expected: usize,
1326 actual: usize,
1327 },
1328 WrongEnum {
1329 expected_enum: EnumId,
1330 actual_enum: EnumId,
1331 },
1332 InvalidCopyTraitImpl(InferenceError),
1333 InvalidDropTraitImpl(InferenceError),
1334 InvalidImplItem(SmolStr),
1335 MissingItemsInImpl(Vec<SmolStr>),
1336 PassPanicAsNopanic {
1337 impl_function_id: ImplFunctionId,
1338 trait_id: TraitId,
1339 },
1340 PassConstAsNonConst {
1341 impl_function_id: ImplFunctionId,
1342 trait_id: TraitId,
1343 },
1344 PanicableFromNonPanicable,
1345 PanicableExternFunction,
1346 PluginDiagnostic(PluginDiagnostic),
1347 NameDefinedMultipleTimes(SmolStr),
1348 NonPrivateUseStar,
1349 NamedArgumentsAreNotSupported,
1350 ArgPassedToNegativeImpl,
1351 UnnamedArgumentFollowsNamed,
1352 NamedArgumentMismatch {
1353 expected: SmolStr,
1354 found: SmolStr,
1355 },
1356 UnsupportedOutsideOfFunction(UnsupportedOutsideOfFunctionFeatureName),
1357 UnsupportedConstant,
1358 FailedConstantCalculation,
1359 ConstantCalculationDepthExceeded,
1360 InnerFailedConstantCalculation(Box<SemanticDiagnostic>, Vec<DiagnosticNote>),
1361 DivisionByZero,
1362 ExternTypeWithImplGenericsNotSupported,
1363 MissingSemicolon,
1364 TraitMismatch {
1365 expected_trt: semantic::ConcreteTraitId,
1366 actual_trt: semantic::ConcreteTraitId,
1367 },
1368 DesnapNonSnapshot,
1369 InternalInferenceError(InferenceError),
1370 NoImplementationOfIndexOperator {
1371 ty: semantic::TypeId,
1372 inference_errors: TraitInferenceErrors,
1373 },
1374 NoImplementationOfTrait {
1375 ty: semantic::TypeId,
1376 trait_name: SmolStr,
1377 inference_errors: TraitInferenceErrors,
1378 },
1379 CallExpressionRequiresFunction {
1380 ty: semantic::TypeId,
1381 inference_errors: TraitInferenceErrors,
1382 },
1383 MultipleImplementationOfIndexOperator(semantic::TypeId),
1384
1385 UnsupportedInlineArguments,
1386 RedundantInlineAttribute,
1387 InlineAttrForExternFunctionNotAllowed,
1388 InlineAlwaysWithImplGenericArgNotAllowed,
1389 TailExpressionNotAllowedInLoop,
1390 ContinueOnlyAllowedInsideALoop,
1391 BreakOnlyAllowedInsideALoop,
1392 BreakWithValueOnlyAllowedInsideALoop,
1393 ErrorPropagateNotAllowedInsideALoop,
1394 ImplicitPrecedenceAttrForExternFunctionNotAllowed,
1395 RedundantImplicitPrecedenceAttribute,
1396 UnsupportedImplicitPrecedenceArguments,
1397 UnsupportedFeatureAttrArguments,
1398 UnsupportedAllowAttrArguments,
1399 UnsupportedPubArgument,
1400 UnknownStatementAttribute,
1401 InlineMacroNotFound(SmolStr),
1402 InlineMacroFailed(SmolStr),
1403 UnknownGenericParam(SmolStr),
1404 PositionalGenericAfterNamed,
1405 GenericArgDuplicate(SmolStr),
1406 TooManyGenericArguments {
1407 expected: usize,
1408 actual: usize,
1409 },
1410 GenericArgOutOfOrder(SmolStr),
1411 CouponForExternFunctionNotAllowed,
1412 CouponArgumentNoModifiers,
1413 CouponsDisabled,
1415 FixedSizeArrayTypeNonSingleType,
1416 FixedSizeArrayTypeEmptySize,
1417 FixedSizeArrayNonNumericSize,
1418 FixedSizeArrayNonSingleValue,
1419 FixedSizeArraySizeTooBig,
1420 SelfNotSupportedInContext,
1421 SelfMustBeFirst,
1422 DerefCycle {
1423 deref_chain: String,
1424 },
1425 CompilerTraitReImplementation {
1426 trait_id: TraitId,
1427 },
1428 ClosureInGlobalScope,
1429 MaybeMissingColonColon,
1430 CallingShadowedFunction {
1431 shadowed_function_name: SmolStr,
1432 },
1433 RefClosureArgument,
1434 RefClosureParam,
1435 MustBeNextToTypeOrTrait {
1436 trait_id: TraitId,
1437 },
1438 MutableCapturedVariable,
1439 NonTraitTypeConstrained {
1440 identifier: SmolStr,
1441 concrete_trait_id: ConcreteTraitId,
1442 },
1443 DuplicateTypeConstraint {
1444 concrete_trait_type_id: ConcreteTraitTypeId,
1445 },
1446 TypeConstraintsSyntaxNotEnabled,
1447}
1448
1449#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1451pub enum MultiArmExprKind {
1452 If,
1453 Match,
1454 Loop,
1455}
1456
1457impl SemanticDiagnosticKind {
1458 pub fn error_code(&self) -> Option<ErrorCode> {
1459 Some(match &self {
1460 Self::UnusedVariable => error_code!(E0001),
1461 Self::CannotCallMethod { .. } => {
1462 error_code!(E0002)
1463 }
1464 Self::MissingMember(_) => error_code!(E0003),
1465 Self::MissingItemsInImpl(_) => error_code!(E0004),
1466 Self::ModuleFileNotFound(_) => error_code!(E0005),
1467 Self::PathNotFound(_) => error_code!(E0006),
1468 _ => return None,
1469 })
1470 }
1471}
1472
1473#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1474pub enum NotFoundItemType {
1475 Identifier,
1476 Function,
1477 Type,
1478 Trait,
1479 Impl,
1480}
1481
1482#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1483pub enum UnsupportedOutsideOfFunctionFeatureName {
1484 ReturnStatement,
1485 ErrorPropagate,
1486}
1487
1488#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1489pub enum ElementKind {
1490 Constant,
1491 Variable,
1492 Module,
1493 Function,
1494 Type,
1495 Variant,
1496 Trait,
1497 Impl,
1498}
1499impl From<&ResolvedConcreteItem> for ElementKind {
1500 fn from(val: &ResolvedConcreteItem) -> Self {
1501 match val {
1502 ResolvedConcreteItem::Constant(_) => ElementKind::Constant,
1503 ResolvedConcreteItem::Module(_) => ElementKind::Module,
1504 ResolvedConcreteItem::Function(_) => ElementKind::Function,
1505 ResolvedConcreteItem::Type(_) => ElementKind::Type,
1506 ResolvedConcreteItem::Variant(_) => ElementKind::Variant,
1507 ResolvedConcreteItem::Trait(_) | ResolvedConcreteItem::SelfTrait(_) => {
1508 ElementKind::Trait
1509 }
1510 ResolvedConcreteItem::Impl(_) => ElementKind::Impl,
1511 }
1512 }
1513}
1514impl From<&ResolvedGenericItem> for ElementKind {
1515 fn from(val: &ResolvedGenericItem) -> Self {
1516 match val {
1517 ResolvedGenericItem::GenericConstant(_) => ElementKind::Constant,
1518 ResolvedGenericItem::Module(_) => ElementKind::Module,
1519 ResolvedGenericItem::GenericFunction(_) => ElementKind::Function,
1520 ResolvedGenericItem::GenericType(_) | ResolvedGenericItem::GenericTypeAlias(_) => {
1521 ElementKind::Type
1522 }
1523 ResolvedGenericItem::Variant(_) => ElementKind::Variant,
1524 ResolvedGenericItem::Trait(_) => ElementKind::Trait,
1525 ResolvedGenericItem::Impl(_) | ResolvedGenericItem::GenericImplAlias(_) => {
1526 ElementKind::Impl
1527 }
1528 ResolvedGenericItem::Variable(_) => ElementKind::Variable,
1529 }
1530 }
1531}
1532impl Display for ElementKind {
1533 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1534 let res = match self {
1535 ElementKind::Constant => "constant",
1536 ElementKind::Variable => "variable",
1537 ElementKind::Module => "module",
1538 ElementKind::Function => "function",
1539 ElementKind::Type => "type",
1540 ElementKind::Variant => "variant",
1541 ElementKind::Trait => "trait",
1542 ElementKind::Impl => "impl",
1543 };
1544 write!(f, "{res}")
1545 }
1546}
1547
1548#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1550pub struct TraitInferenceErrors {
1551 pub traits_and_errors: Vec<(TraitFunctionId, InferenceError)>,
1552}
1553impl TraitInferenceErrors {
1554 pub fn is_empty(&self) -> bool {
1556 self.traits_and_errors.is_empty()
1557 }
1558 fn format(&self, db: &(dyn SemanticGroup + 'static)) -> String {
1560 self.traits_and_errors
1561 .iter()
1562 .map(|(trait_function_id, inference_error)| {
1563 format!(
1564 "Candidate `{}` inference failed with: {}",
1565 trait_function_id.full_path(db.upcast()),
1566 inference_error.format(db)
1567 )
1568 })
1569 .join("\n")
1570 }
1571}