From 12397ab48ba9e14fbcc1f65954682f764f36e31b Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 28 Jan 2022 21:57:29 +1100 Subject: Report the selection error when possible --- .../src/transform/check_consts/check.rs | 51 +++++++++++++++------- 1 file changed, 36 insertions(+), 15 deletions(-) (limited to 'compiler/rustc_const_eval/src') diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 2fd814c129c..095c8f84f41 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -14,6 +14,7 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, use rustc_middle::ty::{Binder, TraitPredicate, TraitRef}; use rustc_mir_dataflow::{self, Analysis}; use rustc_span::{sym, Span, Symbol}; +use rustc_trait_selection::traits::error_reporting::InferCtxtExt; use rustc_trait_selection::traits::SelectionContext; use std::mem; @@ -808,15 +809,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } let trait_ref = TraitRef::from_method(tcx, trait_id, substs); - let obligation = Obligation::new( - ObligationCause::dummy(), - param_env, - Binder::dummy(TraitPredicate { - trait_ref, - constness: ty::BoundConstness::NotConst, - polarity: ty::ImplPolarity::Positive, - }), - ); + let poly_trait_pred = Binder::dummy(TraitPredicate { + trait_ref, + constness: ty::BoundConstness::ConstIfConst, + polarity: ty::ImplPolarity::Positive, + }); + let obligation = + Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred); let implsrc = tcx.infer_ctxt().enter(|infcx| { let mut selcx = SelectionContext::new(&infcx); @@ -860,15 +859,37 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // #[default_method_body_is_const], and the callee is in the same // trait. let callee_trait = tcx.trait_of_item(callee); - if callee_trait.is_some() { - if tcx.has_attr(caller, sym::default_method_body_is_const) { - if tcx.trait_of_item(caller) == callee_trait { - nonconst_call_permission = true; - } - } + if callee_trait.is_some() + && tcx.has_attr(caller, sym::default_method_body_is_const) + && callee_trait == tcx.trait_of_item(caller) + // Can only call methods when it's `::f`. + && tcx.types.self_param == substs.type_at(0) + { + nonconst_call_permission = true; } if !nonconst_call_permission { + let obligation = Obligation::new( + ObligationCause::dummy_with_span(*fn_span), + param_env, + tcx.mk_predicate( + poly_trait_pred.map_bound(ty::PredicateKind::Trait), + ), + ); + + // improve diagnostics by showing what failed. Our requirements are stricter this time + // as we are going to error again anyways. + tcx.infer_ctxt().enter(|infcx| { + if let Err(e) = implsrc { + infcx.report_selection_error( + obligation.clone(), + &obligation, + &e, + false, + ); + } + }); + self.check_op(ops::FnCallNonConst { caller, callee, -- cgit 1.4.1-3-g733a5