13
13
//! - For every static, collect initializer and drop functions.
14
14
//!
15
15
//! We have kept this module agnostic of any Kani code in case we can contribute this back to rustc.
16
+ use rustc_span:: ErrorGuaranteed ;
16
17
use tracing:: { debug, debug_span, trace, warn} ;
17
18
18
19
use rustc_data_structures:: fingerprint:: Fingerprint ;
@@ -26,6 +27,7 @@ use rustc_middle::mir::mono::MonoItem;
26
27
use rustc_middle:: mir:: visit:: Visitor as MirVisitor ;
27
28
use rustc_middle:: mir:: {
28
29
Body , CastKind , Constant , ConstantKind , Location , Rvalue , Terminator , TerminatorKind ,
30
+ UnevaluatedConst ,
29
31
} ;
30
32
use rustc_middle:: span_bug;
31
33
use rustc_middle:: ty:: adjustment:: PointerCoercion ;
@@ -458,7 +460,23 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
458
460
// The `monomorphize` call should have evaluated that constant already.
459
461
Ok ( const_val) => const_val,
460
462
Err ( ErrorHandled :: TooGeneric ( span) ) => {
461
- span_bug ! ( span, "Unexpected polymorphic constant: {:?}" , literal)
463
+ if graceful_const_resolution_err (
464
+ self . tcx ,
465
+ & un_eval,
466
+ span,
467
+ self . instance . def_id ( ) ,
468
+ )
469
+ . is_some ( )
470
+ {
471
+ return ;
472
+ } else {
473
+ span_bug ! (
474
+ span,
475
+ "Unexpected polymorphic constant: {:?} {:?}" ,
476
+ literal,
477
+ constant. literal
478
+ )
479
+ }
462
480
}
463
481
Err ( error) => {
464
482
warn ! ( ?error, "Error already reported" ) ;
@@ -494,6 +512,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
494
512
// implement the same traits as those in the
495
513
// original function/method. A trait mismatch shows
496
514
// up here, when we try to resolve a trait method
515
+
516
+ // FIXME: This assumes the type resolving the
517
+ // trait is the first argument, but that isn't
518
+ // necessarily true. It could be any argument or
519
+ // even the return type, for instance for a
520
+ // trait like `FromIterator`.
497
521
let generic_ty = outer_args[ 0 ] . ty ( self . body , tcx) . peel_refs ( ) ;
498
522
let receiver_ty = tcx. subst_and_normalize_erasing_regions (
499
523
substs,
@@ -508,7 +532,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
508
532
"`{receiver_ty}` doesn't implement \
509
533
`{trait_}`. The function `{caller}` \
510
534
cannot be stubbed by `{}` due to \
511
- generic bounds not being met.",
535
+ generic bounds not being met. Callee: {callee} ",
512
536
tcx. def_path_str( stub)
513
537
) ,
514
538
) ;
@@ -555,6 +579,36 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
555
579
}
556
580
}
557
581
582
+ /// Try to construct a nice error message when const evaluation fails.
583
+ ///
584
+ /// This function handles the `Trt::CNST` case where there is one trait (`Trt`)
585
+ /// which defined a constant `CNST` that we failed to resolve. As such we expect
586
+ /// that the trait can be resolved from the constant and that only one generic
587
+ /// parameter, the instantiation of `Trt`, is present.
588
+ ///
589
+ /// If these expectations are not met we return `None`. We do not know in what
590
+ /// situation that would be the case and if they are even possible.
591
+ fn graceful_const_resolution_err < ' tcx > (
592
+ tcx : TyCtxt < ' tcx > ,
593
+ mono_const : & UnevaluatedConst < ' tcx > ,
594
+ span : rustc_span:: Span ,
595
+ parent_fn : DefId ,
596
+ ) -> Option < ErrorGuaranteed > {
597
+ let implementor = match mono_const. args . as_slice ( ) {
598
+ [ one] => one. as_type ( ) ,
599
+ _ => None ,
600
+ } ?;
601
+ let trait_ = tcx. trait_of_item ( mono_const. def ) ?;
602
+ let msg = format ! (
603
+ "Type `{implementor}` does not implement trait `{}`. \
604
+ This is likely because `{}` is used as a stub but its \
605
+ generic bounds are not being met.",
606
+ tcx. def_path_str( trait_) ,
607
+ tcx. def_path_str( parent_fn)
608
+ ) ;
609
+ Some ( tcx. sess . span_err ( span, msg) )
610
+ }
611
+
558
612
/// Convert a `MonoItem` into a stable `Fingerprint` which can be used as a stable hash across
559
613
/// compilation sessions. This allow us to provide a stable deterministic order to codegen.
560
614
fn to_fingerprint ( tcx : TyCtxt , item : & MonoItem ) -> Fingerprint {
0 commit comments