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, 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, DiagnosticsBuilder, ErrorCode, Severity,
13 error_code,
14};
15use cairo_lang_filesystem::db::Edition;
16use cairo_lang_syntax 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 SemanticDiagnosticKind::AmbiguousTrait { trait_function_id0, trait_function_id1 } => {
341 format!(
342 "Ambiguous method call. More than one applicable trait function with a \
343 suitable self type was found: {} and {}. Consider adding type annotations or \
344 explicitly refer to the impl function.",
345 trait_function_id0.full_path(db.upcast()),
346 trait_function_id1.full_path(db.upcast())
347 )
348 }
349 SemanticDiagnosticKind::VariableNotFound(name) => {
350 format!(r#"Variable "{name}" not found."#)
351 }
352 SemanticDiagnosticKind::MissingVariableInPattern => {
353 "Missing variable in pattern.".into()
354 }
355 SemanticDiagnosticKind::StructMemberRedefinition { struct_id, member_name } => {
356 format!(
357 r#"Redefinition of member "{member_name}" on struct "{}"."#,
358 struct_id.full_path(db.upcast())
359 )
360 }
361 SemanticDiagnosticKind::EnumVariantRedefinition { enum_id, variant_name } => {
362 format!(
363 r#"Redefinition of variant "{variant_name}" on enum "{}"."#,
364 enum_id.full_path(db.upcast())
365 )
366 }
367 SemanticDiagnosticKind::InfiniteSizeType(ty) => {
368 format!(r#"Recursive type "{}" has infinite size."#, ty.format(db))
369 }
370 SemanticDiagnosticKind::ArrayOfZeroSizedElements(ty) => {
371 format!(r#"Cannot have array of type "{}" that is zero sized."#, ty.format(db))
372 }
373 SemanticDiagnosticKind::ParamNameRedefinition { function_title_id, param_name } => {
374 format!(
375 r#"Redefinition of parameter name "{param_name}"{}"#,
376 function_title_id
377 .map(|function_title_id| format!(
378 r#" in function "{}"."#,
379 function_title_id.full_path(db.upcast())
380 ))
381 .unwrap_or(".".into()),
382 )
383 }
384 SemanticDiagnosticKind::ConditionNotBool(condition_ty) => {
385 format!(r#"Condition has type "{}", expected bool."#, condition_ty.format(db))
386 }
387 SemanticDiagnosticKind::IncompatibleArms {
388 multi_arm_expr_kind: incompatibility_kind,
389 pending_ty: first_ty,
390 different_ty,
391 } => {
392 let prefix = match incompatibility_kind {
393 MultiArmExprKind::Match => "Match arms have incompatible types",
394 MultiArmExprKind::If => "If blocks have incompatible types",
395 MultiArmExprKind::Loop => "Loop has incompatible return types",
396 };
397 format!(r#"{prefix}: "{}" and "{}""#, first_ty.format(db), different_ty.format(db))
398 }
399 SemanticDiagnosticKind::LogicalOperatorNotAllowedInIfLet => {
400 "Logical operator not allowed in if-let.".into()
401 }
402 SemanticDiagnosticKind::LogicalOperatorNotAllowedInWhileLet => {
403 "Logical operator not allowed in while-let.".into()
404 }
405 SemanticDiagnosticKind::TypeHasNoMembers { ty, member_name: _ } => {
406 format!(r#"Type "{}" has no members."#, ty.format(db))
407 }
408 SemanticDiagnosticKind::NoSuchStructMember { struct_id, member_name } => {
409 format!(
410 r#"Struct "{}" has no member "{member_name}""#,
411 struct_id.full_path(db.upcast())
412 )
413 }
414 SemanticDiagnosticKind::NoSuchTypeMember { ty, member_name } => {
415 format!(r#"Type "{}" has no member "{member_name}""#, ty.format(db))
416 }
417 SemanticDiagnosticKind::MemberNotVisible(member_name) => {
418 format!(r#"Member "{member_name}" is not visible in this context."#)
419 }
420 SemanticDiagnosticKind::NoSuchVariant { enum_id, variant_name } => {
421 format!(
422 r#"Enum "{}" has no variant "{variant_name}""#,
423 enum_id.full_path(db.upcast())
424 )
425 }
426 SemanticDiagnosticKind::ReturnTypeNotErrorPropagateType => {
427 "`?` can only be used in a function with `Option` or `Result` return type.".into()
428 }
429 SemanticDiagnosticKind::IncompatibleErrorPropagateType { return_ty, err_ty } => {
430 format!(
431 r#"Return type "{}" does not wrap error "{}""#,
432 return_ty.format(db),
433 err_ty.format(db)
434 )
435 }
436 SemanticDiagnosticKind::ErrorPropagateOnNonErrorType(ty) => {
437 format!(r#"Type "{}" can not error propagate"#, ty.format(db))
438 }
439 SemanticDiagnosticKind::UnhandledMustUseType(ty) => {
440 format!(r#"Unhandled `#[must_use]` type `{}`"#, ty.format(db))
441 }
442 SemanticDiagnosticKind::UnhandledMustUseFunction => {
443 "Unhandled `#[must_use]` function.".into()
444 }
445 SemanticDiagnosticKind::UnstableFeature { feature_name, note } => {
446 format!(
447 "Usage of unstable feature `{feature_name}` with no \
448 `#[feature({feature_name})]` attribute.{}",
449 note.as_ref().map(|note| format!(" Note: {}", note)).unwrap_or_default()
450 )
451 }
452 SemanticDiagnosticKind::DeprecatedFeature { feature_name, note } => {
453 format!(
454 "Usage of deprecated feature `{feature_name}` with no \
455 `#[feature({feature_name})]` attribute.{}",
456 note.as_ref().map(|note| format!(" Note: {}", note)).unwrap_or_default()
457 )
458 }
459 SemanticDiagnosticKind::InternalFeature { feature_name, note } => {
460 format!(
461 "Usage of internal feature `{feature_name}` with no \
462 `#[feature({feature_name})]` attribute.{}",
463 note.as_ref().map(|note| format!(" Note: {}", note)).unwrap_or_default()
464 )
465 }
466 SemanticDiagnosticKind::FeatureMarkerDiagnostic(diagnostic) => match diagnostic {
467 FeatureMarkerDiagnostic::MultipleMarkers => {
468 "Multiple feature marker attributes.".into()
469 }
470 FeatureMarkerDiagnostic::MissingAllowFeature => {
471 "Missing `feature` arg for feature marker attribute.".into()
472 }
473 FeatureMarkerDiagnostic::UnsupportedArgument => {
474 "Unsupported argument for feature marker attribute.".into()
475 }
476 FeatureMarkerDiagnostic::DuplicatedArgument => {
477 "Duplicated argument for feature marker attribute.".into()
478 }
479 },
480 SemanticDiagnosticKind::UnusedVariable => {
481 "Unused variable. Consider ignoring by prefixing with `_`.".into()
482 }
483 SemanticDiagnosticKind::UnusedConstant => {
484 "Unused constant. Consider ignoring by prefixing with `_`.".into()
485 }
486 SemanticDiagnosticKind::MultipleConstantDefinition(constant_name) => {
487 format!(r#"Multiple definitions of constant "{}"."#, constant_name)
488 }
489 SemanticDiagnosticKind::UnusedUse => "Unused use.".into(),
490 SemanticDiagnosticKind::MultipleDefinitionforBinding(identifier_name) => {
491 format!(
492 r#"Multiple definitions of identifier '{}' as constant and variable."#,
493 identifier_name
494 )
495 }
496 SemanticDiagnosticKind::MultipleGenericItemDefinition(type_name) => {
497 format!(r#"Multiple definitions of an item "{}"."#, type_name)
498 }
499 SemanticDiagnosticKind::UnsupportedUseItemInStatement => {
500 "Unsupported use item in statement.".into()
501 }
502 SemanticDiagnosticKind::InvalidMemberExpression => "Invalid member expression.".into(),
503 SemanticDiagnosticKind::InvalidPath => "Invalid path.".into(),
504 SemanticDiagnosticKind::RefArgNotAVariable => "ref argument must be a variable.".into(),
505 SemanticDiagnosticKind::RefArgNotMutable => {
506 "ref argument must be a mutable variable.".into()
507 }
508 SemanticDiagnosticKind::RefArgNotExplicit => {
509 "ref argument must be passed with a preceding 'ref'.".into()
510 }
511 SemanticDiagnosticKind::ImmutableArgWithModifiers => {
512 "Argument to immutable parameter cannot have modifiers.".into()
513 }
514 SemanticDiagnosticKind::AssignmentToImmutableVar => {
515 "Cannot assign to an immutable variable.".into()
516 }
517 SemanticDiagnosticKind::InvalidLhsForAssignment => {
518 "Invalid left-hand side of assignment.".into()
519 }
520 SemanticDiagnosticKind::PathNotFound(item_type) => match item_type {
521 NotFoundItemType::Identifier => "Identifier not found.".into(),
522 NotFoundItemType::Function => "Function not found.".into(),
523 NotFoundItemType::Type => "Type not found.".into(),
524 NotFoundItemType::Trait => "Trait not found.".into(),
525 NotFoundItemType::Impl => "Impl not found.".into(),
526 },
527 SemanticDiagnosticKind::AmbiguousPath(module_items) => {
528 format!(
529 "Ambiguous path. Multiple matching items: {}",
530 module_items
531 .iter()
532 .map(|item| format!("`{}`", item.full_path(db.upcast())))
533 .join(", ")
534 )
535 }
536 SemanticDiagnosticKind::UseStarEmptyPath => {
537 "`*` in `use` items is not allowed for empty path.".into()
538 }
539 SemanticDiagnosticKind::GlobalUsesNotSupportedInEdition(edition) => {
540 format!("Global `use` item is not supported in `{edition:?}` edition.")
541 }
542 SemanticDiagnosticKind::TraitInTraitMustBeExplicit => {
543 "In a trait, paths of the same trait must be fully explicit. Either use `Self` if \
544 this is the intention, or explicitly specify all the generic arguments."
545 .to_string()
546 }
547 SemanticDiagnosticKind::ImplInImplMustBeExplicit => {
548 "In an impl, paths of the same impl must be fully explicit. Either use `Self` if \
549 this is the intention, or explicitly specify all the generic arguments."
550 .to_string()
551 }
552 SemanticDiagnosticKind::TraitItemForbiddenInTheTrait => {
553 "In a trait, paths of the same trait are not allowed. Did you mean to use `Self::`?"
554 .to_string()
555 }
556 SemanticDiagnosticKind::TraitItemForbiddenInItsImpl => "In an impl, paths of the \
557 impl's trait are not allowed. \
558 Did you mean to use `Self::`?"
559 .to_string(),
560 SemanticDiagnosticKind::ImplItemForbiddenInTheImpl => {
561 "In an impl, paths of the same impl are not allowed. Did you mean to use `Self::`?"
562 .to_string()
563 }
564 SemanticDiagnosticKind::SuperUsedInRootModule => {
565 "'super' cannot be used for the crate's root module.".into()
566 }
567 SemanticDiagnosticKind::ItemNotVisible(item_id, containing_modules) => {
568 format!(
569 "Item `{}` is not visible in this context{}.",
570 item_id.full_path(db.upcast()),
571 if containing_modules.is_empty() {
572 "".to_string()
573 } else if let [module_id] = &containing_modules[..] {
574 format!(" through module `{}`", module_id.full_path(db.upcast()))
575 } else {
576 format!(
577 " through any of the modules: {}",
578 containing_modules
579 .iter()
580 .map(|module_id| format!("`{}`", module_id.full_path(db.upcast())))
581 .join(", ")
582 )
583 }
584 )
585 }
586 SemanticDiagnosticKind::UnusedImport(use_id) => {
587 format!("Unused import: `{}`", use_id.full_path(db.upcast()))
588 }
589 SemanticDiagnosticKind::UnexpectedEnumPattern(ty) => {
590 format!(r#"Unexpected type for enum pattern. "{}" is not an enum."#, ty.format(db),)
591 }
592 SemanticDiagnosticKind::UnexpectedStructPattern(ty) => {
593 format!(
594 r#"Unexpected type for struct pattern. "{}" is not a struct."#,
595 ty.format(db),
596 )
597 }
598 SemanticDiagnosticKind::UnexpectedTuplePattern(ty) => {
599 format!(r#"Unexpected type for tuple pattern. "{}" is not a tuple."#, ty.format(db),)
600 }
601 SemanticDiagnosticKind::UnexpectedFixedSizeArrayPattern(ty) => {
602 format!(
603 "Unexpected type for fixed size array pattern. \"{}\" is not a fixed size \
604 array.",
605 ty.format(db),
606 )
607 }
608 SemanticDiagnosticKind::WrongNumberOfTupleElements { expected, actual } => format!(
609 r#"Wrong number of tuple elements in pattern. Expected: {}. Got: {}."#,
610 expected, actual
611 ),
612 SemanticDiagnosticKind::WrongNumberOfFixedSizeArrayElements { expected, actual } => {
613 format!(
614 "Wrong number of fixed size array elements in pattern. Expected: {}. Got: {}.",
615 expected, actual
616 )
617 }
618 SemanticDiagnosticKind::WrongEnum { expected_enum, actual_enum } => {
619 format!(
620 r#"Wrong enum in pattern. Expected: "{}". Got: "{}"."#,
621 expected_enum.full_path(db.upcast()),
622 actual_enum.full_path(db.upcast())
623 )
624 }
625 SemanticDiagnosticKind::RedundantModifier { current_modifier, previous_modifier } => {
626 format!(
627 "`{current_modifier}` modifier was specified after another modifier \
628 (`{previous_modifier}`). Only a single modifier is allowed."
629 )
630 }
631 SemanticDiagnosticKind::ReferenceLocalVariable => {
632 "`ref` is only allowed for function parameters, not for local variables."
633 .to_string()
634 }
635 SemanticDiagnosticKind::InvalidCopyTraitImpl(inference_error) => {
636 format!("Invalid copy trait implementation, {}", inference_error.format(db))
637 }
638 SemanticDiagnosticKind::InvalidDropTraitImpl(inference_error) => {
639 format!("Invalid drop trait implementation, {}", inference_error.format(db))
640 }
641 SemanticDiagnosticKind::InvalidImplItem(item_kw) => {
642 format!("`{item_kw}` is not allowed inside impl.")
643 }
644 SemanticDiagnosticKind::MissingItemsInImpl(item_names) => {
645 format!(
646 "Not all trait items are implemented. Missing: {}.",
647 item_names.iter().map(|name| format!("'{name}'")).join(", ")
648 )
649 }
650 SemanticDiagnosticKind::PassPanicAsNopanic { impl_function_id, trait_id } => {
651 let name = impl_function_id.name(db.upcast());
652 let trait_name = trait_id.name(db.upcast());
653 format!(
654 "The signature of function `{name}` is incompatible with trait \
655 `{trait_name}`. The trait function is declared as nopanic."
656 )
657 }
658 SemanticDiagnosticKind::PanicableFromNonPanicable => {
659 "Function is declared as nopanic but calls a function that may panic.".into()
660 }
661 SemanticDiagnosticKind::PanicableExternFunction => {
662 "An extern function must be marked as nopanic.".into()
663 }
664 SemanticDiagnosticKind::PluginDiagnostic(diagnostic) => {
665 format!("Plugin diagnostic: {}", diagnostic.message)
666 }
667 SemanticDiagnosticKind::NameDefinedMultipleTimes(name) => {
668 format!("The name `{name}` is defined multiple times.")
669 }
670 SemanticDiagnosticKind::NonPrivateUseStar => {
671 "`pub` not supported for global `use`.".into()
672 }
673 SemanticDiagnosticKind::NamedArgumentsAreNotSupported => {
674 "Named arguments are not supported in this context.".into()
675 }
676 SemanticDiagnosticKind::UnnamedArgumentFollowsNamed => {
677 "Unnamed arguments cannot follow named arguments.".into()
678 }
679 SemanticDiagnosticKind::NamedArgumentMismatch { expected, found } => {
680 format!("Unexpected argument name. Expected: '{expected}', found '{found}'.")
681 }
682 SemanticDiagnosticKind::UnsupportedOutsideOfFunction(feature_name) => {
683 let feature_name_str = match feature_name {
684 UnsupportedOutsideOfFunctionFeatureName::ReturnStatement => "Return statement",
685 UnsupportedOutsideOfFunctionFeatureName::ErrorPropagate => "The '?' operator",
686 };
687 format!("{feature_name_str} is not supported outside of functions.")
688 }
689 SemanticDiagnosticKind::UnsupportedConstant => {
690 "This expression is not supported as constant.".into()
691 }
692 SemanticDiagnosticKind::DivisionByZero => "Division by zero.".into(),
693 SemanticDiagnosticKind::ExternTypeWithImplGenericsNotSupported => {
694 "Extern types with impl generics are not supported.".into()
695 }
696 SemanticDiagnosticKind::MissingSemicolon => "Missing semicolon".into(),
697 SemanticDiagnosticKind::TraitMismatch { expected_trt, actual_trt } => {
698 format!(
699 "Expected an impl of `{:?}`. Got an impl of `{:?}`.",
700 expected_trt.debug(db),
701 actual_trt.debug(db),
702 )
703 }
704 SemanticDiagnosticKind::InternalInferenceError(err) => err.format(db),
705 SemanticDiagnosticKind::DesnapNonSnapshot => {
706 "Desnap operator can only be applied on snapshots".into()
707 }
708 SemanticDiagnosticKind::NoImplementationOfIndexOperator { ty, inference_errors } => {
709 if inference_errors.is_empty() {
710 format!(
711 "Type `{}` does not implement the `Index` trait nor the `IndexView` trait.",
712 ty.format(db)
713 )
714 } else {
715 format!(
716 "Type `{}` could not be indexed.\n{}",
717 ty.format(db),
718 inference_errors.format(db)
719 )
720 }
721 }
722 SemanticDiagnosticKind::MultipleImplementationOfIndexOperator(ty) => {
723 format!(
724 r#"Type "{}" implements both the "Index" trait and the "IndexView" trait."#,
725 ty.format(db)
726 )
727 }
728
729 SemanticDiagnosticKind::UnsupportedInlineArguments => {
730 "Unsupported `inline` arguments.".into()
731 }
732 SemanticDiagnosticKind::RedundantInlineAttribute => {
733 "Redundant `inline` attribute.".into()
734 }
735 SemanticDiagnosticKind::InlineAttrForExternFunctionNotAllowed => {
736 "`inline` attribute is not allowed for extern functions.".into()
737 }
738 SemanticDiagnosticKind::InlineAlwaysWithImplGenericArgNotAllowed => {
739 "`#[inline(always)]` is not allowed for functions with impl generic parameters."
740 .into()
741 }
742 SemanticDiagnosticKind::CannotCallMethod { ty, method_name, inference_errors } => {
743 if inference_errors.is_empty() {
744 format!(
745 "Method `{}` not found on type `{}`. Did you import the correct trait and \
746 impl?",
747 method_name,
748 ty.format(db)
749 )
750 } else {
751 format!(
752 "Method `{}` could not be called on type `{}`.\n{}",
753 method_name,
754 ty.format(db),
755 inference_errors.format(db)
756 )
757 }
758 }
759 SemanticDiagnosticKind::TailExpressionNotAllowedInLoop => {
760 "Tail expression not allowed in a `loop` block.".into()
761 }
762 SemanticDiagnosticKind::ContinueOnlyAllowedInsideALoop => {
763 "`continue` only allowed inside a `loop`.".into()
764 }
765 SemanticDiagnosticKind::BreakOnlyAllowedInsideALoop => {
766 "`break` only allowed inside a `loop`.".into()
767 }
768 SemanticDiagnosticKind::BreakWithValueOnlyAllowedInsideALoop => {
769 "Can only break with a value inside a `loop`.".into()
770 }
771 SemanticDiagnosticKind::ReturnNotAllowedInsideALoop => {
772 "`return` not allowed inside a `loop`.".into()
773 }
774 SemanticDiagnosticKind::ErrorPropagateNotAllowedInsideALoop => {
775 "`?` not allowed inside a `loop`.".into()
776 }
777 SemanticDiagnosticKind::ConstGenericParamNotSupported => {
778 "Const generic args are not allowed in this context.".into()
779 }
780 SemanticDiagnosticKind::NegativeImplsNotEnabled => {
781 "Negative impls are not enabled in the current crate.".into()
782 }
783 SemanticDiagnosticKind::NegativeImplsOnlyOnImpls => {
784 "Negative impls supported only in impl definitions.".into()
785 }
786 SemanticDiagnosticKind::ImplicitPrecedenceAttrForExternFunctionNotAllowed => {
787 "`implicit_precedence` attribute is not allowed for extern functions.".into()
788 }
789 SemanticDiagnosticKind::RedundantImplicitPrecedenceAttribute => {
790 "Redundant `implicit_precedence` attribute.".into()
791 }
792 SemanticDiagnosticKind::UnsupportedImplicitPrecedenceArguments => {
793 "Unsupported `implicit_precedence` arguments.".into()
794 }
795 SemanticDiagnosticKind::UnsupportedFeatureAttrArguments => {
796 "`feature` attribute argument should be a single string.".into()
797 }
798 SemanticDiagnosticKind::UnsupportedAllowAttrArguments => {
799 "`allow` attribute argument not supported.".into()
801 }
802 SemanticDiagnosticKind::UnsupportedPubArgument => "Unsupported `pub` argument.".into(),
803 SemanticDiagnosticKind::UnknownStatementAttribute => {
804 "Unknown statement attribute.".into()
805 }
806 SemanticDiagnosticKind::InlineMacroNotFound(macro_name) => {
807 format!("Inline macro `{}` not found.", macro_name)
808 }
809 SemanticDiagnosticKind::InlineMacroFailed(macro_name) => {
810 format!("Inline macro `{}` failed.", macro_name)
811 }
812 SemanticDiagnosticKind::UnknownGenericParam(name) => {
813 format!("Unknown generic parameter `{}`.", name)
814 }
815 SemanticDiagnosticKind::PositionalGenericAfterNamed => {
816 "Positional generic parameters must come before named generic parameters.".into()
817 }
818 SemanticDiagnosticKind::GenericArgDuplicate(name) => {
819 format!("Generic argument `{}` is specified more than once.", name)
820 }
821 SemanticDiagnosticKind::TooManyGenericArguments { expected, actual } => {
822 format!("Expected {} generic arguments, found {}.", expected, actual)
823 }
824 SemanticDiagnosticKind::GenericArgOutOfOrder(name) => {
825 format!("Generic argument `{}` is out of order.", name)
826 }
827 SemanticDiagnosticKind::ArgPassedToNegativeImpl => {
828 "Only `_` is valid as a negative impl argument.".into()
829 }
830 SemanticDiagnosticKind::CouponForExternFunctionNotAllowed => {
831 "Coupon cannot be used with extern functions.".into()
832 }
833 SemanticDiagnosticKind::CouponArgumentNoModifiers => {
834 "The __coupon__ argument cannot have modifiers.".into()
835 }
836 SemanticDiagnosticKind::CouponsDisabled => {
837 "Coupons are disabled in the current crate.\nYou can enable them by enabling the \
838 coupons experimental feature in the crate config."
839 .into()
840 }
841 SemanticDiagnosticKind::StructBaseStructExpressionNotLast => {
842 "The base struct must always be the last argument.".into()
843 }
844 SemanticDiagnosticKind::StructBaseStructExpressionNoEffect => {
845 "Base struct has no effect, all the fields in the struct have already been \
846 specified."
847 .into()
848 }
849 SemanticDiagnosticKind::FixedSizeArrayTypeNonSingleType => {
850 "Fixed size array type must have exactly one type.".into()
851 }
852 SemanticDiagnosticKind::FixedSizeArrayTypeEmptySize => {
853 "Fixed size array type must have a size clause.".into()
854 }
855 SemanticDiagnosticKind::FixedSizeArrayNonNumericSize => {
856 "Fixed size array type must have a positive integer size.".into()
857 }
858 SemanticDiagnosticKind::FixedSizeArrayNonSingleValue => {
859 "Fixed size array with defined size must have exactly one value.".into()
860 }
861 SemanticDiagnosticKind::FixedSizeArraySizeTooBig => {
862 "Fixed size array size must be smaller than 2^15.".into()
863 }
864 SemanticDiagnosticKind::SelfNotSupportedInContext => {
865 "`Self` is not supported in this context.".into()
866 }
867 SemanticDiagnosticKind::SelfMustBeFirst => {
868 "`Self` can only be the first segment of a path.".into()
869 }
870 SemanticDiagnosticKind::CannotCreateInstancesOfPhantomTypes => {
871 "Can not create instances of phantom types.".into()
872 }
873 SemanticDiagnosticKind::NonPhantomTypeContainingPhantomType => {
874 "Non-phantom type containing phantom type.".into()
875 }
876 SemanticDiagnosticKind::DerefCycle { deref_chain } => {
877 format!("Deref impls cycle detected:\n{}", deref_chain)
878 }
879 SemanticDiagnosticKind::NoImplementationOfTrait {
880 ty,
881 trait_name,
882 inference_errors,
883 } => {
884 if inference_errors.is_empty() {
885 format!(
886 "Implementation of trait `{}` not found on type `{}`. Did you import the \
887 correct trait and impl?",
888 trait_name,
889 ty.format(db)
890 )
891 } else {
892 format!(
893 "Could not find implementation of trait `{}` on type `{}`.\n{}",
894 trait_name,
895 ty.format(db),
896 inference_errors.format(db)
897 )
898 }
899 }
900 SemanticDiagnosticKind::CallExpressionRequiresFunction { ty, inference_errors } => {
901 if inference_errors.is_empty() {
902 format!("Call expression requires a function, found `{}`.", ty.format(db))
903 } else {
904 format!(
905 "Call expression requires a function, found `{}`.\n{}",
906 ty.format(db),
907 inference_errors.format(db)
908 )
909 }
910 }
911 SemanticDiagnosticKind::CompilerTraitReImplementation { trait_id } => {
912 format!("Trait `{}` should not be re-implemented.", trait_id.full_path(db.upcast()))
913 }
914 SemanticDiagnosticKind::ClosureInGlobalScope => {
915 "Closures are not allowed in this context.".into()
916 }
917 SemanticDiagnosticKind::MaybeMissingColonColon => "Are you missing a `::`?.".into(),
918 SemanticDiagnosticKind::CallingShadowedFunction { shadowed_function_name } => {
919 format!("Function `{}` is shadowed by a local variable.", shadowed_function_name)
920 }
921 SemanticDiagnosticKind::RefClosureArgument => {
922 "Arguments to closure functions cannot be references".into()
923 }
924 SemanticDiagnosticKind::MutableCapturedVariable => {
925 "Capture of mutable variables in a closure is not supported".into()
926 }
927 SemanticDiagnosticKind::NonTraitTypeConstrained { identifier, concrete_trait_id } => {
928 format!(
929 "associated type `{}` not found for `{}`",
930 identifier,
931 concrete_trait_id.full_path(db)
932 )
933 }
934 SemanticDiagnosticKind::DuplicateTypeConstraint {
935 concrete_trait_type_id: trait_type_id,
936 } => {
937 format!(
938 "the value of the associated type `{}` in trait `{}` is already specified",
939 trait_type_id.trait_type(db).name(db.upcast()),
940 trait_type_id.concrete_trait(db).full_path(db)
941 )
942 }
943 SemanticDiagnosticKind::TypeConstraintsSyntaxNotEnabled => {
944 "Type constraints syntax is not enabled in the current crate.".into()
945 }
946 }
947 }
948
949 fn location(&self, db: &Self::DbType) -> DiagnosticLocation {
950 let mut location = self.stable_location.diagnostic_location(db.upcast());
951 if self.after {
952 location = location.after();
953 }
954 location
955 }
956
957 fn severity(&self) -> Severity {
958 match &self.kind {
959 SemanticDiagnosticKind::UnusedVariable
960 | SemanticDiagnosticKind::UnhandledMustUseType { .. }
961 | SemanticDiagnosticKind::UnhandledMustUseFunction
962 | SemanticDiagnosticKind::TraitInTraitMustBeExplicit
963 | SemanticDiagnosticKind::ImplInImplMustBeExplicit
964 | SemanticDiagnosticKind::TraitItemForbiddenInTheTrait
965 | SemanticDiagnosticKind::TraitItemForbiddenInItsImpl
966 | SemanticDiagnosticKind::ImplItemForbiddenInTheImpl
967 | SemanticDiagnosticKind::UnstableFeature { .. }
968 | SemanticDiagnosticKind::DeprecatedFeature { .. }
969 | SemanticDiagnosticKind::UnusedImport { .. }
970 | SemanticDiagnosticKind::CallingShadowedFunction { .. }
971 | SemanticDiagnosticKind::UnusedConstant
972 | SemanticDiagnosticKind::UnusedUse => Severity::Warning,
973 SemanticDiagnosticKind::PluginDiagnostic(diag) => diag.severity,
974 _ => Severity::Error,
975 }
976 }
977
978 fn error_code(&self) -> Option<ErrorCode> {
979 self.kind.error_code()
980 }
981
982 fn is_same_kind(&self, other: &Self) -> bool {
983 other.kind == self.kind
984 }
985}
986
987#[derive(Clone, Debug, Eq, Hash, PartialEq)]
988pub enum SemanticDiagnosticKind {
989 ModuleFileNotFound(String),
990 Unsupported,
991 UnknownLiteral,
992 UnknownBinaryOperator,
993 UnknownTrait,
994 UnknownImpl,
995 UnexpectedElement {
996 expected: Vec<ElementKind>,
997 actual: ElementKind,
998 },
999 UnknownType,
1000 UnknownEnum,
1001 LiteralError(LiteralError),
1002 NotAVariant,
1003 NotAStruct,
1004 NotAType,
1005 NotATrait,
1006 NotAnImpl,
1007 ImplItemNotInTrait {
1008 impl_def_id: ImplDefId,
1009 impl_item_name: SmolStr,
1010 trait_id: TraitId,
1011 item_kind: String,
1012 },
1013 ImplicitImplNotInferred {
1014 trait_impl_id: TraitImplId,
1015 concrete_trait_id: ConcreteTraitId,
1016 },
1017 GenericsNotSupportedInItem {
1018 scope: String,
1019 item_kind: String,
1020 },
1021 UnexpectedGenericArgs,
1022 UnknownMember,
1023 CannotCreateInstancesOfPhantomTypes,
1024 NonPhantomTypeContainingPhantomType,
1025 MemberSpecifiedMoreThanOnce,
1026 StructBaseStructExpressionNotLast,
1027 StructBaseStructExpressionNoEffect,
1028 ConstCycle,
1029 UseCycle,
1030 TypeAliasCycle,
1031 ImplAliasCycle,
1032 ImplRequirementCycle,
1033 MissingMember(SmolStr),
1034 WrongNumberOfParameters {
1035 impl_def_id: ImplDefId,
1036 impl_function_id: ImplFunctionId,
1037 trait_id: TraitId,
1038 expected: usize,
1039 actual: usize,
1040 },
1041 WrongNumberOfArguments {
1042 expected: usize,
1043 actual: usize,
1044 },
1045 WrongParameterType {
1046 impl_def_id: ImplDefId,
1047 impl_function_id: ImplFunctionId,
1048 trait_id: TraitId,
1049 expected_ty: semantic::TypeId,
1050 actual_ty: semantic::TypeId,
1051 },
1052 VariantCtorNotImmutable,
1053 TraitParamMutable {
1054 trait_id: TraitId,
1055 function_id: TraitFunctionId,
1056 },
1057 ParameterShouldBeReference {
1058 impl_def_id: ImplDefId,
1059 impl_function_id: ImplFunctionId,
1060 trait_id: TraitId,
1061 },
1062 ParameterShouldNotBeReference {
1063 impl_def_id: ImplDefId,
1064 impl_function_id: ImplFunctionId,
1065 trait_id: TraitId,
1066 },
1067 WrongParameterName {
1068 impl_def_id: ImplDefId,
1069 impl_function_id: ImplFunctionId,
1070 trait_id: TraitId,
1071 expected_name: SmolStr,
1072 },
1073 WrongType {
1074 expected_ty: semantic::TypeId,
1075 actual_ty: semantic::TypeId,
1076 },
1077 InconsistentBinding,
1078 WrongArgumentType {
1079 expected_ty: semantic::TypeId,
1080 actual_ty: semantic::TypeId,
1081 },
1082 WrongReturnType {
1083 expected_ty: semantic::TypeId,
1084 actual_ty: semantic::TypeId,
1085 },
1086 WrongExprType {
1087 expected_ty: semantic::TypeId,
1088 actual_ty: semantic::TypeId,
1089 },
1090 WrongNumberOfGenericParamsForImplFunction {
1091 expected: usize,
1092 actual: usize,
1093 },
1094 WrongReturnTypeForImpl {
1095 impl_def_id: ImplDefId,
1096 impl_function_id: ImplFunctionId,
1097 trait_id: TraitId,
1098 expected_ty: semantic::TypeId,
1099 actual_ty: semantic::TypeId,
1100 },
1101 AmbiguousTrait {
1102 trait_function_id0: TraitFunctionId,
1103 trait_function_id1: TraitFunctionId,
1104 },
1105 VariableNotFound(SmolStr),
1106 MissingVariableInPattern,
1107 StructMemberRedefinition {
1108 struct_id: StructId,
1109 member_name: SmolStr,
1110 },
1111 EnumVariantRedefinition {
1112 enum_id: EnumId,
1113 variant_name: SmolStr,
1114 },
1115 InfiniteSizeType(semantic::TypeId),
1116 ArrayOfZeroSizedElements(semantic::TypeId),
1117 ParamNameRedefinition {
1118 function_title_id: Option<FunctionTitleId>,
1119 param_name: SmolStr,
1120 },
1121 ConditionNotBool(semantic::TypeId),
1122 IncompatibleArms {
1123 multi_arm_expr_kind: MultiArmExprKind,
1124 pending_ty: semantic::TypeId,
1125 different_ty: semantic::TypeId,
1126 },
1127 LogicalOperatorNotAllowedInIfLet,
1128 LogicalOperatorNotAllowedInWhileLet,
1129 TypeHasNoMembers {
1130 ty: semantic::TypeId,
1131 member_name: SmolStr,
1132 },
1133 CannotCallMethod {
1134 ty: semantic::TypeId,
1135 method_name: SmolStr,
1136 inference_errors: TraitInferenceErrors,
1137 },
1138 NoSuchStructMember {
1139 struct_id: StructId,
1140 member_name: SmolStr,
1141 },
1142 NoSuchTypeMember {
1143 ty: semantic::TypeId,
1144 member_name: SmolStr,
1145 },
1146 MemberNotVisible(SmolStr),
1147 NoSuchVariant {
1148 enum_id: EnumId,
1149 variant_name: SmolStr,
1150 },
1151 ReturnTypeNotErrorPropagateType,
1152 IncompatibleErrorPropagateType {
1153 return_ty: semantic::TypeId,
1154 err_ty: semantic::TypeId,
1155 },
1156 ErrorPropagateOnNonErrorType(semantic::TypeId),
1157 UnhandledMustUseType(semantic::TypeId),
1158 UnstableFeature {
1159 feature_name: SmolStr,
1160 note: Option<SmolStr>,
1161 },
1162 DeprecatedFeature {
1163 feature_name: SmolStr,
1164 note: Option<SmolStr>,
1165 },
1166 InternalFeature {
1167 feature_name: SmolStr,
1168 note: Option<SmolStr>,
1169 },
1170 FeatureMarkerDiagnostic(FeatureMarkerDiagnostic),
1171 UnhandledMustUseFunction,
1172 UnusedVariable,
1173 UnusedConstant,
1174 UnusedUse,
1175 MultipleConstantDefinition(SmolStr),
1176 MultipleDefinitionforBinding(SmolStr),
1177 MultipleGenericItemDefinition(SmolStr),
1178 UnsupportedUseItemInStatement,
1179 ConstGenericParamNotSupported,
1180 NegativeImplsNotEnabled,
1181 NegativeImplsOnlyOnImpls,
1182 RefArgNotAVariable,
1183 RefArgNotMutable,
1184 RefArgNotExplicit,
1185 ImmutableArgWithModifiers,
1186 AssignmentToImmutableVar,
1187 InvalidLhsForAssignment,
1188 InvalidMemberExpression,
1189 InvalidPath,
1190 PathNotFound(NotFoundItemType),
1191 AmbiguousPath(Vec<ModuleItemId>),
1192 UseStarEmptyPath,
1193 GlobalUsesNotSupportedInEdition(Edition),
1194 TraitInTraitMustBeExplicit,
1195 ImplInImplMustBeExplicit,
1196 TraitItemForbiddenInTheTrait,
1197 TraitItemForbiddenInItsImpl,
1198 ImplItemForbiddenInTheImpl,
1199 SuperUsedInRootModule,
1200 ItemNotVisible(ModuleItemId, Vec<ModuleId>),
1201 UnusedImport(UseId),
1202 RedundantModifier {
1203 current_modifier: SmolStr,
1204 previous_modifier: SmolStr,
1205 },
1206 ReferenceLocalVariable,
1207 UnexpectedEnumPattern(semantic::TypeId),
1208 UnexpectedStructPattern(semantic::TypeId),
1209 UnexpectedTuplePattern(semantic::TypeId),
1210 UnexpectedFixedSizeArrayPattern(semantic::TypeId),
1211 WrongNumberOfTupleElements {
1212 expected: usize,
1213 actual: usize,
1214 },
1215 WrongNumberOfFixedSizeArrayElements {
1216 expected: usize,
1217 actual: usize,
1218 },
1219 WrongEnum {
1220 expected_enum: EnumId,
1221 actual_enum: EnumId,
1222 },
1223 InvalidCopyTraitImpl(InferenceError),
1224 InvalidDropTraitImpl(InferenceError),
1225 InvalidImplItem(SmolStr),
1226 MissingItemsInImpl(Vec<SmolStr>),
1227 PassPanicAsNopanic {
1228 impl_function_id: ImplFunctionId,
1229 trait_id: TraitId,
1230 },
1231 PanicableFromNonPanicable,
1232 PanicableExternFunction,
1233 PluginDiagnostic(PluginDiagnostic),
1234 NameDefinedMultipleTimes(SmolStr),
1235 NonPrivateUseStar,
1236 NamedArgumentsAreNotSupported,
1237 ArgPassedToNegativeImpl,
1238 UnnamedArgumentFollowsNamed,
1239 NamedArgumentMismatch {
1240 expected: SmolStr,
1241 found: SmolStr,
1242 },
1243 UnsupportedOutsideOfFunction(UnsupportedOutsideOfFunctionFeatureName),
1244 UnsupportedConstant,
1245 DivisionByZero,
1246 ExternTypeWithImplGenericsNotSupported,
1247 MissingSemicolon,
1248 TraitMismatch {
1249 expected_trt: semantic::ConcreteTraitId,
1250 actual_trt: semantic::ConcreteTraitId,
1251 },
1252 DesnapNonSnapshot,
1253 InternalInferenceError(InferenceError),
1254 NoImplementationOfIndexOperator {
1255 ty: semantic::TypeId,
1256 inference_errors: TraitInferenceErrors,
1257 },
1258 NoImplementationOfTrait {
1259 ty: semantic::TypeId,
1260 trait_name: SmolStr,
1261 inference_errors: TraitInferenceErrors,
1262 },
1263 CallExpressionRequiresFunction {
1264 ty: semantic::TypeId,
1265 inference_errors: TraitInferenceErrors,
1266 },
1267 MultipleImplementationOfIndexOperator(semantic::TypeId),
1268
1269 UnsupportedInlineArguments,
1270 RedundantInlineAttribute,
1271 InlineAttrForExternFunctionNotAllowed,
1272 InlineAlwaysWithImplGenericArgNotAllowed,
1273 TailExpressionNotAllowedInLoop,
1274 ContinueOnlyAllowedInsideALoop,
1275 BreakOnlyAllowedInsideALoop,
1276 BreakWithValueOnlyAllowedInsideALoop,
1277 ReturnNotAllowedInsideALoop,
1278 ErrorPropagateNotAllowedInsideALoop,
1279 ImplicitPrecedenceAttrForExternFunctionNotAllowed,
1280 RedundantImplicitPrecedenceAttribute,
1281 UnsupportedImplicitPrecedenceArguments,
1282 UnsupportedFeatureAttrArguments,
1283 UnsupportedAllowAttrArguments,
1284 UnsupportedPubArgument,
1285 UnknownStatementAttribute,
1286 InlineMacroNotFound(SmolStr),
1287 InlineMacroFailed(SmolStr),
1288 UnknownGenericParam(SmolStr),
1289 PositionalGenericAfterNamed,
1290 GenericArgDuplicate(SmolStr),
1291 TooManyGenericArguments {
1292 expected: usize,
1293 actual: usize,
1294 },
1295 GenericArgOutOfOrder(SmolStr),
1296 CouponForExternFunctionNotAllowed,
1297 CouponArgumentNoModifiers,
1298 CouponsDisabled,
1300 FixedSizeArrayTypeNonSingleType,
1301 FixedSizeArrayTypeEmptySize,
1302 FixedSizeArrayNonNumericSize,
1303 FixedSizeArrayNonSingleValue,
1304 FixedSizeArraySizeTooBig,
1305 SelfNotSupportedInContext,
1306 SelfMustBeFirst,
1307 DerefCycle {
1308 deref_chain: String,
1309 },
1310 CompilerTraitReImplementation {
1311 trait_id: TraitId,
1312 },
1313 ClosureInGlobalScope,
1314 MaybeMissingColonColon,
1315 CallingShadowedFunction {
1316 shadowed_function_name: SmolStr,
1317 },
1318 RefClosureArgument,
1319 MutableCapturedVariable,
1320 NonTraitTypeConstrained {
1321 identifier: SmolStr,
1322 concrete_trait_id: ConcreteTraitId,
1323 },
1324 DuplicateTypeConstraint {
1325 concrete_trait_type_id: ConcreteTraitTypeId,
1326 },
1327 TypeConstraintsSyntaxNotEnabled,
1328}
1329
1330#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1332pub enum MultiArmExprKind {
1333 If,
1334 Match,
1335 Loop,
1336}
1337
1338impl SemanticDiagnosticKind {
1339 pub fn error_code(&self) -> Option<ErrorCode> {
1340 Some(match &self {
1341 Self::UnusedVariable => error_code!(E0001),
1342 Self::CannotCallMethod { .. } => {
1343 error_code!(E0002)
1344 }
1345 Self::MissingMember(_) => error_code!(E0003),
1346 Self::MissingItemsInImpl(_) => error_code!(E0004),
1347 Self::ModuleFileNotFound(_) => error_code!(E0005),
1348 _ => return None,
1349 })
1350 }
1351}
1352
1353#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1354pub enum NotFoundItemType {
1355 Identifier,
1356 Function,
1357 Type,
1358 Trait,
1359 Impl,
1360}
1361
1362#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1363pub enum UnsupportedOutsideOfFunctionFeatureName {
1364 ReturnStatement,
1365 ErrorPropagate,
1366}
1367
1368#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1369pub enum ElementKind {
1370 Constant,
1371 Variable,
1372 Module,
1373 Function,
1374 TraitFunction,
1375 Type,
1376 Variant,
1377 Trait,
1378 Impl,
1379}
1380impl From<&ResolvedConcreteItem> for ElementKind {
1381 fn from(val: &ResolvedConcreteItem) -> Self {
1382 match val {
1383 ResolvedConcreteItem::Constant(_) => ElementKind::Constant,
1384 ResolvedConcreteItem::Module(_) => ElementKind::Module,
1385 ResolvedConcreteItem::Function(_) => ElementKind::Function,
1386 ResolvedConcreteItem::TraitFunction(_) => ElementKind::TraitFunction,
1387 ResolvedConcreteItem::Type(_) => ElementKind::Type,
1388 ResolvedConcreteItem::Variant(_) => ElementKind::Variant,
1389 ResolvedConcreteItem::Trait(_) => ElementKind::Trait,
1390 ResolvedConcreteItem::Impl(_) => ElementKind::Impl,
1391 }
1392 }
1393}
1394impl From<&ResolvedGenericItem> for ElementKind {
1395 fn from(val: &ResolvedGenericItem) -> Self {
1396 match val {
1397 ResolvedGenericItem::GenericConstant(_) => ElementKind::Constant,
1398 ResolvedGenericItem::Module(_) => ElementKind::Module,
1399 ResolvedGenericItem::GenericFunction(_) => ElementKind::Function,
1400 ResolvedGenericItem::TraitFunction(_) => ElementKind::TraitFunction,
1401 ResolvedGenericItem::GenericType(_) | ResolvedGenericItem::GenericTypeAlias(_) => {
1402 ElementKind::Type
1403 }
1404 ResolvedGenericItem::Variant(_) => ElementKind::Variant,
1405 ResolvedGenericItem::Trait(_) => ElementKind::Trait,
1406 ResolvedGenericItem::Impl(_) | ResolvedGenericItem::GenericImplAlias(_) => {
1407 ElementKind::Impl
1408 }
1409 ResolvedGenericItem::Variable(_) => ElementKind::Variable,
1410 }
1411 }
1412}
1413impl Display for ElementKind {
1414 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1415 let res = match self {
1416 ElementKind::Constant => "constant",
1417 ElementKind::Variable => "variable",
1418 ElementKind::Module => "module",
1419 ElementKind::Function => "function",
1420 ElementKind::TraitFunction => "function",
1421 ElementKind::Type => "type",
1422 ElementKind::Variant => "variant",
1423 ElementKind::Trait => "trait",
1424 ElementKind::Impl => "impl",
1425 };
1426 write!(f, "{res}")
1427 }
1428}
1429
1430#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1432pub struct TraitInferenceErrors {
1433 pub traits_and_errors: Vec<(TraitFunctionId, InferenceError)>,
1434}
1435impl TraitInferenceErrors {
1436 fn is_empty(&self) -> bool {
1438 self.traits_and_errors.is_empty()
1439 }
1440 fn format(&self, db: &(dyn SemanticGroup + 'static)) -> String {
1442 self.traits_and_errors
1443 .iter()
1444 .map(|(trait_function_id, inference_error)| {
1445 format!(
1446 "Candidate `{}` inference failed with: {}",
1447 trait_function_id.full_path(db.upcast()),
1448 inference_error.format(db)
1449 )
1450 })
1451 .join("\n")
1452 }
1453}