1313//! - For every static, collect initializer and drop functions.
1414//!
1515//! We have kept this module agnostic of any Kani code in case we can contribute this back to rustc.
16+ use rustc_span:: ErrorGuaranteed ;
1617use tracing:: { debug, debug_span, trace, warn} ;
1718
1819use rustc_data_structures:: fingerprint:: Fingerprint ;
@@ -26,6 +27,7 @@ use rustc_middle::mir::mono::MonoItem;
2627use rustc_middle:: mir:: visit:: Visitor as MirVisitor ;
2728use rustc_middle:: mir:: {
2829 Body , CastKind , Constant , ConstantKind , Location , Rvalue , Terminator , TerminatorKind ,
30+ UnevaluatedConst ,
2931} ;
3032use rustc_middle:: span_bug;
3133use rustc_middle:: ty:: adjustment:: PointerCoercion ;
@@ -458,7 +460,23 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
458460 // The `monomorphize` call should have evaluated that constant already.
459461 Ok ( const_val) => const_val,
460462 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+ }
462480 }
463481 Err ( error) => {
464482 warn ! ( ?error, "Error already reported" ) ;
@@ -494,6 +512,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
494512 // implement the same traits as those in the
495513 // original function/method. A trait mismatch shows
496514 // 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`.
497521 let generic_ty = outer_args[ 0 ] . ty ( self . body , tcx) . peel_refs ( ) ;
498522 let receiver_ty = tcx. subst_and_normalize_erasing_regions (
499523 substs,
@@ -508,7 +532,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
508532 "`{receiver_ty}` doesn't implement \
509533 `{trait_}`. The function `{caller}` \
510534 cannot be stubbed by `{}` due to \
511- generic bounds not being met.",
535+ generic bounds not being met. Callee: {callee} ",
512536 tcx. def_path_str( stub)
513537 ) ,
514538 ) ;
@@ -555,6 +579,36 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MonoItemsFnCollector<'a, 'tcx> {
555579 }
556580}
557581
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+
558612/// Convert a `MonoItem` into a stable `Fingerprint` which can be used as a stable hash across
559613/// compilation sessions. This allow us to provide a stable deterministic order to codegen.
560614fn to_fingerprint ( tcx : TyCtxt , item : & MonoItem ) -> Fingerprint {
0 commit comments