about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/transform
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-22 04:22:24 +0000
committerbors <bors@rust-lang.org>2022-09-22 04:22:24 +0000
commit7a8636c843bd24038fe1d1f69b4a8e4b0ea55d4e (patch)
tree242508adbaeccdb47f57c20a90717945a433130a /compiler/rustc_const_eval/src/transform
parent626b02a8f97a9e35a647aa18fcdb67cbcb3b09c8 (diff)
parent898c76cd8257ffd91e9de9714215ece477e1065b (diff)
downloadrust-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.rs44
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!(