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