diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2022-09-10 06:37:26 +0000 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2022-09-16 11:48:43 +0800 |
| commit | f8813cf10eea79f7703e716b6c050e818220670a (patch) | |
| tree | 3784e8db8807e9cd46581ed9a494b41d0f38f5ea /compiler/rustc_const_eval/src/transform | |
| parent | 1bcc26a6b135fb934bf5f91d03d525f204323829 (diff) | |
| download | rust-f8813cf10eea79f7703e716b6c050e818220670a.tar.gz rust-f8813cf10eea79f7703e716b6c050e818220670a.zip | |
do const trait method bounds check later in rustc_const_eval
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 7e15858c8c1..329d1033abf 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; @@ -738,6 +741,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!( |
