diff options
| author | bors <bors@rust-lang.org> | 2022-09-22 04:22:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-09-22 04:22:24 +0000 |
| commit | 7a8636c843bd24038fe1d1f69b4a8e4b0ea55d4e (patch) | |
| tree | 242508adbaeccdb47f57c20a90717945a433130a /compiler/rustc_const_eval/src/transform | |
| parent | 626b02a8f97a9e35a647aa18fcdb67cbcb3b09c8 (diff) | |
| parent | 898c76cd8257ffd91e9de9714215ece477e1065b (diff) | |
| download | rust-7a8636c843bd24038fe1d1f69b4a8e4b0ea55d4e.tar.gz rust-7a8636c843bd24038fe1d1f69b4a8e4b0ea55d4e.zip | |
Auto merge of #100982 - fee1-dead-contrib:const-impl-requires-const-trait, r=oli-obk
Require `#[const_trait]` on `Trait` for `impl const Trait` r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_const_eval/src/transform')
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/check.rs | 44 |
1 files changed, 42 insertions, 2 deletions
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 a8f6507d594..fb35399fa3a 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -13,8 +13,11 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeVisitable}; 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 rustc_trait_selection::infer::InferCtxtExt; +use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; +use rustc_trait_selection::traits::{ + self, ObligationCauseCode, SelectionContext, TraitEngine, TraitEngineExt, +}; use std::mem; use std::ops::Deref; @@ -739,6 +742,43 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { selcx.select(&obligation) }); + // do a well-formedness check on the trait method being called. This is because typeck only does a + // "non-const" check. This is required for correctness here. + tcx.infer_ctxt().enter(|infcx| { + let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx); + let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); + let hir_id = tcx + .hir() + .local_def_id_to_hir_id(self.body.source.def_id().expect_local()); + let cause = || { + ObligationCause::new( + terminator.source_info.span, + hir_id, + ObligationCauseCode::ItemObligation(callee), + ) + }; + let normalized = infcx.partially_normalize_associated_types_in( + cause(), + param_env, + predicates, + ); + + for p in normalized.obligations { + fulfill_cx.register_predicate_obligation(&infcx, p); + } + for obligation in traits::predicates_for_generics( + |_, _| cause(), + self.param_env, + normalized.value, + ) { + fulfill_cx.register_predicate_obligation(&infcx, obligation); + } + let errors = fulfill_cx.select_all_or_error(&infcx); + if !errors.is_empty() { + infcx.report_fulfillment_errors(&errors, None, false); + } + }); + match implsrc { Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => { debug!( |
