@@ -13,8 +13,11 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
13
13
use rustc_middle:: ty:: { Binder , TraitPredicate , TraitRef , TypeVisitable } ;
14
14
use rustc_mir_dataflow:: { self , Analysis } ;
15
15
use 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
+ } ;
18
21
19
22
use std:: mem;
20
23
use std:: ops:: Deref ;
@@ -739,6 +742,43 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
739
742
selcx. select ( & obligation)
740
743
} ) ;
741
744
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
+
742
782
match implsrc {
743
783
Ok ( Some ( ImplSource :: Param ( _, ty:: BoundConstness :: ConstIfConst ) ) ) => {
744
784
debug ! (
0 commit comments