@@ -13,8 +13,11 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
1313use rustc_middle:: ty:: { Binder , TraitPredicate , TraitRef , TypeVisitable } ;
1414use rustc_mir_dataflow:: { self , Analysis } ;
1515use rustc_span:: { sym, Span , Symbol } ;
16- use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
17- use rustc_trait_selection:: traits:: SelectionContext ;
16+ use rustc_trait_selection:: infer:: InferCtxtExt ;
17+ use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt as _;
18+ use rustc_trait_selection:: traits:: {
19+ self , ObligationCauseCode , SelectionContext , TraitEngine , TraitEngineExt ,
20+ } ;
1821
1922use std:: mem;
2023use std:: ops:: Deref ;
@@ -739,6 +742,43 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
739742 selcx. select ( & obligation)
740743 } ) ;
741744
745+ // do a well-formedness check on the trait method being called. This is because typeck only does a
746+ // "non-const" check. This is required for correctness here.
747+ tcx. infer_ctxt ( ) . enter ( |infcx| {
748+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( infcx. tcx ) ;
749+ let predicates = tcx. predicates_of ( callee) . instantiate ( tcx, substs) ;
750+ let hir_id = tcx
751+ . hir ( )
752+ . local_def_id_to_hir_id ( self . body . source . def_id ( ) . expect_local ( ) ) ;
753+ let cause = || {
754+ ObligationCause :: new (
755+ terminator. source_info . span ,
756+ hir_id,
757+ ObligationCauseCode :: ItemObligation ( callee) ,
758+ )
759+ } ;
760+ let normalized = infcx. partially_normalize_associated_types_in (
761+ cause ( ) ,
762+ param_env,
763+ predicates,
764+ ) ;
765+
766+ for p in normalized. obligations {
767+ fulfill_cx. register_predicate_obligation ( & infcx, p) ;
768+ }
769+ for obligation in traits:: predicates_for_generics (
770+ |_, _| cause ( ) ,
771+ self . param_env ,
772+ normalized. value ,
773+ ) {
774+ fulfill_cx. register_predicate_obligation ( & infcx, obligation) ;
775+ }
776+ let errors = fulfill_cx. select_all_or_error ( & infcx) ;
777+ if !errors. is_empty ( ) {
778+ infcx. report_fulfillment_errors ( & errors, None , false ) ;
779+ }
780+ } ) ;
781+
742782 match implsrc {
743783 Ok ( Some ( ImplSource :: Param ( _, ty:: BoundConstness :: ConstIfConst ) ) ) => {
744784 debug ! (
0 commit comments