1use std::{panic::Location, sync::Arc};
2
3use dada_ir_ast::{
4 ast::SpannedBinaryOp,
5 diagnostic::{Diagnostic, Level, Reported},
6 span::Span,
7};
8use serde::Serialize;
9
10use crate::{
11 check::{debug::export, env::Env, predicates::Predicate},
12 ir::{
13 exprs::{SymExpr, SymPlaceExpr},
14 generics::SymWhereClause,
15 indices::InferVarIndex,
16 types::{SymGenericTerm, SymPerm, SymPlace, SymTy, SymTyName},
17 variables::SymVariable,
18 },
19};
20
21use super::{
22 inference::{Direction, InferVarKind},
23 red::{RedPerm, RedTy},
24 to_red::RedTyExt,
25};
26
27pub trait OrElse<'db> {
38 #[track_caller]
40 fn report(&self, env: &mut Env<'db>, because: Because<'db>) -> Reported {
41 let diagnostic = self.or_else(env, because);
42 env.report(diagnostic)
43 }
44
45 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic;
53
54 fn to_arc(&self) -> ArcOrElse<'db>;
59
60 fn compiler_location(&self) -> &'static Location<'static>;
63}
64
65#[derive(Clone)]
67pub struct ArcOrElse<'db> {
68 data: Arc<dyn OrElse<'db> + 'db>,
69}
70
71impl<'db, T> From<Arc<T>> for ArcOrElse<'db>
72where
73 T: OrElse<'db> + 'db,
74{
75 fn from(data: Arc<T>) -> Self {
76 ArcOrElse { data }
77 }
78}
79
80impl<'db> OrElse<'db> for ArcOrElse<'db> {
81 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
82 self.data.or_else(env, because)
83 }
84
85 fn to_arc(&self) -> ArcOrElse<'db> {
86 ArcOrElse::clone(self)
87 }
88
89 fn compiler_location(&self) -> &'static Location<'static> {
90 self.data.compiler_location()
91 }
92}
93
94impl<'db> std::ops::Deref for ArcOrElse<'db> {
95 type Target = dyn OrElse<'db> + 'db;
96
97 fn deref(&self) -> &Self::Target {
98 &*self.data
99 }
100}
101
102impl Serialize for ArcOrElse<'_> {
103 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104 where
105 S: serde::Serializer,
106 {
107 #[derive(Serialize)]
108 struct ErasedOrElse {
109 compiler_location: export::CompilerLocation<'static>,
110 }
111
112 ErasedOrElse {
113 compiler_location: self.compiler_location().into(),
114 }
115 .serialize(serializer)
116 }
117}
118
119pub trait OrElseHelper<'db>: Sized {
120 fn map_because(
127 self,
128 f: impl 'db + Clone + Fn(Because<'db>) -> Because<'db>,
129 ) -> impl OrElse<'db>;
130}
131
132impl<'db> OrElseHelper<'db> for &dyn OrElse<'db> {
133 #[track_caller]
135 fn map_because(
136 self,
137 f: impl 'db + Clone + Fn(Because<'db>) -> Because<'db>,
138 ) -> impl OrElse<'db> {
139 struct MapBecause<F, G>(F, G, &'static Location<'static>);
140
141 impl<'db, F, G> OrElse<'db> for MapBecause<F, G>
142 where
143 F: 'db + Clone + Fn(Because<'db>) -> Because<'db>,
144 G: std::ops::Deref<Target: OrElse<'db>>,
145 {
146 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
147 self.1.or_else(env, (self.0)(because))
148 }
149
150 fn to_arc(&self) -> ArcOrElse<'db> {
151 Arc::new(MapBecause(self.0.clone(), self.1.to_arc(), self.2)).into()
152 }
153
154 fn compiler_location(&self) -> &'static Location<'static> {
155 self.2
156 }
157 }
158
159 MapBecause(f, self, Location::caller())
160 }
161}
162
163pub enum Because<'db> {
165 JustSo,
167
168 VarNotDeclaredToBe(SymVariable<'db>, Predicate),
170
171 NeverIsNotCopy,
173
174 NoWhereClause(SymVariable<'db>, Predicate),
176
177 StructsAreNotLent(SymTyName<'db>),
180
181 PermIsNot(SymPerm<'db>, Predicate),
183
184 LeasedFromCopyIsCopy(Vec<SymPlace<'db>>),
186
187 UniversalMismatch(SymVariable<'db>, SymVariable<'db>),
189
190 NameMismatch(SymTyName<'db>, SymTyName<'db>),
192
193 InferredPermBound(Direction, RedPerm<'db>, ArcOrElse<'db>),
196
197 InferredLowerBound(RedTy<'db>, ArcOrElse<'db>),
200
201 UnconstrainedInfer(InferVarIndex),
203}
204
205impl<'db> Because<'db> {
206 pub fn annotate_diagnostic(self, env: &mut Env<'db>, diagnostic: Diagnostic) -> Diagnostic {
207 let db = env.db();
208 let span = diagnostic.span.into_span(db);
209 if let Some(child) = self.to_annotation(env, span) {
210 diagnostic.child(child)
211 } else {
212 diagnostic
213 }
214 }
215
216 fn to_annotation(&self, env: &mut Env<'db>, span: Span<'db>) -> Option<Diagnostic> {
217 let db = env.db();
218 match self {
219 Because::JustSo => None,
220 Because::VarNotDeclaredToBe(v, predicate) => Some(Diagnostic::info(
221 db,
222 span,
223 format!(
224 "to conclude that `{v}` is `{predicate}`, I would need you to add a declaration"
225 ),
226 )),
227 Because::NeverIsNotCopy => Some(Diagnostic::info(
228 db,
229 span,
230 "the never type (`!`) is not considered `copy`",
231 )),
232 Because::LeasedFromCopyIsCopy(places) => {
233 if places.len() == 1 {
234 Some(Diagnostic::info(
235 db,
236 span,
237 format!(
238 "`{place}` is `copy`, so leasing from `{place}` yields a `copy` permission",
239 place = places[0]
240 ),
241 ))
242 } else {
243 Some(Diagnostic::info(
244 db,
245 span,
246 format!(
247 "{places} are all `copy`, so leasing from them yields a `copy` permission",
248 places = anded_list(places),
249 ),
250 ))
251 }
252 }
253 Because::UniversalMismatch(v1, v2) => Some(Diagnostic::info(
254 db,
255 span,
256 format!("I cannot know whether `{v1}` and `{v2}` are the same"),
257 )),
258 Because::NameMismatch(n1, n2) => Some(Diagnostic::info(
259 db,
260 span,
261 format!("`{n1}` and `{n2}` are distinct types"),
262 )),
263 Because::InferredPermBound(direction, red_perm, or_else) => {
264 let or_else_diagnostic = or_else.or_else(env, Because::JustSo);
265 Some(
266 Diagnostic::info(
267 db,
268 span,
269 format!(
270 "I inferred that the perm must be {assignable_from_or_to} `{bound}` or else this error will occur",
271 assignable_from_or_to = match direction {
272 Direction::FromBelow => "assignable from",
273 Direction::FromAbove => "assignable to",
274 },
275 bound = format!("{red_perm:?}"), ),
277 )
278 .child(or_else_diagnostic),
279 )
280 }
281 Because::InferredLowerBound(red_ty, or_else) => {
282 let or_else_diagnostic = or_else.or_else(env, Because::JustSo);
283 Some(Diagnostic::info(
284 db,
285 span,
286 format!(
287 "I inferred that the type `{red_ty}` is required because otherwise it would cause this error",
288 red_ty = red_ty.display(env),
289 ),
290 )
291 .child(or_else_diagnostic))
292 }
293 Because::UnconstrainedInfer(infer) => Some(Diagnostic::info(
294 db,
295 env.infer_var_span(*infer),
296 "this error might well be bogus, I just can't infer the type here".to_string(),
297 )),
298 Because::NoWhereClause(var, predicate) => Some(Diagnostic::info(
299 db,
300 span,
301 format!("the variable `{var}` needs a where-clause to be considered `{predicate}`"),
302 )),
303 Because::StructsAreNotLent(s) => Some(Diagnostic::info(
304 db,
305 span,
306 format!("the struct type `{s}` is never considered `lent`"),
307 )),
308 Because::PermIsNot(perm, predicate) => Some(Diagnostic::info(
309 db,
310 span,
311 format!("the permission `{perm}` is not considered `{predicate}`"),
312 )),
313 }
314 }
315}
316
317fn anded_list<T>(v: &[T]) -> String
318where
319 T: std::fmt::Display,
320{
321 use std::fmt::Write;
322
323 let mut s = String::new();
324 let Some((last, prefix)) = v.split_last() else {
325 return s;
326 };
327
328 for p in prefix {
329 write!(s, "{p}, ").unwrap();
330 }
331
332 write!(s, "and {last}").unwrap();
333 s
334}
335
336#[derive(Copy, Clone, Debug)]
340pub struct BadSubtermError<'db> {
341 span: Span<'db>,
342 lower: SymGenericTerm<'db>,
343 upper: SymGenericTerm<'db>,
344 compiler_location: &'static Location<'static>,
345}
346
347impl<'db> BadSubtermError<'db> {
348 #[track_caller]
349 pub fn new(
350 span: Span<'db>,
351 lower: impl Into<SymGenericTerm<'db>>,
352 upper: impl Into<SymGenericTerm<'db>>,
353 ) -> Self {
354 Self {
355 span,
356 lower: lower.into(),
357 upper: upper.into(),
358 compiler_location: Location::caller(),
359 }
360 }
361}
362
363impl<'db> OrElse<'db> for BadSubtermError<'db> {
364 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
365 let db = env.db();
366 let Self {
367 span,
368 lower,
369 upper,
370 compiler_location: _,
371 } = *self;
372 because.annotate_diagnostic(
373 env,
374 Diagnostic::error(db, span, "subtype expected".to_string()).label(
375 db,
376 Level::Error,
377 span,
378 format!("expected `{upper}`, found `{lower}`"),
379 ),
380 )
381 }
382
383 fn to_arc(&self) -> ArcOrElse<'db> {
384 Arc::new(*self).into()
385 }
386
387 fn compiler_location(&self) -> &'static Location<'static> {
388 self.compiler_location
389 }
390}
391
392#[derive(Copy, Clone, Debug)]
396pub struct WhereClauseError<'db> {
397 span: Span<'db>,
398 where_clause: SymWhereClause<'db>,
399 compiler_location: &'static Location<'static>,
400}
401
402impl<'db> WhereClauseError<'db> {
403 #[track_caller]
404 pub fn new(span: Span<'db>, where_clause: SymWhereClause<'db>) -> Self {
405 Self {
406 span,
407 where_clause,
408 compiler_location: Location::caller(),
409 }
410 }
411}
412
413impl<'db> OrElse<'db> for WhereClauseError<'db> {
414 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
415 let db = env.db();
416 let Self {
417 span,
418 where_clause,
419 compiler_location: _,
420 } = *self;
421 because.annotate_diagnostic(
422 env,
423 Diagnostic::error(
424 db,
425 span,
426 "where clause on function not satisfied".to_string(),
427 )
428 .label(
429 db,
430 Level::Error,
431 span,
432 format!("expected `{where_clause:?}`"),
433 ),
434 )
435 }
436
437 fn to_arc(&self) -> ArcOrElse<'db> {
438 Arc::new(*self).into()
439 }
440
441 fn compiler_location(&self) -> &'static Location<'static> {
442 self.compiler_location
443 }
444}
445
446#[derive(Copy, Clone, Debug)]
447pub struct InvalidInitializerType<'db> {
448 variable: SymVariable<'db>,
449 variable_span: Span<'db>,
450 variable_ty: SymTy<'db>,
451 initializer: SymExpr<'db>,
452 compiler_location: &'static Location<'static>,
453}
454
455impl<'db> InvalidInitializerType<'db> {
456 #[track_caller]
457 pub fn new(
458 variable: SymVariable<'db>,
459 variable_span: Span<'db>,
460 variable_ty: SymTy<'db>,
461 initializer: SymExpr<'db>,
462 ) -> Self {
463 Self {
464 variable,
465 variable_span,
466 variable_ty,
467 initializer,
468 compiler_location: Location::caller(),
469 }
470 }
471}
472
473impl<'db> OrElse<'db> for InvalidInitializerType<'db> {
474 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
475 let db = env.db();
476 let initializer_ty = self.initializer.ty(db);
477 because.annotate_diagnostic(
478 env,
479 Diagnostic::error(
480 db,
481 self.initializer.span(db),
482 format!(
483 "variable `{v}` initialized with value of wrong type",
484 v = self.variable
485 ),
486 )
487 .label(
488 db,
489 Level::Error,
490 self.initializer.span(db),
491 format!("initializer has type `{initializer_ty}`"),
492 )
493 .label(
494 db,
495 Level::Info,
496 self.variable_span,
497 format!(
498 "`{v}` has type `{variable_ty}`",
499 v = self.variable,
500 variable_ty = self.variable_ty
501 ),
502 ),
503 )
504 }
505
506 fn to_arc(&self) -> ArcOrElse<'db> {
507 Arc::new(*self).into()
508 }
509
510 fn compiler_location(&self) -> &'static Location<'static> {
511 self.compiler_location
512 }
513}
514
515#[derive(Copy, Clone, Debug)]
516pub struct InvalidAssignmentType<'db> {
517 lhs: SymPlaceExpr<'db>,
518 rhs: SymExpr<'db>,
519 compiler_location: &'static Location<'static>,
520}
521
522impl<'db> InvalidAssignmentType<'db> {
523 #[track_caller]
524 pub fn new(lhs: SymPlaceExpr<'db>, rhs: SymExpr<'db>) -> Self {
525 Self {
526 lhs,
527 rhs,
528 compiler_location: Location::caller(),
529 }
530 }
531}
532
533impl<'db> OrElse<'db> for InvalidAssignmentType<'db> {
534 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
535 let db = env.db();
536 let lhs_ty = self.lhs.ty(db);
537 let rhs_ty = self.rhs.ty(db);
538 because.annotate_diagnostic(
539 env,
540 Diagnostic::error(
541 db,
542 self.rhs.span(db),
543 "wrong type in assignment".to_string(),
544 )
545 .label(
546 db,
547 Level::Error,
548 self.rhs.span(db),
549 format!("this expression has type `{rhs_ty}`"),
550 )
551 .label(
552 db,
553 Level::Info,
554 self.lhs.span(db),
555 format!("I expected something assignable to this, which has type `{lhs_ty}`",),
556 ),
557 )
558 }
559
560 fn to_arc(&self) -> ArcOrElse<'db> {
561 Arc::new(*self).into()
562 }
563
564 fn compiler_location(&self) -> &'static Location<'static> {
565 self.compiler_location
566 }
567}
568
569#[derive(Copy, Clone, Debug)]
570pub struct InvalidReturnValue<'db> {
571 value: SymExpr<'db>,
572 return_ty: SymTy<'db>,
573 compiler_location: &'static Location<'static>,
574}
575
576impl<'db> InvalidReturnValue<'db> {
577 #[track_caller]
578 pub fn new(value: SymExpr<'db>, return_ty: SymTy<'db>) -> Self {
579 Self {
580 value,
581 return_ty,
582 compiler_location: Location::caller(),
583 }
584 }
585}
586
587impl<'db> OrElse<'db> for InvalidReturnValue<'db> {
588 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
589 let db = env.db();
590 let value_ty = self.value.ty(db);
591 because.annotate_diagnostic(
592 env,
593 Diagnostic::error(db, self.value.span(db), "invalid return value".to_string())
594 .label(
595 db,
596 Level::Error,
597 self.value.span(db),
598 format!(
599 "I expected a value of the return type, but this has type `{value_ty}`"
600 ),
601 )
602 .label(
603 db,
604 Level::Info,
605 self.value.span(db),
607 format!(
608 "the return type is declared to be `{return_ty}`",
609 return_ty = self.return_ty,
610 ),
611 ),
612 )
613 }
614
615 fn to_arc(&self) -> ArcOrElse<'db> {
616 Arc::new(*self).into()
617 }
618
619 fn compiler_location(&self) -> &'static Location<'static> {
620 self.compiler_location
621 }
622}
623
624#[derive(Copy, Clone, Debug)]
625pub struct AwaitNonFuture<'db> {
626 await_span: Span<'db>,
627 future_expr: SymExpr<'db>,
628 compiler_location: &'static Location<'static>,
629}
630
631impl<'db> AwaitNonFuture<'db> {
632 #[track_caller]
633 pub fn new(await_span: Span<'db>, future_expr: SymExpr<'db>) -> Self {
634 Self {
635 await_span,
636 future_expr,
637 compiler_location: Location::caller(),
638 }
639 }
640}
641
642impl<'db> OrElse<'db> for AwaitNonFuture<'db> {
643 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
644 let Self {
645 await_span,
646 future_expr,
647 compiler_location: _,
648 } = *self;
649 let db = env.db();
650 because.annotate_diagnostic(
651 env,
652 Diagnostic::error(
653 db,
654 await_span,
655 "`await` can only be used on futures".to_string(),
656 )
657 .label(
658 db,
659 Level::Error,
660 await_span,
661 "I expect `await` to be applied to a future",
662 )
663 .label(
664 db,
665 Level::Info,
666 future_expr.span(db),
667 format!(
668 "this expression has type `{future_ty}`",
669 future_ty = future_expr.ty(db),
670 ),
671 ),
672 )
673 }
674
675 fn to_arc(&self) -> ArcOrElse<'db> {
676 Arc::new(*self).into()
677 }
678
679 fn compiler_location(&self) -> &'static Location<'static> {
680 self.compiler_location
681 }
682}
683
684#[derive(Copy, Clone, Debug)]
685pub struct BooleanTypeRequired<'db> {
686 expr: SymExpr<'db>,
687 compiler_location: &'static Location<'static>,
688}
689
690impl<'db> BooleanTypeRequired<'db> {
691 #[track_caller]
692 pub fn new(expr: SymExpr<'db>) -> Self {
693 Self {
694 expr,
695 compiler_location: Location::caller(),
696 }
697 }
698}
699
700impl<'db> OrElse<'db> for BooleanTypeRequired<'db> {
701 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
702 let db = env.db();
703 because.annotate_diagnostic(
704 env,
705 Diagnostic::error(
706 db,
707 self.expr.span(db),
708 "boolean expression required".to_string(),
709 )
710 .label(
711 db,
712 Level::Error,
713 self.expr.span(db),
714 format!(
715 "I expected this expression to have a boolean type, but it has the type `{}`",
716 self.expr.ty(db)
717 ),
718 ),
719 )
720 }
721
722 fn to_arc(&self) -> ArcOrElse<'db> {
723 Arc::new(*self).into()
724 }
725
726 fn compiler_location(&self) -> &'static Location<'static> {
727 self.compiler_location
728 }
729}
730
731#[derive(Copy, Clone, Debug)]
732pub struct NumericTypeExpected<'db> {
733 expr: SymExpr<'db>,
734 ty: SymTy<'db>,
735 compiler_location: &'static Location<'static>,
736}
737
738impl<'db> NumericTypeExpected<'db> {
739 #[track_caller]
740 pub fn new(expr: SymExpr<'db>, ty: SymTy<'db>) -> Self {
741 Self {
742 expr,
743 ty,
744 compiler_location: Location::caller(),
745 }
746 }
747}
748
749impl<'db> OrElse<'db> for NumericTypeExpected<'db> {
750 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
751 let db = env.db();
752 because.annotate_diagnostic(
753 env,
754 Diagnostic::error(db, self.expr.span(db), "numeric type expected").label(
755 db,
756 Level::Error,
757 self.expr.span(db),
758 format!("I expected a numeric type but I found `{}`", self.ty),
759 ),
760 )
761 }
762
763 fn to_arc(&self) -> ArcOrElse<'db> {
764 Arc::new(*self).into()
765 }
766
767 fn compiler_location(&self) -> &'static Location<'static> {
768 self.compiler_location
769 }
770}
771
772#[derive(Copy, Clone, Debug)]
773pub struct OperatorRequiresNumericType<'db> {
774 op: SpannedBinaryOp<'db>,
775 expr: SymExpr<'db>,
776 compiler_location: &'static Location<'static>,
777}
778
779impl<'db> OperatorRequiresNumericType<'db> {
780 #[track_caller]
781 pub fn new(op: SpannedBinaryOp<'db>, expr: SymExpr<'db>) -> Self {
782 Self {
783 op,
784 expr,
785 compiler_location: Location::caller(),
786 }
787 }
788}
789
790impl<'db> OrElse<'db> for OperatorRequiresNumericType<'db> {
791 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
792 let db = env.db();
793 let Self {
794 op: SpannedBinaryOp { span: op_span, op },
795 expr,
796 compiler_location: _,
797 } = *self;
798
799 because.annotate_diagnostic(
800 env,
801 Diagnostic::error(db, expr.span(db), "numeric type expected")
802 .label(
803 db,
804 Level::Error,
805 expr.span(db),
806 format!(
807 "I expected this to have a numeric type but it had the type `{}`",
808 expr.ty(db)
809 ),
810 )
811 .label(
812 db,
813 Level::Info,
814 op_span,
815 format!("the operator `{op}` requires numeric arguments"),
816 ),
817 )
818 }
819
820 fn to_arc(&self) -> ArcOrElse<'db> {
821 Arc::new(*self).into()
822 }
823
824 fn compiler_location(&self) -> &'static Location<'static> {
825 self.compiler_location
826 }
827}
828
829#[derive(Copy, Clone, Debug)]
830pub struct OperatorArgumentsMustHaveSameType<'db> {
831 op: SpannedBinaryOp<'db>,
832 lhs: SymExpr<'db>,
833 rhs: SymExpr<'db>,
834 compiler_location: &'static Location<'static>,
835}
836
837impl<'db> OperatorArgumentsMustHaveSameType<'db> {
838 #[track_caller]
839 pub fn new(op: SpannedBinaryOp<'db>, lhs: SymExpr<'db>, rhs: SymExpr<'db>) -> Self {
840 Self {
841 op,
842 lhs,
843 rhs,
844 compiler_location: Location::caller(),
845 }
846 }
847}
848
849impl<'db> OrElse<'db> for OperatorArgumentsMustHaveSameType<'db> {
850 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
851 let db = env.db();
852 let Self {
853 op: SpannedBinaryOp { span: op_span, op },
854 lhs,
855 rhs,
856 compiler_location: _,
857 } = *self;
858
859 because.annotate_diagnostic(
860 env,
861 Diagnostic::error(db, op_span, "same types expected")
862 .label(
863 db,
864 Level::Error,
865 op_span,
866 format!("I expected both arguments to `{op}` to have the same type",),
867 )
868 .label(
869 db,
870 Level::Info,
871 lhs.span(db),
872 format!("has type `{}`", lhs.ty(db)),
873 )
874 .label(
875 db,
876 Level::Info,
877 rhs.span(db),
878 format!("has type `{}`", rhs.ty(db)),
879 ),
880 )
881 }
882
883 fn to_arc(&self) -> ArcOrElse<'db> {
884 Arc::new(*self).into()
885 }
886
887 fn compiler_location(&self) -> &'static Location<'static> {
888 self.compiler_location
889 }
890}
891
892#[derive(Copy, Clone, Debug)]
893pub struct InferenceFallback<'db> {
894 span: Span<'db>,
895 kind: InferVarKind,
896 term: SymGenericTerm<'db>,
897 compiler_location: &'static Location<'static>,
898}
899
900impl<'db> InferenceFallback<'db> {
901 #[track_caller]
902 pub fn new(span: Span<'db>, kind: InferVarKind, term: impl Into<SymGenericTerm<'db>>) -> Self {
903 Self {
904 span,
905 kind,
906 term: term.into(),
907 compiler_location: Location::caller(),
908 }
909 }
910}
911
912impl<'db> OrElse<'db> for InferenceFallback<'db> {
913 fn or_else(&self, env: &mut Env<'db>, because: Because<'db>) -> Diagnostic {
914 let db = env.db();
915 let Self {
916 span,
917 kind,
918 term,
919 compiler_location: _,
920 } = *self;
921
922 because.annotate_diagnostic(
923 env,
924 Diagnostic::error(db, span, "unconstrained inference variable").label(
925 db,
926 Level::Error,
927 span,
928 format!("I resolved this {kind} to {term}",),
929 ),
930 )
931 }
932
933 fn to_arc(&self) -> ArcOrElse<'db> {
934 Arc::new(*self).into()
935 }
936
937 fn compiler_location(&self) -> &'static Location<'static> {
938 self.compiler_location
939 }
940}