diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
commit | 94a0819fe3a0d679c3042a77bfe6a2afc505daea (patch) | |
tree | 2b827afe6a05f3538db3f7803a88c4587fe85648 /compiler/rustc_const_eval/src/transform/check_consts/check.rs | |
parent | Adding upstream version 1.64.0+dfsg1. (diff) | |
download | rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.tar.xz rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.zip |
Adding upstream version 1.66.0+dfsg1.upstream/1.66.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/check.rs | 89 |
1 files changed, 68 insertions, 21 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 0adb88a18..22a61774e 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::TypeErrCtxtExt as _; +use rustc_trait_selection::traits::{ + self, ObligationCauseCode, SelectionContext, TraitEngine, TraitEngineExt, +}; use std::mem; use std::ops::Deref; @@ -135,7 +138,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { // qualifs for the return type. let return_block = ccx .body - .basic_blocks() + .basic_blocks .iter_enumerated() .find(|(_, block)| matches!(block.terminator().kind, TerminatorKind::Return)) .map(|(bb, _)| bb); @@ -546,7 +549,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Since no pointer can ever get exposed (rejected above), this is easy to support. } - Rvalue::Cast(CastKind::Misc, _, _) => {} + Rvalue::Cast(CastKind::DynStar, _, _) => { + unimplemented!() + } + + Rvalue::Cast(_, _, _) => {} Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} Rvalue::ShallowInitBox(_, _) => {} @@ -652,6 +659,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { ProjectionElem::ConstantIndex { .. } | ProjectionElem::Downcast(..) + | ProjectionElem::OpaqueCast(..) | ProjectionElem::Subslice { .. } | ProjectionElem::Field(..) | ProjectionElem::Index(_) => {} @@ -678,7 +686,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) - | StatementKind::CopyNonOverlapping(..) + | StatementKind::Intrinsic(..) | StatementKind::Nop => {} } } @@ -729,10 +737,49 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let obligation = Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred); - let implsrc = tcx.infer_ctxt().enter(|infcx| { + let implsrc = { + let infcx = tcx.infer_ctxt().build(); let mut selcx = SelectionContext::new(&infcx); 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. + { + let infcx = tcx.infer_ctxt().build(); + 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.err_ctxt().report_fulfillment_errors(&errors, None, false); + } + } match implsrc { Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => { @@ -790,16 +837,15 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // 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, - ); - } - }); + let infcx = tcx.infer_ctxt().build(); + if let Err(e) = implsrc { + infcx.err_ctxt().report_selection_error( + obligation.clone(), + &obligation, + &e, + false, + ); + } self.check_op(ops::FnCallNonConst { caller, @@ -863,8 +909,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } - let is_intrinsic = tcx.is_intrinsic(callee); - if !tcx.is_const_fn_raw(callee) { if !tcx.is_const_default_method(callee) { // To get to here we must have already found a const impl for the @@ -924,7 +968,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // We do not use `const` modifiers for intrinsic "functions", as intrinsics are // `extern` functions, and these have no way to get marked `const`. So instead we // use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const` - if self.ccx.is_const_stable_const_fn() || is_intrinsic { + if self.ccx.is_const_stable_const_fn() || tcx.is_intrinsic(callee) { self.check_op(ops::FnCallUnstable(callee, None)); return; } @@ -964,7 +1008,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { if needs_non_const_drop { self.check_op_spanned( - ops::LiveDrop { dropped_at: Some(terminator.source_info.span) }, + ops::LiveDrop { + dropped_at: Some(terminator.source_info.span), + dropped_ty: ty_of_dropped_place, + }, err_span, ); } |