@@ -14,6 +14,7 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
14
14
use rustc_middle:: ty:: { Binder , TraitPredicate , TraitRef } ;
15
15
use rustc_mir_dataflow:: { self , Analysis } ;
16
16
use rustc_span:: { sym, Span , Symbol } ;
17
+ use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
17
18
use rustc_trait_selection:: traits:: SelectionContext ;
18
19
19
20
use std:: mem;
@@ -806,15 +807,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
806
807
}
807
808
808
809
let trait_ref = TraitRef :: from_method ( tcx, trait_id, substs) ;
809
- let obligation = Obligation :: new (
810
- ObligationCause :: dummy ( ) ,
811
- param_env,
812
- Binder :: dummy ( TraitPredicate {
813
- trait_ref,
814
- constness : ty:: BoundConstness :: NotConst ,
815
- polarity : ty:: ImplPolarity :: Positive ,
816
- } ) ,
817
- ) ;
810
+ let poly_trait_pred = Binder :: dummy ( TraitPredicate {
811
+ trait_ref,
812
+ constness : ty:: BoundConstness :: ConstIfConst ,
813
+ polarity : ty:: ImplPolarity :: Positive ,
814
+ } ) ;
815
+ let obligation =
816
+ Obligation :: new ( ObligationCause :: dummy ( ) , param_env, poly_trait_pred) ;
818
817
819
818
let implsrc = tcx. infer_ctxt ( ) . enter ( |infcx| {
820
819
let mut selcx = SelectionContext :: new ( & infcx) ;
@@ -858,15 +857,37 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
858
857
// #[default_method_body_is_const], and the callee is in the same
859
858
// trait.
860
859
let callee_trait = tcx. trait_of_item ( callee) ;
861
- if callee_trait. is_some ( ) {
862
- if tcx. has_attr ( caller, sym:: default_method_body_is_const) {
863
- if tcx. trait_of_item ( caller) == callee_trait {
864
- nonconst_call_permission = true ;
865
- }
866
- }
860
+ if callee_trait. is_some ( )
861
+ && tcx. has_attr ( caller, sym:: default_method_body_is_const)
862
+ && callee_trait == tcx. trait_of_item ( caller)
863
+ // Can only call methods when it's `<Self as TheTrait>::f`.
864
+ && tcx. types . self_param == substs. type_at ( 0 )
865
+ {
866
+ nonconst_call_permission = true ;
867
867
}
868
868
869
869
if !nonconst_call_permission {
870
+ let obligation = Obligation :: new (
871
+ ObligationCause :: dummy_with_span ( * fn_span) ,
872
+ param_env,
873
+ tcx. mk_predicate (
874
+ poly_trait_pred. map_bound ( ty:: PredicateKind :: Trait ) ,
875
+ ) ,
876
+ ) ;
877
+
878
+ // improve diagnostics by showing what failed. Our requirements are stricter this time
879
+ // as we are going to error again anyways.
880
+ tcx. infer_ctxt ( ) . enter ( |infcx| {
881
+ if let Err ( e) = implsrc {
882
+ infcx. report_selection_error (
883
+ obligation. clone ( ) ,
884
+ & obligation,
885
+ & e,
886
+ false ,
887
+ ) ;
888
+ }
889
+ } ) ;
890
+
870
891
self . check_op ( ops:: FnCallNonConst {
871
892
caller,
872
893
callee,
0 commit comments