diff options
| author | bors <bors@rust-lang.org> | 2024-03-06 18:51:11 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-03-06 18:51:11 +0000 |
| commit | 305d2b0f5c7e8081ab21f78e2d53ed8f84aebecd (patch) | |
| tree | e8c9415143a6307f929727db3da941edda124d78 /compiler/rustc_const_eval/src | |
| parent | 033c1e00b0fda6616c1442ecf40bb79da8c5db20 (diff) | |
| parent | 3c2318c0b21e2f4473c2465a4d9481ccd21906dd (diff) | |
Auto merge of #3363 - RalfJung:rustup, r=RalfJung
Rustup This should finally work again :)
Diffstat (limited to 'compiler/rustc_const_eval/src')
11 files changed, 72 insertions, 92 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 62bc68b1a20..e5b4fc3a574 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -1,8 +1,6 @@ use std::mem; -use rustc_errors::{ - DiagArgName, DiagArgValue, DiagnosticMessage, IntoDiagnostic, IntoDiagnosticArg, -}; +use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, IntoDiagnostic, IntoDiagnosticArg}; use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::AssertKind; use rustc_middle::query::TyCtxtAt; @@ -25,7 +23,7 @@ pub enum ConstEvalErrKind { } impl MachineStopType for ConstEvalErrKind { - fn diagnostic_message(&self) -> DiagnosticMessage { + fn diagnostic_message(&self) -> DiagMessage { use crate::fluent_generated::*; use ConstEvalErrKind::*; match self { diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 62aab9d5635..afabd9689c6 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -1,8 +1,7 @@ use std::borrow::Cow; use rustc_errors::{ - codes::*, Diag, DiagArgValue, DiagCtxt, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, - Level, + codes::*, Diag, DiagArgValue, DiagCtxt, DiagMessage, EmissionGuarantee, IntoDiagnostic, Level, }; use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -424,7 +423,7 @@ pub struct UndefinedBehavior { pub trait ReportErrorExt { /// Returns the diagnostic message for this error. - fn diagnostic_message(&self) -> DiagnosticMessage; + fn diagnostic_message(&self) -> DiagMessage; fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>); fn debug(self) -> String @@ -433,7 +432,7 @@ pub trait ReportErrorExt { { ty::tls::with(move |tcx| { let dcx = tcx.dcx(); - let mut diag = dcx.struct_allow(DiagnosticMessage::Str(String::new().into())); + let mut diag = dcx.struct_allow(DiagMessage::Str(String::new().into())); let message = self.diagnostic_message(); self.add_args(&mut diag); let s = dcx.eagerly_translate_to_string(message, diag.args.iter()); @@ -457,7 +456,7 @@ fn bad_pointer_message(msg: CheckInAllocMsg, dcx: &DiagCtxt) -> String { } impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { - fn diagnostic_message(&self) -> DiagnosticMessage { + fn diagnostic_message(&self) -> DiagMessage { use crate::fluent_generated::*; use UndefinedBehaviorInfo::*; match self { @@ -595,7 +594,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { } impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { - fn diagnostic_message(&self) -> DiagnosticMessage { + fn diagnostic_message(&self) -> DiagMessage { use crate::fluent_generated::*; use rustc_middle::mir::interpret::ValidationErrorKind::*; match self.kind { @@ -613,7 +612,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { PartialPointer => const_eval_validation_partial_pointer, ConstRefToMutable => const_eval_validation_const_ref_to_mutable, ConstRefToExtern => const_eval_validation_const_ref_to_extern, - MutableRefInConstOrStatic => const_eval_validation_mutable_ref_in_const_or_static, MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable, NullFnPtr => const_eval_validation_null_fn_ptr, NeverVal => const_eval_validation_never_val, @@ -767,7 +765,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { } NullPtr { .. } | PtrToStatic { .. } - | MutableRefInConstOrStatic | ConstRefToMutable | ConstRefToExtern | MutableRefToImmutable @@ -785,7 +782,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { } impl ReportErrorExt for UnsupportedOpInfo { - fn diagnostic_message(&self) -> DiagnosticMessage { + fn diagnostic_message(&self) -> DiagMessage { use crate::fluent_generated::*; match self { UnsupportedOpInfo::Unsupported(s) => s.clone().into(), @@ -821,7 +818,7 @@ impl ReportErrorExt for UnsupportedOpInfo { } impl<'tcx> ReportErrorExt for InterpError<'tcx> { - fn diagnostic_message(&self) -> DiagnosticMessage { + fn diagnostic_message(&self) -> DiagMessage { match self { InterpError::UndefinedBehavior(ub) => ub.diagnostic_message(), InterpError::Unsupported(e) => e.diagnostic_message(), @@ -844,7 +841,7 @@ impl<'tcx> ReportErrorExt for InterpError<'tcx> { } impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { - fn diagnostic_message(&self) -> DiagnosticMessage { + fn diagnostic_message(&self) -> DiagMessage { use crate::fluent_generated::*; match self { InvalidProgramInfo::TooGeneric => const_eval_too_generic, @@ -879,7 +876,7 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { } impl ReportErrorExt for ResourceExhaustionInfo { - fn diagnostic_message(&self) -> DiagnosticMessage { + fn diagnostic_message(&self) -> DiagMessage { use crate::fluent_generated::*; match self { ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached, diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index a88e130cd4b..2cebea9d145 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -182,13 +182,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { use rustc_type_ir::TyKind::*; - let val = match src.layout.ty.kind() { - // Floating point - Float(FloatTy::F32) => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty), - Float(FloatTy::F64) => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty), - _ => { - bug!("Can't cast 'Float' type into {}", cast_to.ty); - } + let Float(fty) = src.layout.ty.kind() else { + bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty) + }; + let val = match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty), + FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty), + FloatTy::F128 => unimplemented!("f16_f128"), }; Ok(ImmTy::from_scalar(val, cast_to)) } @@ -275,6 +276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty); Ok(match *cast_ty.kind() { + // int -> int Int(_) | Uint(_) => { let size = match *cast_ty.kind() { Int(t) => Integer::from_int_ty(self, t).size(), @@ -285,15 +287,26 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Scalar::from_uint(v, size) } - Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value), - Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value), - Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value), - Float(FloatTy::F64) => Scalar::from_f64(Double::from_u128(v).value), - - Char => { - // `u8` to `char` cast - Scalar::from_u32(u8::try_from(v).unwrap().into()) + // signed int -> float + Float(fty) if signed => { + let v = v as i128; + match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value), + FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value), + FloatTy::F128 => unimplemented!("f16_f128"), + } } + // unsigned int -> float + Float(fty) => match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value), + FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value), + FloatTy::F128 => unimplemented!("f16_f128"), + }, + + // u8 -> char + Char => Scalar::from_u32(u8::try_from(v).unwrap().into()), // Casts to bool are not permitted by rustc, no need to handle them here. _ => span_bug!(self.cur_span(), "invalid int to {} cast", cast_ty), @@ -339,14 +352,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let v = f.to_i128(size.bits_usize()).value; Scalar::from_int(v, size) } - // float -> f32 - Float(FloatTy::F32) => { - Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)) - } - // float -> f64 - Float(FloatTy::F64) => { - Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)) - } + // float -> float + Float(fty) => match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)), + FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)), + FloatTy::F128 => unimplemented!("f16_f128"), + }, // That's it. _ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty), } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index eef15425764..475c533077a 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -389,12 +389,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let left = left.to_scalar(); let right = right.to_scalar(); Ok(match fty { + FloatTy::F16 => unimplemented!("f16_f128"), FloatTy::F32 => { self.binary_float_op(bin_op, layout, left.to_f32()?, right.to_f32()?) } FloatTy::F64 => { self.binary_float_op(bin_op, layout, left.to_f64()?, right.to_f64()?) } + FloatTy::F128 => unimplemented!("f16_f128"), }) } _ if left.layout.ty.is_integral() => { diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 6e987784ff9..672008edfd3 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -437,6 +437,7 @@ where trace!("deref to {} on {:?}", val.layout.ty, *val); if val.layout.ty.is_box() { + // Derefer should have removed all Box derefs bug!("dereferencing {}", val.layout.ty); } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index e72ace8be35..d29e69d753e 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -359,14 +359,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(Some(match ty.kind() { ty::Ref(_, ty, _) => *ty, ty::RawPtr(mt) => mt.ty, - // We should only accept `Box` with the default allocator. - // It's hard to test for that though so we accept every 1-ZST allocator. - ty::Adt(def, args) - if def.is_box() - && self.layout_of(args[1].expect_ty()).is_ok_and(|l| l.is_1zst()) => - { - args[0].expect_ty() - } + // We only accept `Box` with the default allocator. + _ if ty.is_box_global(*self.tcx) => ty.boxed_ty(), _ => return Ok(None), })) }; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 2a13671a829..3427368421f 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -30,9 +30,9 @@ where } impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> { - type BreakTy = FoundParam; + type Result = ControlFlow<FoundParam>; - fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { if !ty.has_param() { return ControlFlow::Continue(()); } @@ -64,7 +64,7 @@ where } } - fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { + fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result { match c.kind() { ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam), _ => c.super_visit_with(self), diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 792e1c9e736..ff1cb43db86 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -148,14 +148,6 @@ impl CtfeValidationMode { } } } - - fn may_contain_mutable_ref(self) -> bool { - match self { - CtfeValidationMode::Static { mutbl } => mutbl == Mutability::Mut, - CtfeValidationMode::Promoted { .. } => false, - CtfeValidationMode::Const { .. } => false, - } - } } /// State for tracking recursive validation of references @@ -511,20 +503,19 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // If this allocation has size zero, there is no actual mutability here. let (size, _align, _alloc_kind) = self.ecx.get_alloc_info(alloc_id); if size != Size::ZERO { + // Mutable pointer to immutable memory is no good. if ptr_expected_mutbl == Mutability::Mut && alloc_actual_mutbl == Mutability::Not { throw_validation_failure!(self.path, MutableRefToImmutable); } - if ptr_expected_mutbl == Mutability::Mut - && self.ctfe_mode.is_some_and(|c| !c.may_contain_mutable_ref()) - { - throw_validation_failure!(self.path, MutableRefInConstOrStatic); - } - if alloc_actual_mutbl == Mutability::Mut - && matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) - { - throw_validation_failure!(self.path, ConstRefToMutable); + // In a const, everything must be completely immutable. + if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) { + if ptr_expected_mutbl == Mutability::Mut + || alloc_actual_mutbl == Mutability::Mut + { + throw_validation_failure!(self.path, ConstRefToMutable); + } } } // Potentially skip recursive check. 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 c98dc4deb75..0b41b4f9682 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -17,7 +17,7 @@ use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; use std::mem; -use std::ops::{ControlFlow, Deref}; +use std::ops::Deref; use super::ops::{self, NonConstOp, Status}; use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop}; @@ -164,9 +164,9 @@ struct LocalReturnTyVisitor<'ck, 'mir, 'tcx> { } impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> { - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { + fn visit_ty(&mut self, t: Ty<'tcx>) { match t.kind() { - ty::FnPtr(_) => ControlFlow::Continue(()), + ty::FnPtr(_) => {} ty::Ref(_, _, hir::Mutability::Mut) => { self.checker.check_op(ops::ty::MutRef(self.kind)); t.super_visit_with(self) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 1107b894ab3..15720f25c5c 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -62,6 +62,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp { } } + #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { feature_err( &ccx.tcx.sess, @@ -556,6 +557,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref { Status::Unstable(sym::const_mut_refs) } + #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { feature_err( &ccx.tcx.sess, @@ -589,6 +591,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess { } } + #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { let mut err = feature_err( &ccx.tcx.sess, @@ -632,6 +635,7 @@ pub mod ty { } } + #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { feature_err( &ccx.tcx.sess, diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 265ca0c7884..3ea54146fc7 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -4,7 +4,7 @@ //! other areas of the compiler as well. use rustc_infer::infer::TyCtxtInferExt; -use rustc_middle::traits::{DefiningAnchor, ObligationCause}; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Variance}; use rustc_trait_selection::traits::ObligationCtxt; @@ -33,9 +33,6 @@ pub fn is_equal_up_to_subtyping<'tcx>( /// When validating assignments, the variance should be `Covariant`. When checking /// during `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial)` variance should be `Invariant` /// because we want to check for type equality. -/// -/// This mostly ignores opaque types as it can be used in constraining contexts -/// while still computing the final underlying type. pub fn relate_types<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, @@ -47,8 +44,7 @@ pub fn relate_types<'tcx>( return true; } - let mut builder = - tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble); + let mut builder = tcx.infer_ctxt().ignoring_regions(); let infcx = builder.build(); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); @@ -58,20 +54,5 @@ pub fn relate_types<'tcx>( Ok(()) => {} Err(_) => return false, }; - let errors = ocx.select_all_or_error(); - // With `Reveal::All`, opaque types get normalized away, with `Reveal::UserFacing` - // we would get unification errors because we're unable to look into opaque types, - // even if they're constrained in our current function. - for (key, ty) in infcx.take_opaque_types() { - let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args); - if hidden_ty != ty.hidden_type.ty { - span_bug!( - ty.hidden_type.span, - "{}, {}", - tcx.type_of(key.def_id).instantiate(tcx, key.args), - ty.hidden_type.ty - ); - } - } - errors.is_empty() + ocx.select_all_or_error().is_empty() } |
