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 "{}" cannot 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::ConstTypeNotVarFree => {
776 "Constant type must not depend on its value.".into()
777 }
778 SemanticDiagnosticKind::UnsupportedConstant => {
779 "This expression is not supported as constant.".into()
780 }
781 SemanticDiagnosticKind::FailedConstantCalculation => {
782 "Failed to calculate constant.".into()
783 }
784 SemanticDiagnosticKind::ConstantCalculationDepthExceeded => {
785 "Constant calculation depth exceeded.".into()
786 }
787 SemanticDiagnosticKind::InnerFailedConstantCalculation(inner, _) => inner.format(db),
788 SemanticDiagnosticKind::DivisionByZero => "Division by zero.".into(),
789 SemanticDiagnosticKind::ExternTypeWithImplGenericsNotSupported => {
790 "Extern types with impl generics are not supported.".into()
791 }
792 SemanticDiagnosticKind::MissingSemicolon => "Missing semicolon".into(),
793 SemanticDiagnosticKind::TraitMismatch { expected_trt, actual_trt } => {
794 format!(
795 "Expected an impl of `{:?}`. Got an impl of `{:?}`.",
796 expected_trt.debug(db),
797 actual_trt.debug(db),
798 )
799 }
800 SemanticDiagnosticKind::InternalInferenceError(err) => err.format(db),
801 SemanticDiagnosticKind::DerefNonRef { ty } => {
802 format!("Type `{}` cannot be dereferenced", ty.format(db))
803 }
804 SemanticDiagnosticKind::NoImplementationOfIndexOperator { ty, inference_errors } => {
805 if inference_errors.is_empty() {
806 format!(
807 "Type `{}` does not implement the `Index` trait nor the `IndexView` trait.",
808 ty.format(db)
809 )
810 } else {
811 format!(
812 "Type `{}` could not be indexed.\n{}",
813 ty.format(db),
814 inference_errors.format(db)
815 )
816 }
817 }
818 SemanticDiagnosticKind::MultipleImplementationOfIndexOperator(ty) => {
819 format!(
820 r#"Type "{}" implements both the "Index" trait and the "IndexView" trait."#,
821 ty.format(db)
822 )
823 }
824 SemanticDiagnosticKind::UnsupportedInlineArguments => {
825 "Unsupported `inline` arguments.".into()
826 }
827 SemanticDiagnosticKind::RedundantInlineAttribute => {
828 "Redundant `inline` attribute.".into()
829 }
830 SemanticDiagnosticKind::InlineAttrForExternFunctionNotAllowed => {
831 "`inline` attribute is not allowed for extern functions.".into()
832 }
833 SemanticDiagnosticKind::InlineAlwaysWithImplGenericArgNotAllowed => {
834 "`#[inline(always)]` is not allowed for functions with impl generic parameters."
835 .into()
836 }
837 SemanticDiagnosticKind::CannotCallMethod {
838 ty,
839 method_name,
840 inference_errors,
841 relevant_traits,
842 } => {
843 if !inference_errors.is_empty() {
844 return format!(
845 "Method `{}` could not be called on type `{}`.\n{}",
846 method_name.long(db),
847 ty.format(db),
848 inference_errors.format(db)
849 );
850 }
851 if !relevant_traits.is_empty() {
852 let suggestions = relevant_traits
853 .iter()
854 .map(|trait_path| format!("`{trait_path}`"))
855 .collect::<Vec<_>>()
856 .join(", ");
857
858 format!(
859 "Method `{}` not found on type `{}`. Consider importing one of the \
860 following traits: {}.",
861 method_name.long(db),
862 ty.format(db),
863 suggestions
864 )
865 } else {
866 format!(
867 "Method `{}` not found on type `{}`. Did you import the correct trait and \
868 impl?",
869 method_name.long(db),
870 ty.format(db)
871 )
872 }
873 }
874 SemanticDiagnosticKind::TailExpressionNotAllowedInLoop => {
875 "Tail expression not allowed in a `loop` block.".into()
876 }
877 SemanticDiagnosticKind::ContinueOnlyAllowedInsideALoop => {
878 "`continue` only allowed inside a `loop`.".into()
879 }
880 SemanticDiagnosticKind::BreakOnlyAllowedInsideALoop => {
881 "`break` only allowed inside a `loop`.".into()
882 }
883 SemanticDiagnosticKind::BreakWithValueOnlyAllowedInsideALoop => {
884 "Can only break with a value inside a `loop`.".into()
885 }
886 SemanticDiagnosticKind::ErrorPropagateNotAllowedInsideALoop => {
887 "`?` not allowed inside a `loop`.".into()
888 }
889 SemanticDiagnosticKind::ConstGenericParamNotSupported => {
890 "Const generic args are not allowed in this context.".into()
891 }
892 SemanticDiagnosticKind::NegativeImplsNotEnabled => {
893 "Negative impls are not enabled in the current crate.".into()
894 }
895 SemanticDiagnosticKind::NegativeImplsOnlyOnImpls => {
896 "Negative impls supported only in impl definitions.".into()
897 }
898 SemanticDiagnosticKind::ImplicitPrecedenceAttrForExternFunctionNotAllowed => {
899 "`implicit_precedence` attribute is not allowed for extern functions.".into()
900 }
901 SemanticDiagnosticKind::RedundantImplicitPrecedenceAttribute => {
902 "Redundant `implicit_precedence` attribute.".into()
903 }
904 SemanticDiagnosticKind::UnsupportedImplicitPrecedenceArguments => {
905 "Unsupported `implicit_precedence` arguments.".into()
906 }
907 SemanticDiagnosticKind::UnsupportedFeatureAttrArguments => {
908 "`feature` attribute argument should be a single string.".into()
909 }
910 SemanticDiagnosticKind::UnsupportedAllowAttrArguments => {
911 "`allow` attribute argument not supported.".into()
913 }
914 SemanticDiagnosticKind::UnsupportedPubArgument => "Unsupported `pub` argument.".into(),
915 SemanticDiagnosticKind::UnknownStatementAttribute => {
916 "Unknown statement attribute.".into()
917 }
918 SemanticDiagnosticKind::InlineMacroNotFound(macro_name) => {
919 format!("Inline macro `{}` not found.", macro_name.long(db))
920 }
921 SemanticDiagnosticKind::InlineMacroFailed(macro_name) => {
922 format!("Inline macro `{}` failed.", macro_name.long(db))
923 }
924 SemanticDiagnosticKind::InlineMacroNoMatchingRule(macro_name) => {
925 format!("No matching rule found in inline macro `{}`.", macro_name.long(db))
926 }
927 SemanticDiagnosticKind::MacroCallToNotAMacro(name) => {
928 format!("Call to `{}` which is not a macro.", name.long(db))
929 }
930 SemanticDiagnosticKind::UnknownGenericParam(name) => {
931 format!("Unknown generic parameter `{}`.", name.long(db))
932 }
933 SemanticDiagnosticKind::PositionalGenericAfterNamed => {
934 "Positional generic parameters must come before named generic parameters.".into()
935 }
936 SemanticDiagnosticKind::GenericArgDuplicate(name) => {
937 format!("Generic argument `{}` is specified more than once.", name.long(db))
938 }
939 SemanticDiagnosticKind::TooManyGenericArguments { expected, actual } => {
940 format!("Expected {expected} generic arguments, found {actual}.")
941 }
942 SemanticDiagnosticKind::GenericArgOutOfOrder(name) => {
943 format!("Generic argument `{}` is out of order.", name.long(db))
944 }
945 SemanticDiagnosticKind::ArgPassedToNegativeImpl => {
946 "Only `_` is valid as a negative impl argument.".into()
947 }
948 SemanticDiagnosticKind::CouponForExternFunctionNotAllowed => {
949 "Coupon cannot be used with extern functions.".into()
950 }
951 SemanticDiagnosticKind::CouponArgumentNoModifiers => {
952 "The __coupon__ argument cannot have modifiers.".into()
953 }
954 SemanticDiagnosticKind::CouponsDisabled => {
955 "Coupons are disabled in the current crate.\nYou can enable them by enabling the \
956 coupons experimental feature in the crate config."
957 .into()
958 }
959 SemanticDiagnosticKind::ReprPtrsDisabled => {
960 "Representation pointers are disabled in the current crate.\nYou can enable them \
961 by enabling the `repr_ptrs` experimental feature in the crate config."
962 .into()
963 }
964 SemanticDiagnosticKind::AssignmentToReprPtrVariable { .. } => {
965 "Cannot assign to a variable with a taken pointer".into()
966 }
967 SemanticDiagnosticKind::StructBaseStructExpressionNotLast => {
968 "The base struct must always be the last argument.".into()
969 }
970 SemanticDiagnosticKind::StructBaseStructExpressionNoEffect => {
971 "Base struct has no effect, all the fields in the struct have already been \
972 specified."
973 .into()
974 }
975 SemanticDiagnosticKind::FixedSizeArrayTypeNonSingleType => {
976 "Fixed size array type must have exactly one type.".into()
977 }
978 SemanticDiagnosticKind::FixedSizeArrayTypeEmptySize => {
979 "Fixed size array type must have a size clause.".into()
980 }
981 SemanticDiagnosticKind::FixedSizeArrayNonNumericSize => {
982 "Fixed size array type must have a positive integer size.".into()
983 }
984 SemanticDiagnosticKind::FixedSizeArrayNonSingleValue => {
985 "Fixed size array with defined size must have exactly one value.".into()
986 }
987 SemanticDiagnosticKind::FixedSizeArraySizeTooBig => {
988 "Fixed size array size must be smaller than 2^15.".into()
989 }
990 SemanticDiagnosticKind::SelfNotSupportedInContext => {
991 "`Self` is not supported in this context.".into()
992 }
993 SemanticDiagnosticKind::SelfMustBeFirst => {
994 "`Self` can only be the first segment of a path.".into()
995 }
996 SemanticDiagnosticKind::DollarNotSupportedInContext => {
997 "`$` is not supported in this context.".into()
998 }
999 SemanticDiagnosticKind::UnknownResolverModifier { modifier } => {
1000 format!("`${}` is not supported.", modifier.long(db))
1001 }
1002 SemanticDiagnosticKind::EmptyPathAfterResolverModifier => {
1003 "Expected path after modifier.".into()
1004 }
1005 SemanticDiagnosticKind::CannotCreateInstancesOfPhantomTypes => {
1006 "Can not create instances of phantom types.".into()
1007 }
1008 SemanticDiagnosticKind::NonPhantomTypeContainingPhantomType => {
1009 "Non-phantom type containing phantom type.".into()
1010 }
1011 SemanticDiagnosticKind::DerefCycle { deref_chain } => {
1012 format!("Deref impls cycle detected:\n{deref_chain}")
1013 }
1014 SemanticDiagnosticKind::NoImplementationOfTrait {
1015 ty,
1016 trait_name,
1017 inference_errors,
1018 } => {
1019 if inference_errors.is_empty() {
1020 format!(
1021 "Implementation of trait `{}` not found on type `{}`. Did you import the \
1022 correct trait and impl?",
1023 trait_name.long(db),
1024 ty.format(db)
1025 )
1026 } else {
1027 format!(
1028 "Could not find implementation of trait `{}` on type `{}`.\n{}",
1029 trait_name.long(db),
1030 ty.format(db),
1031 inference_errors.format(db)
1032 )
1033 }
1034 }
1035 SemanticDiagnosticKind::CallExpressionRequiresFunction { ty, inference_errors } => {
1036 if inference_errors.is_empty() {
1037 format!("Call expression requires a function, found `{}`.", ty.format(db))
1038 } else {
1039 format!(
1040 "Call expression requires a function, found `{}`.\n{}",
1041 ty.format(db),
1042 inference_errors.format(db)
1043 )
1044 }
1045 }
1046 SemanticDiagnosticKind::CompilerTraitReImplementation { trait_id } => {
1047 format!(
1048 "Trait `{}` should not be implemented outside of the corelib.",
1049 trait_id.full_path(db)
1050 )
1051 }
1052 SemanticDiagnosticKind::ClosureInGlobalScope => {
1053 "Closures are not allowed in this context.".into()
1054 }
1055 SemanticDiagnosticKind::MaybeMissingColonColon => "Are you missing a `::`?.".into(),
1056 SemanticDiagnosticKind::CallingShadowedFunction { shadowed_function_name } => {
1057 format!(
1058 "Function `{}` is shadowed by a local variable.",
1059 shadowed_function_name.long(db)
1060 )
1061 }
1062 SemanticDiagnosticKind::RefClosureArgument => {
1063 "Arguments to closure functions cannot be references".into()
1064 }
1065 SemanticDiagnosticKind::RefClosureParam => {
1066 "Closure parameters cannot be references".into()
1067 }
1068 SemanticDiagnosticKind::MustBeNextToTypeOrTrait { trait_id } => {
1069 format!(
1070 "'{}' implementation must be defined in the same module as either the type \
1071 being dereferenced or the trait itself",
1072 trait_id.name(db).long(db)
1073 )
1074 }
1075 SemanticDiagnosticKind::MutableCapturedVariable => {
1076 "Capture of mutable variables in a closure is not supported".into()
1077 }
1078 SemanticDiagnosticKind::NonTraitTypeConstrained { identifier, concrete_trait_id } => {
1079 format!(
1080 "associated type `{}` not found for `{}`",
1081 identifier.long(db),
1082 concrete_trait_id.full_path(db)
1083 )
1084 }
1085 SemanticDiagnosticKind::DuplicateTypeConstraint {
1086 concrete_trait_type_id: trait_type_id,
1087 } => {
1088 format!(
1089 "the value of the associated type `{}` in trait `{}` is already specified",
1090 trait_type_id.trait_type(db).name(db).long(db),
1091 trait_type_id.concrete_trait(db).full_path(db)
1092 )
1093 }
1094 SemanticDiagnosticKind::TypeConstraintsSyntaxNotEnabled => {
1095 "Type constraints syntax is not enabled in the current crate.".into()
1096 }
1097 SemanticDiagnosticKind::PatternMissingArgs(path) => {
1098 format!(
1099 "Pattern missing subpattern for the payload of variant. Consider using `{}(_)`",
1100 path.segments(db)
1101 .elements(db)
1102 .map(|seg| seg.identifier(db).long(db))
1103 .join("::")
1104 )
1105 }
1106 SemanticDiagnosticKind::UndefinedMacroPlaceholder(name) => {
1107 format!("Undefined macro placeholder: '{}'.", name.long(db))
1108 }
1109 SemanticDiagnosticKind::UserDefinedInlineMacrosDisabled => {
1110 "User defined inline macros are disabled in the current crate.".into()
1111 }
1112 SemanticDiagnosticKind::NonNeverLetElseType => concat!(
1113 "`else` clause of `let...else` must exit the scope. ",
1114 "Consider using `return`, `continue`, ..."
1115 )
1116 .into(),
1117 SemanticDiagnosticKind::OnlyTypeOrConstParamsInNegImpl => {
1118 "Negative impls may only use type or const generic parameters.".into()
1119 }
1120 }
1121 }
1122 fn location(&self, db: &'db dyn Database) -> SpanInFile<'db> {
1123 if let SemanticDiagnosticKind::MacroGeneratedCodeParserDiagnostic(parser_diagnostic) =
1124 &self.kind
1125 {
1126 return SpanInFile { file_id: parser_diagnostic.file_id, span: parser_diagnostic.span };
1127 };
1128
1129 let mut location = self.stable_location.span_in_file(db);
1130 if self.after {
1131 location = location.after();
1132 }
1133 location
1134 }
1135
1136 fn severity(&self) -> Severity {
1137 match &self.kind {
1138 SemanticDiagnosticKind::UnusedVariable
1139 | SemanticDiagnosticKind::UnhandledMustUseType { .. }
1140 | SemanticDiagnosticKind::UnhandledMustUseFunction
1141 | SemanticDiagnosticKind::TraitInTraitMustBeExplicit
1142 | SemanticDiagnosticKind::ImplInImplMustBeExplicit
1143 | SemanticDiagnosticKind::TraitItemForbiddenInTheTrait
1144 | SemanticDiagnosticKind::TraitItemForbiddenInItsImpl
1145 | SemanticDiagnosticKind::ImplItemForbiddenInTheImpl
1146 | SemanticDiagnosticKind::UnstableFeature { .. }
1147 | SemanticDiagnosticKind::DeprecatedFeature { .. }
1148 | SemanticDiagnosticKind::UnusedImport { .. }
1149 | SemanticDiagnosticKind::CallingShadowedFunction { .. }
1150 | SemanticDiagnosticKind::UnusedConstant
1151 | SemanticDiagnosticKind::UnusedUse
1152 | SemanticDiagnosticKind::PatternMissingArgs(_)
1153 | SemanticDiagnosticKind::UnsupportedAllowAttrArguments => Severity::Warning,
1154 SemanticDiagnosticKind::PluginDiagnostic(diag) => diag.severity,
1155 _ => Severity::Error,
1156 }
1157 }
1158
1159 fn notes(&self, _db: &dyn Database) -> &[DiagnosticNote<'_>] {
1160 match &self.kind {
1161 SemanticDiagnosticKind::InnerFailedConstantCalculation(_, notes) => notes,
1162 SemanticDiagnosticKind::AssignmentToReprPtrVariable(notes) => notes,
1163 _ => &[],
1164 }
1165 }
1166
1167 fn error_code(&self) -> Option<ErrorCode> {
1168 self.kind.error_code()
1169 }
1170
1171 fn is_same_kind(&self, other: &Self) -> bool {
1172 other.kind == self.kind
1173 }
1174}
1175
1176#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1177pub enum SemanticDiagnosticKind<'db> {
1178 ModuleFileNotFound(String),
1179 Unsupported,
1180 UnknownLiteral,
1181 UnknownBinaryOperator,
1182 UnknownTrait,
1183 UnknownImpl,
1184 UnexpectedElement {
1185 expected: Vec<ElementKind>,
1186 actual: ElementKind,
1187 },
1188 UnknownType,
1189 UnknownEnum,
1190 LiteralError(LiteralError<'db>),
1191 NotAVariant,
1192 NotAStruct,
1193 NotAType,
1194 NotATrait,
1195 NotAnImpl,
1196 ImplItemNotInTrait {
1197 impl_def_id: ImplDefId<'db>,
1198 impl_item_name: SmolStrId<'db>,
1199 trait_id: TraitId<'db>,
1200 item_kind: String,
1201 },
1202 ImplicitImplNotInferred {
1203 trait_impl_id: TraitImplId<'db>,
1204 concrete_trait_id: ConcreteTraitId<'db>,
1205 },
1206 GenericsNotSupportedInItem {
1207 scope: String,
1208 item_kind: String,
1209 },
1210 UnexpectedGenericArgs,
1211 UnknownMember,
1212 CannotCreateInstancesOfPhantomTypes,
1213 NonPhantomTypeContainingPhantomType,
1214 MemberSpecifiedMoreThanOnce,
1215 StructBaseStructExpressionNotLast,
1216 StructBaseStructExpressionNoEffect,
1217 ConstCycle,
1218 UseCycle,
1219 TypeAliasCycle,
1220 ImplAliasCycle,
1221 ImplRequirementCycle,
1222 MissingMember(SmolStrId<'db>),
1223 WrongNumberOfParameters {
1224 impl_def_id: ImplDefId<'db>,
1225 impl_function_id: ImplFunctionId<'db>,
1226 trait_id: TraitId<'db>,
1227 expected: usize,
1228 actual: usize,
1229 },
1230 WrongNumberOfArguments {
1231 expected: usize,
1232 actual: usize,
1233 },
1234 WrongParameterType {
1235 impl_def_id: ImplDefId<'db>,
1236 impl_function_id: ImplFunctionId<'db>,
1237 trait_id: TraitId<'db>,
1238 expected_ty: semantic::TypeId<'db>,
1239 actual_ty: semantic::TypeId<'db>,
1240 },
1241 VariantCtorNotImmutable,
1242 TraitParamMutable {
1243 trait_id: TraitId<'db>,
1244 function_id: TraitFunctionId<'db>,
1245 },
1246 ParameterShouldBeReference {
1247 impl_def_id: ImplDefId<'db>,
1248 impl_function_id: ImplFunctionId<'db>,
1249 trait_id: TraitId<'db>,
1250 },
1251 ParameterShouldNotBeReference {
1252 impl_def_id: ImplDefId<'db>,
1253 impl_function_id: ImplFunctionId<'db>,
1254 trait_id: TraitId<'db>,
1255 },
1256 WrongParameterName {
1257 impl_def_id: ImplDefId<'db>,
1258 impl_function_id: ImplFunctionId<'db>,
1259 trait_id: TraitId<'db>,
1260 expected_name: SmolStrId<'db>,
1261 },
1262 WrongGenericParamTraitForImplFunction {
1263 impl_def_id: ImplDefId<'db>,
1264 impl_function_id: ImplFunctionId<'db>,
1265 trait_id: TraitId<'db>,
1266 expected_trait: ConcreteTraitId<'db>,
1267 actual_trait: ConcreteTraitId<'db>,
1268 },
1269 WrongGenericParamKindForImplFunction {
1270 impl_def_id: ImplDefId<'db>,
1271 impl_function_id: ImplFunctionId<'db>,
1272 trait_id: TraitId<'db>,
1273 expected_kind: GenericKind,
1274 actual_kind: GenericKind,
1275 },
1276 WrongType {
1277 expected_ty: semantic::TypeId<'db>,
1278 actual_ty: semantic::TypeId<'db>,
1279 },
1280 InconsistentBinding,
1281 WrongArgumentType {
1282 expected_ty: semantic::TypeId<'db>,
1283 actual_ty: semantic::TypeId<'db>,
1284 },
1285 WrongReturnType {
1286 expected_ty: semantic::TypeId<'db>,
1287 actual_ty: semantic::TypeId<'db>,
1288 },
1289 WrongExprType {
1290 expected_ty: semantic::TypeId<'db>,
1291 actual_ty: semantic::TypeId<'db>,
1292 },
1293 WrongNumberOfGenericParamsForImplFunction {
1294 expected: usize,
1295 actual: usize,
1296 },
1297 WrongReturnTypeForImpl {
1298 impl_def_id: ImplDefId<'db>,
1299 impl_function_id: ImplFunctionId<'db>,
1300 trait_id: TraitId<'db>,
1301 expected_ty: semantic::TypeId<'db>,
1302 actual_ty: semantic::TypeId<'db>,
1303 },
1304 AmbiguousTrait {
1305 trait_function_id0: TraitFunctionId<'db>,
1306 trait_function_id1: TraitFunctionId<'db>,
1307 },
1308 VariableNotFound(SmolStrId<'db>),
1309 MissingVariableInPattern,
1310 VariableDefinedMultipleTimesInPattern(SmolStrId<'db>),
1311 StructMemberRedefinition {
1312 struct_id: StructId<'db>,
1313 member_name: SmolStrId<'db>,
1314 },
1315 EnumVariantRedefinition {
1316 enum_id: EnumId<'db>,
1317 variant_name: SmolStrId<'db>,
1318 },
1319 InfiniteSizeType(semantic::TypeId<'db>),
1320 ArrayOfZeroSizedElements(semantic::TypeId<'db>),
1321 ParamNameRedefinition {
1322 function_title_id: Option<FunctionTitleId<'db>>,
1323 param_name: SmolStrId<'db>,
1324 },
1325 ConditionNotBool(semantic::TypeId<'db>),
1326 IncompatibleArms {
1327 multi_arm_expr_kind: MultiArmExprKind,
1328 pending_ty: semantic::TypeId<'db>,
1329 different_ty: semantic::TypeId<'db>,
1330 },
1331 TypeHasNoMembers {
1332 ty: semantic::TypeId<'db>,
1333 member_name: SmolStrId<'db>,
1334 },
1335 CannotCallMethod {
1336 ty: semantic::TypeId<'db>,
1337 method_name: SmolStrId<'db>,
1338 inference_errors: TraitInferenceErrors<'db>,
1339 relevant_traits: Vec<String>,
1340 },
1341 NoSuchStructMember {
1342 struct_id: StructId<'db>,
1343 member_name: SmolStrId<'db>,
1344 },
1345 NoSuchTypeMember {
1346 ty: semantic::TypeId<'db>,
1347 member_name: SmolStrId<'db>,
1348 },
1349 MemberNotVisible(SmolStrId<'db>),
1350 NoSuchVariant {
1351 enum_id: EnumId<'db>,
1352 variant_name: SmolStrId<'db>,
1353 },
1354 ReturnTypeNotErrorPropagateType,
1355 IncompatibleErrorPropagateType {
1356 return_ty: semantic::TypeId<'db>,
1357 err_ty: semantic::TypeId<'db>,
1358 },
1359 ErrorPropagateOnNonErrorType(semantic::TypeId<'db>),
1360 UnhandledMustUseType(semantic::TypeId<'db>),
1361 UnstableFeature {
1362 feature_name: SmolStrId<'db>,
1363 note: Option<SmolStrId<'db>>,
1364 },
1365 DeprecatedFeature {
1366 feature_name: SmolStrId<'db>,
1367 note: Option<SmolStrId<'db>>,
1368 },
1369 InternalFeature {
1370 feature_name: SmolStrId<'db>,
1371 note: Option<SmolStrId<'db>>,
1372 },
1373 FeatureMarkerDiagnostic(FeatureMarkerDiagnostic),
1374 UnhandledMustUseFunction,
1375 UnusedVariable,
1376 UnusedConstant,
1377 UnusedUse,
1378 MultipleConstantDefinition(SmolStrId<'db>),
1379 MultipleDefinitionforBinding(SmolStrId<'db>),
1380 MultipleGenericItemDefinition(SmolStrId<'db>),
1381 UnsupportedUseItemInStatement,
1382 ConstGenericParamNotSupported,
1383 NegativeImplsNotEnabled,
1384 NegativeImplsOnlyOnImpls,
1385 RefArgNotAVariable,
1386 RefArgNotMutable,
1387 RefArgNotExplicit,
1388 ImmutableArgWithModifiers,
1389 AssignmentToImmutableVar,
1390 InvalidLhsForAssignment,
1391 InvalidMemberExpression,
1392 InvalidPath,
1393 PathNotFound(NotFoundItemType),
1394 AmbiguousPath(Vec<ModuleItemId<'db>>),
1395 UseSelfNonMulti,
1396 UseSelfEmptyPath,
1397 UseStarEmptyPath,
1398 GlobalUsesNotSupportedInEdition(Edition),
1399 TraitInTraitMustBeExplicit,
1400 ImplInImplMustBeExplicit,
1401 TraitItemForbiddenInTheTrait,
1402 TraitItemForbiddenInItsImpl,
1403 ImplItemForbiddenInTheImpl,
1404 SuperUsedInRootModule,
1405 SuperUsedInMacroCallTopLevel,
1406 ItemNotVisible(ModuleItemId<'db>, Vec<ModuleId<'db>>),
1407 UnusedImport(UseId<'db>),
1408 RedundantModifier {
1409 current_modifier: SmolStrId<'db>,
1410 previous_modifier: SmolStrId<'db>,
1411 },
1412 ReferenceLocalVariable,
1413 UnexpectedEnumPattern(semantic::TypeId<'db>),
1414 UnexpectedStructPattern(semantic::TypeId<'db>),
1415 UnexpectedTuplePattern(semantic::TypeId<'db>),
1416 UnexpectedFixedSizeArrayPattern(semantic::TypeId<'db>),
1417 WrongNumberOfTupleElements {
1418 expected: usize,
1419 actual: usize,
1420 },
1421 WrongNumberOfFixedSizeArrayElements {
1422 expected: usize,
1423 actual: usize,
1424 },
1425 WrongEnum {
1426 expected_enum: EnumId<'db>,
1427 actual_enum: EnumId<'db>,
1428 },
1429 InvalidCopyTraitImpl(InferenceError<'db>),
1430 InvalidDropTraitImpl(InferenceError<'db>),
1431 InvalidImplItem(SmolStrId<'db>),
1432 MissingItemsInImpl(Vec<SmolStrId<'db>>),
1433 PassPanicAsNopanic {
1434 impl_function_id: ImplFunctionId<'db>,
1435 trait_id: TraitId<'db>,
1436 },
1437 PassConstAsNonConst {
1438 impl_function_id: ImplFunctionId<'db>,
1439 trait_id: TraitId<'db>,
1440 },
1441 PanicableFromNonPanicable,
1442 PanicableExternFunction,
1443 MacroGeneratedCodeParserDiagnostic(ParserDiagnostic<'db>),
1444 PluginDiagnostic(PluginDiagnostic<'db>),
1445 NameDefinedMultipleTimes(SmolStrId<'db>),
1446 NonPrivateUseStar,
1447 SelfGlobalUse,
1448 NamedArgumentsAreNotSupported,
1449 ArgPassedToNegativeImpl,
1450 UnnamedArgumentFollowsNamed,
1451 NamedArgumentMismatch {
1452 expected: SmolStrId<'db>,
1453 found: SmolStrId<'db>,
1454 },
1455 UnsupportedOutsideOfFunction(UnsupportedOutsideOfFunctionFeatureName),
1456 ConstTypeNotVarFree,
1457 UnsupportedConstant,
1458 FailedConstantCalculation,
1459 ConstantCalculationDepthExceeded,
1460 InnerFailedConstantCalculation(Box<SemanticDiagnostic<'db>>, Vec<DiagnosticNote<'db>>),
1461 DivisionByZero,
1462 ExternTypeWithImplGenericsNotSupported,
1463 MissingSemicolon,
1464 TraitMismatch {
1465 expected_trt: semantic::ConcreteTraitId<'db>,
1466 actual_trt: semantic::ConcreteTraitId<'db>,
1467 },
1468 DerefNonRef {
1469 ty: semantic::TypeId<'db>,
1470 },
1471 InternalInferenceError(InferenceError<'db>),
1472 NoImplementationOfIndexOperator {
1473 ty: semantic::TypeId<'db>,
1474 inference_errors: TraitInferenceErrors<'db>,
1475 },
1476 NoImplementationOfTrait {
1477 ty: semantic::TypeId<'db>,
1478 trait_name: SmolStrId<'db>,
1479 inference_errors: TraitInferenceErrors<'db>,
1480 },
1481 CallExpressionRequiresFunction {
1482 ty: semantic::TypeId<'db>,
1483 inference_errors: TraitInferenceErrors<'db>,
1484 },
1485 MultipleImplementationOfIndexOperator(semantic::TypeId<'db>),
1486
1487 UnsupportedInlineArguments,
1488 RedundantInlineAttribute,
1489 InlineAttrForExternFunctionNotAllowed,
1490 InlineAlwaysWithImplGenericArgNotAllowed,
1491 TailExpressionNotAllowedInLoop,
1492 ContinueOnlyAllowedInsideALoop,
1493 BreakOnlyAllowedInsideALoop,
1494 BreakWithValueOnlyAllowedInsideALoop,
1495 ErrorPropagateNotAllowedInsideALoop,
1496 ImplicitPrecedenceAttrForExternFunctionNotAllowed,
1497 RedundantImplicitPrecedenceAttribute,
1498 UnsupportedImplicitPrecedenceArguments,
1499 UnsupportedFeatureAttrArguments,
1500 UnsupportedAllowAttrArguments,
1501 UnsupportedPubArgument,
1502 UnknownStatementAttribute,
1503 InlineMacroNotFound(SmolStrId<'db>),
1504 InlineMacroFailed(SmolStrId<'db>),
1505 InlineMacroNoMatchingRule(SmolStrId<'db>),
1506 MacroCallToNotAMacro(SmolStrId<'db>),
1507 UnknownGenericParam(SmolStrId<'db>),
1508 PositionalGenericAfterNamed,
1509 GenericArgDuplicate(SmolStrId<'db>),
1510 TooManyGenericArguments {
1511 expected: usize,
1512 actual: usize,
1513 },
1514 GenericArgOutOfOrder(SmolStrId<'db>),
1515 CouponForExternFunctionNotAllowed,
1516 CouponArgumentNoModifiers,
1517 CouponsDisabled,
1519 ReprPtrsDisabled,
1521 AssignmentToReprPtrVariable(Vec<DiagnosticNote<'db>>),
1523 FixedSizeArrayTypeNonSingleType,
1524 FixedSizeArrayTypeEmptySize,
1525 FixedSizeArrayNonNumericSize,
1526 FixedSizeArrayNonSingleValue,
1527 FixedSizeArraySizeTooBig,
1528 SelfNotSupportedInContext,
1529 SelfMustBeFirst,
1530 DollarNotSupportedInContext,
1531 UnknownResolverModifier {
1532 modifier: SmolStrId<'db>,
1533 },
1534 EmptyPathAfterResolverModifier,
1535 DerefCycle {
1536 deref_chain: String,
1537 },
1538 CompilerTraitReImplementation {
1539 trait_id: TraitId<'db>,
1540 },
1541 ClosureInGlobalScope,
1542 MaybeMissingColonColon,
1543 CallingShadowedFunction {
1544 shadowed_function_name: SmolStrId<'db>,
1545 },
1546 RefClosureArgument,
1547 RefClosureParam,
1548 MustBeNextToTypeOrTrait {
1549 trait_id: TraitId<'db>,
1550 },
1551 MutableCapturedVariable,
1552 NonTraitTypeConstrained {
1553 identifier: SmolStrId<'db>,
1554 concrete_trait_id: ConcreteTraitId<'db>,
1555 },
1556 DuplicateTypeConstraint {
1557 concrete_trait_type_id: ConcreteTraitTypeId<'db>,
1558 },
1559 TypeConstraintsSyntaxNotEnabled,
1560 PatternMissingArgs(ast::ExprPath<'db>),
1561 UndefinedMacroPlaceholder(SmolStrId<'db>),
1562 UserDefinedInlineMacrosDisabled,
1563 NonNeverLetElseType,
1564 OnlyTypeOrConstParamsInNegImpl,
1565}
1566
1567#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1569pub enum MultiArmExprKind {
1570 If,
1571 Match,
1572 Loop,
1573}
1574
1575impl<'db> SemanticDiagnosticKind<'db> {
1576 pub fn error_code(&self) -> Option<ErrorCode> {
1577 Some(match &self {
1578 Self::UnusedVariable => error_code!(E0001),
1579 Self::CannotCallMethod { .. } => {
1580 error_code!(E0002)
1581 }
1582 Self::MissingMember(_) => error_code!(E0003),
1583 Self::MissingItemsInImpl(_) => error_code!(E0004),
1584 Self::ModuleFileNotFound(_) => error_code!(E0005),
1585 Self::PathNotFound(_) => error_code!(E0006),
1586 Self::NoSuchTypeMember { .. } => error_code!(E0007),
1587 _ => return None,
1588 })
1589 }
1590}
1591
1592#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1594pub enum NotFoundItemType {
1595 Identifier,
1596 Function,
1597 Type,
1598 Trait,
1599 Impl,
1600 Macro,
1601}
1602
1603#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1604pub enum UnsupportedOutsideOfFunctionFeatureName {
1605 ReturnStatement,
1606 ErrorPropagate,
1607}
1608
1609#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, salsa::Update)]
1610pub enum ElementKind {
1611 Constant,
1612 Variable,
1613 Module,
1614 Function,
1615 Type,
1616 Variant,
1617 Trait,
1618 Impl,
1619 Macro,
1620}
1621impl<'db> From<&ResolvedConcreteItem<'db>> for ElementKind {
1622 fn from(val: &ResolvedConcreteItem<'db>) -> Self {
1623 match val {
1624 ResolvedConcreteItem::Constant(_) => ElementKind::Constant,
1625 ResolvedConcreteItem::Module(_) => ElementKind::Module,
1626 ResolvedConcreteItem::Function(_) => ElementKind::Function,
1627 ResolvedConcreteItem::Type(_) => ElementKind::Type,
1628 ResolvedConcreteItem::Variant(_) => ElementKind::Variant,
1629 ResolvedConcreteItem::Trait(_) | ResolvedConcreteItem::SelfTrait(_) => {
1630 ElementKind::Trait
1631 }
1632 ResolvedConcreteItem::Impl(_) => ElementKind::Impl,
1633 ResolvedConcreteItem::Macro(_) => ElementKind::Macro,
1634 }
1635 }
1636}
1637impl<'db> From<&ResolvedGenericItem<'db>> for ElementKind {
1638 fn from(val: &ResolvedGenericItem<'db>) -> Self {
1639 match val {
1640 ResolvedGenericItem::GenericConstant(_)
1641 | ResolvedGenericItem::TraitItem(TraitItemId::Constant(_)) => ElementKind::Constant,
1642 ResolvedGenericItem::Module(_) => ElementKind::Module,
1643 ResolvedGenericItem::GenericFunction(_)
1644 | ResolvedGenericItem::TraitItem(TraitItemId::Function(_)) => ElementKind::Function,
1645 ResolvedGenericItem::GenericType(_)
1646 | ResolvedGenericItem::GenericTypeAlias(_)
1647 | ResolvedGenericItem::TraitItem(TraitItemId::Type(_)) => ElementKind::Type,
1648 ResolvedGenericItem::Variant(_) => ElementKind::Variant,
1649 ResolvedGenericItem::Trait(_) => ElementKind::Trait,
1650 ResolvedGenericItem::Impl(_)
1651 | ResolvedGenericItem::GenericImplAlias(_)
1652 | ResolvedGenericItem::TraitItem(TraitItemId::Impl(_)) => ElementKind::Impl,
1653 ResolvedGenericItem::Variable(_) => ElementKind::Variable,
1654 ResolvedGenericItem::Macro(_) => ElementKind::Macro,
1655 }
1656 }
1657}
1658impl Display for ElementKind {
1659 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1660 let res = match self {
1661 ElementKind::Constant => "constant",
1662 ElementKind::Variable => "variable",
1663 ElementKind::Module => "module",
1664 ElementKind::Function => "function",
1665 ElementKind::Type => "type",
1666 ElementKind::Variant => "variant",
1667 ElementKind::Trait => "trait",
1668 ElementKind::Impl => "impl",
1669 ElementKind::Macro => "macro",
1670 };
1671 write!(f, "{res}")
1672 }
1673}
1674
1675#[derive(Clone, Debug, Eq, Hash, PartialEq, salsa::Update)]
1677pub struct TraitInferenceErrors<'db> {
1678 pub traits_and_errors: Vec<(TraitFunctionId<'db>, InferenceError<'db>)>,
1679}
1680impl<'db> TraitInferenceErrors<'db> {
1681 pub fn is_empty(&self) -> bool {
1683 self.traits_and_errors.is_empty()
1684 }
1685 fn format(&self, db: &dyn Database) -> String {
1687 self.traits_and_errors
1688 .iter()
1689 .map(|(trait_function_id, inference_error)| {
1690 format!(
1691 "Candidate `{}` inference failed with: {}",
1692 trait_function_id.full_path(db),
1693 inference_error.format(db)
1694 )
1695 })
1696 .join("\n")
1697 }
1698}