diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 41295f2b7b661..debe0acb04ef6 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -13,7 +13,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::PredicateOrigin; use rustc_index::vec::{Idx, IndexVec}; -use rustc_middle::ty::{DefIdTree, ResolverAstLowering, TyCtxt}; +use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident}; diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a99fd594a07a7..538c02b8000cd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::{ Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::print::Print; -use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; use rustc_span::def_id::LocalDefId; use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP}; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index f6881a2e5bc87..cc5a1f5ab122d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -6,7 +6,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, DefIdTree, RegionVid, Ty}; +use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a49da3da6c013..408402a7aeecb 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2242,6 +2242,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } + CastKind::Transmute => { + span_mirbug!( + self, + rvalue, + "Unexpected CastKind::Transmute, which is not permitted in Analysis MIR", + ); + } } } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 15d7613a812de..76d0b8754248e 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -22,9 +22,7 @@ use rustc_hir::BodyOwnerKind; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{ - self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt, -}; +use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_span::Symbol; use std::iter; diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 7f857528c7c5c..20644ad6018a5 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -720,6 +720,10 @@ fn codegen_stmt<'tcx>( let operand = codegen_operand(fx, operand); operand.coerce_dyn_star(fx, lval); } + Rvalue::Cast(CastKind::Transmute, ref operand, _to_ty) => { + let operand = codegen_operand(fx, operand); + lval.write_cvalue_transmute(fx, operand); + } Rvalue::Discriminant(place) => { let place = codegen_place(fx, place); let value = place.to_cvalue(fx); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index 5cd0e1cb63ae1..6bcd3e5bf58f3 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs @@ -5,7 +5,7 @@ use super::CodegenUnitDebugContext; use rustc_hir::def_id::DefId; use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; -use rustc_middle::ty::{self, DefIdTree, Ty}; +use rustc_middle::ty::{self, Ty}; use trace; use crate::common::CodegenCx; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 067a3e167feea..fd81b1c6fe1e5 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -11,7 +11,7 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::ty::query::{ExternProviders, Providers}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::Instance; -use rustc_middle::ty::{self, DefIdTree, SymbolName, TyCtxt}; +use rustc_middle::ty::{self, SymbolName, TyCtxt}; use rustc_session::config::{CrateType, OomStrategy}; use rustc_target::spec::SanitizerSet; diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 3619cb48d64f8..9f9a4ac40586d 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -8,7 +8,7 @@ use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem}; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self as ty, DefIdTree, TyCtxt}; +use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::{lint, parse::feature_err}; use rustc_span::{sym, Span}; use rustc_target::spec::{abi, SanitizerSet}; diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 57a19a4ab1eab..a77a8abbec13d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -16,7 +16,7 @@ use rustc_index::vec::Idx; use rustc_middle::mir::{self, AssertKind, SwitchTargets}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; -use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Instance, Ty}; use rustc_session::config::OptLevel; use rustc_span::source_map::Span; use rustc_span::{sym, Symbol}; @@ -765,6 +765,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => None, }; + if let Some(intrinsic @ (sym::copy_nonoverlapping | sym::transmute)) = intrinsic { + bug!("Intrinsic {intrinsic} should have been lowered before codegen"); + } + let extra_args = &args[sig.inputs().skip_binder().len()..]; let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| { let op_ty = op_arg.ty(self.mir, bx.tcx()); @@ -776,23 +780,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { None => bx.fn_abi_of_fn_ptr(sig, extra_args), }; - if intrinsic == Some(sym::transmute) { - return if let Some(target) = target { - self.codegen_transmute(bx, &args[0], destination); - helper.funclet_br(self, bx, target, mergeable_succ) - } else { - // If we are trying to transmute to an uninhabited type, - // it is likely there is no allotted destination. In fact, - // transmuting to an uninhabited type is UB, which means - // we can do what we like. Here, we declare that transmuting - // into an uninhabited type is impossible, so anything following - // it must be unreachable. - assert_eq!(fn_abi.ret.layout.abi, abi::Abi::Uninhabited); - bx.unreachable(); - MergingSucc::False - }; - } - if let Some(merging_succ) = self.codegen_panic_intrinsic( &helper, bx, @@ -835,7 +822,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match intrinsic { None | Some(sym::drop_in_place) => {} - Some(sym::copy_nonoverlapping) => unreachable!(), Some(intrinsic) => { let dest = match ret_dest { _ if fn_abi.ret.is_indirect() => llargs[0], @@ -1746,33 +1732,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: mir::Place<'tcx>) { - if let Some(index) = dst.as_local() { - match self.locals[index] { - LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place), - LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"), - LocalRef::Operand(None) => { - let dst_layout = bx.layout_of(self.monomorphized_place_ty(dst.as_ref())); - assert!(!dst_layout.ty.has_erasable_regions()); - let place = PlaceRef::alloca(bx, dst_layout); - place.storage_live(bx); - self.codegen_transmute_into(bx, src, place); - let op = bx.load_operand(place); - place.storage_dead(bx); - self.locals[index] = LocalRef::Operand(Some(op)); - self.debug_introduce_local(bx, index); - } - LocalRef::Operand(Some(op)) => { - assert!(op.layout.is_zst(), "assigning to initialized SSAtemp"); - } - } - } else { - let dst = self.codegen_place(bx, dst.as_ref()); - self.codegen_transmute_into(bx, src, dst); - } - } - - fn codegen_transmute_into( + pub(crate) fn codegen_transmute_into( &mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 3d856986fb4f7..4d8835cc446c6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -135,6 +135,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { dest.codegen_set_discr(bx, variant_index); } + mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, _ty) => { + self.codegen_transmute_into(bx, operand, dest); + } + _ => { assert!(self.rvalue_creates_operand(rvalue, DUMMY_SP)); let temp = self.codegen_rvalue_operand(bx, rvalue); @@ -344,6 +348,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; OperandValue::Immediate(newval) } + mir::CastKind::Transmute => { + bug!("Transmute operand {:?} in `codegen_rvalue_operand`", operand); + } }; OperandRef { val, layout: cast } } @@ -684,6 +691,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool { match *rvalue { + mir::Rvalue::Cast(mir::CastKind::Transmute, ..) => + // sometimes this could, but for aggregates it can't + false, mir::Rvalue::Ref(..) | mir::Rvalue::CopyForDeref(..) | mir::Rvalue::AddressOf(..) | diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index e59fad99ad798..4301e4fe69bed 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{DefIdTree, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::symbol::sym; diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 9eaab1f47a7ea..04c90f285516a 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -2,7 +2,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{DefIdTree, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_span::symbol::Symbol; /// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 2be5ed896ec80..e07a00d4cba1b 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -133,6 +133,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { bug!() } } + + Transmute => { + self.copy_op(src, dest, /*allow_transmute*/ true)?; + } } Ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index c65d677e8ea75..426d16e4160b6 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -124,10 +124,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let substs = instance.substs; let intrinsic_name = self.tcx.item_name(instance.def_id()); + if let sym::copy_nonoverlapping | sym::transmute = intrinsic_name { + bug!("Intrinsic {intrinsic_name} should have been lowered before interpreting MIR"); + } + // First handle intrinsics without return place. let ret = match ret { None => match intrinsic_name { - sym::transmute => throw_ub_format!("transmuting to uninhabited type"), sym::abort => M::abort(self, "the program aborted execution".to_owned())?, // Unsupported diverging intrinsic. _ => return Ok(false), @@ -411,9 +414,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.exact_div(&val, &size, dest)?; } - sym::transmute => { - self.copy_op(&args[0], dest, /*allow_transmute*/ true)?; - } sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => { 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 3e416b89ca6ea..e586720a0d088 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -12,9 +12,7 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{ - suggest_constraining_type_param, Adt, Closure, DefIdTree, FnDef, FnPtr, Param, Ty, -}; +use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty}; use rustc_middle::ty::{Binder, TraitRef}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index fb37eb79a335f..906e8b37b8337 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -619,6 +619,43 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } + CastKind::Transmute => { + if let MirPhase::Runtime(..) = self.mir_phase { + // `mem::transmute` currently requires types concrete enough + // to *know* that their sizes are the same, and we repeat + // that check here. This restriction may be lifted in future, + // should some optimizations need to it be more general. + // (It might just end up being UB if they don't match, say.) + + let src_layout = self.tcx.layout_of(self.param_env.and(op_ty)); + let dst_layout = self.tcx.layout_of(self.param_env.and(*target_type)); + if let Err(e) = src_layout { + self.fail( + location, + format!( + "Unable to compute layout for source type {op_ty:?}: {e}" + ), + ); + } + if let Err(e) = dst_layout { + self.fail(location, format!("Unable to compute layout for destination type {target_type:?}: {e}")); + } + + if let (Ok(src_layout), Ok(dst_layout)) = (src_layout, dst_layout) { + if src_layout.layout.size() != dst_layout.layout.size() { + self.fail(location, format!("Source and destination layouts have different sizes: {src_layout:?} vs {dst_layout:?}")); + } + } + } else { + self.fail( + location, + format!( + "Transmute is not supported in non-runtime phase {:?}.", + self.mir_phase + ), + ); + } + } } } Rvalue::Repeat(_, _) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 25c467bfd2bd6..ea3ce3fbb7562 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -35,7 +35,7 @@ use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::DynKind; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 848828175e2d8..9693a59defbb0 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -22,8 +22,7 @@ use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{ - self, AdtDef, DefIdTree, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, + self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index b0dc6b1dcacc3..b2e4850df6089 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -16,8 +16,7 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::util::ExplicitSelf; use rustc_middle::ty::{ - self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, + self, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 9cf3ff65a91ca..6f6f993f72717 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -3,7 +3,7 @@ use crate::astconv::AstConv; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, DefIdTree, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index b14e65183aa3d..9e48c078468d5 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -17,7 +17,7 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::*; -use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_session::lint; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 50073d94ea5c9..acd9f8a5c8eeb 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{ - self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index a8b33c74bc1ee..d53c429ca15ca 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 5d5c8ca604a04..a8b7699b66750 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -8,7 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt}; -use rustc_middle::ty::{DefIdTree, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable}; use std::ops::ControlFlow; /// Defines the `TermsContext` basically houses an arena where we can diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 60e55c7b0cf57..a8f8121153faf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -25,7 +25,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, Ty, TyCtxt, UserType, + self, AdtKind, CanonicalUserType, GenericParamDefKind, Ty, TyCtxt, UserType, }; use rustc_middle::ty::{GenericArgKind, SubstsRef, UserSelfTy, UserSubsts}; use rustc_session::lint; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index d64492e503db0..dfc14958c3ee1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -3,9 +3,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; use rustc_infer::traits::ObligationCauseCode; -use rustc_middle::ty::{ - self, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, -}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_span::{self, Span}; use rustc_trait_selection::traits; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 2e62e13648c95..84286344a13d0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -28,7 +28,7 @@ use rustc_infer::infer::InferOk; use rustc_infer::infer::TypeTrace; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::visit::TypeVisitableExt; -use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty}; +use rustc_middle::ty::{self, IsSuggestable, Ty}; use rustc_session::Session; use rustc_span::symbol::{kw, Ident}; use rustc_span::{self, sym, Span}; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index c49621b7c2488..c77251a156fc0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -16,7 +16,7 @@ use rustc_infer::traits::{self, StatementAsExpression}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty, + self, suggest_constraining_type_params, Binder, IsSuggestable, ToPredicate, Ty, TypeVisitableExt, }; use rustc_session::errors::ExprParenthesesNeeded; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 47a4d4e72dffd..8ec9850d780c1 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -27,7 +27,7 @@ use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths}; -use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index a4b325a9b7984..0c199babc4682 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index e242900fd2329..a3151d2d36577 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -17,7 +17,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; -use rustc_middle::ty::{self, DefIdTree, InferConst}; +use rustc_middle::ty::{self, InferConst}; use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; use rustc_span::symbol::{kw, sym, Ident}; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index db4b8af4683e3..c5ef48fe3da25 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -5,7 +5,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::TyCtxt; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::{self, Binder, DefIdTree, Region, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Binder, Region, Ty, TypeVisitable}; use rustc_span::Span; /// Information about the anonymous region we are searching for. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 85958c4170569..7ca50f5a2db70 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -17,7 +17,7 @@ use rustc_hir::{is_range_literal, Expr, ExprKind, Node}; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{ - self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + self, AdtKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; use rustc_span::def_id::LocalDefId; use rustc_span::source_map; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 3a92f5806c9ef..c43162f63258b 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -14,7 +14,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_infer::traits::util::elaborate_predicates_with_span; use rustc_middle::ty::adjustment; -use rustc_middle::ty::{self, DefIdTree, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 4b5bacac8149c..43eef1c770c96 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1,5 +1,5 @@ use crate::hir::{ModuleItems, Owner}; -use crate::ty::{DefIdTree, TyCtxt}; +use crate::ty::TyCtxt; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index ad119c4e07306..503d79d60f177 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -7,7 +7,7 @@ pub mod nested_filter; pub mod place; use crate::ty::query::Providers; -use crate::ty::{DefIdTree, ImplSubject, TyCtxt}; +use crate::ty::{ImplSubject, TyCtxt}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 893bf54b8660b..171cf1c1ab173 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -1,7 +1,7 @@ //! A pass that checks to make sure private fields and methods aren't used //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. -use crate::ty::{DefIdTree, TyCtxt, Visibility}; +use crate::ty::{TyCtxt, Visibility}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; @@ -112,7 +112,7 @@ impl EffectiveVisibilities { &mut self, def_id: LocalDefId, eff_vis: &EffectiveVisibility, - tree: impl DefIdTree, + tcx: TyCtxt<'_>, ) { use std::collections::hash_map::Entry; match self.map.entry(def_id) { @@ -122,7 +122,7 @@ impl EffectiveVisibilities { let vis_at_level = eff_vis.at_level(l); let old_vis_at_level = old_eff_vis.at_level_mut(l); if vis_at_level != old_vis_at_level - && vis_at_level.is_at_least(*old_vis_at_level, tree) + && vis_at_level.is_at_least(*old_vis_at_level, tcx) { *old_vis_at_level = *vis_at_level } @@ -219,7 +219,7 @@ impl EffectiveVisibilities { lazy_private_vis: impl FnOnce() -> Visibility, inherited_effective_vis: EffectiveVisibility, level: Level, - tree: impl DefIdTree, + tcx: TyCtxt<'_>, ) -> bool { let mut changed = false; let mut current_effective_vis = self @@ -240,7 +240,7 @@ impl EffectiveVisibilities { && level != l) { calculated_effective_vis = - if nominal_vis.is_at_least(inherited_effective_vis_at_level, tree) { + if nominal_vis.is_at_least(inherited_effective_vis_at_level, tcx) { inherited_effective_vis_at_level } else { nominal_vis @@ -249,7 +249,7 @@ impl EffectiveVisibilities { // effective visibility can't be decreased at next update call for the // same id if *current_effective_vis_at_level != calculated_effective_vis - && calculated_effective_vis.is_at_least(*current_effective_vis_at_level, tree) + && calculated_effective_vis.is_at_least(*current_effective_vis_at_level, tcx) { changed = true; *current_effective_vis_at_level = calculated_effective_vis; diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 354c84e2209a3..b61f7806b7a99 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -3,7 +3,7 @@ pub use self::StabilityLevel::*; -use crate::ty::{self, DefIdTree, TyCtxt}; +use crate::ty::{self, TyCtxt}; use rustc_ast::NodeId; use rustc_attr::{self as attr, ConstStability, DefaultBodyStability, Deprecation, Stability}; use rustc_data_structures::fx::FxHashMap; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0d78c6135b336..9091f3558bd66 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -10,7 +10,7 @@ use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::ty::{self, DefIdTree, List, Ty, TyCtxt}; +use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex}; use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; @@ -1963,7 +1963,8 @@ impl<'tcx> Rvalue<'tcx> { | CastKind::PtrToPtr | CastKind::Pointer(_) | CastKind::PointerFromExposedAddress - | CastKind::DynStar, + | CastKind::DynStar + | CastKind::Transmute, _, _, ) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index ae09562a85e98..72efa1e27e47a 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -83,6 +83,9 @@ pub enum MirPhase { /// access to. This occurs in generator bodies. Such locals do not behave like other locals, /// because they eg may be aliased in surprising ways. Runtime MIR has no such special locals - /// all generator bodies are lowered and so all places that look like locals really are locals. + /// - Intrinsics: In analysis MIR, intrinsics are typically represented as [`TerminatorKind::Call`]s + /// to their `extern "rust-intrinsic"` declarations. In runtime MIR, some intrinsics are lowered + /// to MIR constructs not used earlier, such as `mem::transmute` → [`CastKind::Transmute`]. /// /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that @@ -1189,6 +1192,10 @@ pub enum CastKind { IntToFloat, PtrToPtr, FnPtrToPtr, + /// Reinterpret the bits of the input as a different type. + /// + /// Allowed only in [`MirPhase::Runtime`]; Earlier it's a [`TerminatorKind::Call`]. + Transmute, } #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index f1a9e50a4f05f..dfe23cf991f8c 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -1,6 +1,6 @@ pub use self::AssocItemContainer::*; -use crate::ty::{self, DefIdTree}; +use crate::ty; use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 884ae7f5da284..3e3d6c2ba8857 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,6 +1,6 @@ use crate::middle::resolve_bound_vars as rbv; use crate::mir::interpret::LitToConstInput; -use crate::ty::{self, DefIdTree, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; +use crate::ty::{self, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0333198c20310..3419c92c1ebfe 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -20,11 +20,10 @@ use crate::traits; use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData}; use crate::ty::query::{self, TyCtxtAt}; use crate::ty::{ - self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar, - FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, - ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, - ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy, - Visibility, + self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid, + GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, + PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions, + TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy, Visibility, }; use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; use rustc_ast as ast; @@ -794,8 +793,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn consider_optimizing String>(self, msg: T) -> bool { - let cname = self.crate_name(LOCAL_CRATE); - self.sess.consider_optimizing(cname.as_str(), msg) + self.sess.consider_optimizing(|| self.crate_name(LOCAL_CRATE), msg) } /// Obtain all lang items of this crate and all dependencies (recursively) diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index e894e1aaf3695..3ca17e7273eb9 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -3,9 +3,9 @@ use std::ops::ControlFlow; use crate::ty::{ - AliasTy, Const, ConstKind, DefIdTree, FallibleTypeFolder, InferConst, InferTy, Opaque, - PolyTraitPredicate, Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitor, + AliasTy, Const, ConstKind, FallibleTypeFolder, InferConst, InferTy, Opaque, PolyTraitPredicate, + Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, + TypeVisitor, }; use rustc_data_structures::fx::FxHashMap; diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index e268553f8268b..ac42d6e05100f 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -1,5 +1,5 @@ use crate::ty::context::TyCtxt; -use crate::ty::{self, DefId, DefIdTree, ParamEnv, Ty}; +use crate::ty::{self, DefId, ParamEnv, Ty}; /// Represents whether some type is inhabited in a given context. /// Examples of uninhabited types are `!`, `enum Void {}`, or a struct diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 5084bc9cec6c6..e8dfc522c53d3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -325,12 +325,15 @@ pub struct ClosureSizeProfileData<'tcx> { pub after_feature_tys: Ty<'tcx>, } -pub trait DefIdTree: Copy { - fn opt_parent(self, id: DefId) -> Option; +impl TyCtxt<'_> { + #[inline] + pub fn opt_parent(self, id: DefId) -> Option { + self.def_key(id).parent.map(|index| DefId { index, ..id }) + } #[inline] #[track_caller] - fn parent(self, id: DefId) -> DefId { + pub fn parent(self, id: DefId) -> DefId { match self.opt_parent(id) { Some(id) => id, // not `unwrap_or_else` to avoid breaking caller tracking @@ -340,17 +343,17 @@ pub trait DefIdTree: Copy { #[inline] #[track_caller] - fn opt_local_parent(self, id: LocalDefId) -> Option { + pub fn opt_local_parent(self, id: LocalDefId) -> Option { self.opt_parent(id.to_def_id()).map(DefId::expect_local) } #[inline] #[track_caller] - fn local_parent(self, id: LocalDefId) -> LocalDefId { + pub fn local_parent(self, id: LocalDefId) -> LocalDefId { self.parent(id.to_def_id()).expect_local() } - fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { + pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { if descendant.krate != ancestor.krate { return false; } @@ -365,13 +368,6 @@ pub trait DefIdTree: Copy { } } -impl<'tcx> DefIdTree for TyCtxt<'tcx> { - #[inline] - fn opt_parent(self, id: DefId) -> Option { - self.def_key(id).parent.map(|index| DefId { index, ..id }) - } -} - impl Visibility { pub fn is_public(self) -> bool { matches!(self, Visibility::Public) @@ -391,19 +387,19 @@ impl> Visibility { } /// Returns `true` if an item with this visibility is accessible from the given module. - pub fn is_accessible_from(self, module: impl Into, tree: impl DefIdTree) -> bool { + pub fn is_accessible_from(self, module: impl Into, tcx: TyCtxt<'_>) -> bool { match self { // Public items are visible everywhere. Visibility::Public => true, - Visibility::Restricted(id) => tree.is_descendant_of(module.into(), id.into()), + Visibility::Restricted(id) => tcx.is_descendant_of(module.into(), id.into()), } } /// Returns `true` if this visibility is at least as accessible as the given visibility - pub fn is_at_least(self, vis: Visibility>, tree: impl DefIdTree) -> bool { + pub fn is_at_least(self, vis: Visibility>, tcx: TyCtxt<'_>) -> bool { match vis { Visibility::Public => self.is_public(), - Visibility::Restricted(id) => self.is_accessible_from(id, tree), + Visibility::Restricted(id) => self.is_accessible_from(id, tcx), } } } diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 021c20b5854d2..d947d96041ef7 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -1,5 +1,5 @@ use crate::ty::GenericArg; -use crate::ty::{self, DefIdTree, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6a053c368d8ec..b3139d23d36e3 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,6 +1,6 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::ty::{ - self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, + self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; use crate::ty::{GenericArg, GenericArgKind}; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ba714541c9e8f..5539db25e7a6c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -7,7 +7,7 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use crate::ty::visit::ValidateBoundVars; use crate::ty::InferTy::*; use crate::ty::{ - self, AdtDef, DefIdTree, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, + self, AdtDef, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use crate::ty::{List, ParamEnv}; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 90270e0ee9da5..8b5469743dad6 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -4,8 +4,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; use crate::ty::layout::IntegerExt; use crate::ty::{ - self, DefIdTree, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitableExt, + self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, }; use crate::ty::{GenericArgKind, SubstsRef}; use rustc_apfloat::Float as _; diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index c4f526dbdc89d..55aa4fcff2cdb 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -4,7 +4,7 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::Representability; -use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_query_system::query::QueryInfo; use rustc_query_system::Value; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 41306dd80fbdd..f356c8a68380c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -25,7 +25,7 @@ use rustc_middle::mir::{BorrowKind, Field, Mutability}; use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; use rustc_middle::ty::CanonicalUserTypeAnnotation; -use rustc_middle::ty::{self, AdtDef, ConstKind, DefIdTree, Region, Ty, TyCtxt, UserType}; +use rustc_middle::ty::{self, AdtDef, ConstKind, Region, Ty, TyCtxt, UserType}; use rustc_span::{Span, Symbol}; use std::cmp::Ordering; diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index d00ee1f4babe8..110d0581e49a7 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -132,6 +132,12 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { self.register_violations(violations, used_unsafe_blocks.iter().copied()); } }, + Rvalue::Cast(CastKind::Transmute, ..) => { + self.require_unsafe( + UnsafetyViolationKind::General, + UnsafetyViolationDetails::CallToUnsafeFunction, + ); + } _ => {} } self.super_rvalue(rvalue, location); diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index f596cc1808fa2..aad5be1f44c6f 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -2,6 +2,7 @@ use crate::MirPass; use rustc_middle::mir::*; +use rustc_middle::ty::inhabitedness::inhabited_predicate::InhabitedPredicate; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; @@ -162,6 +163,30 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } } + sym::transmute => { + let dst_ty = destination.ty(local_decls, tcx).ty; + if let Some(target) = *target { + let mut args = args.drain(..); + block.statements.push(Statement { + source_info: terminator.source_info, + kind: StatementKind::Assign(Box::new(( + *destination, + Rvalue::Cast(CastKind::Transmute, args.next().unwrap(), dst_ty), + ))), + }); + assert_eq!(args.next(), None, "Extra argument for transmute intrinsic"); + drop(args); + terminator.kind = TerminatorKind::Goto { target }; + } else { + debug_assert!(!matches!( + dst_ty.inhabited_predicate(tcx), + InhabitedPredicate::True + )); + // `transmute::<_, !>(x)` is UB for anything inhabited, + // and must be unreachable if `x` is uninhabited. + terminator.kind = TerminatorKind::Unreachable; + } + } _ if intrinsic_name.as_str().starts_with("simd_shuffle") => { validate_simd_shuffle(tcx, args, terminator.source_info.span); } diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 2c56edd89bc31..3c7425d83c488 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -9,7 +9,7 @@ use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::ty::print::characteristic_def_id_of_type; -use rustc_middle::ty::{self, visit::TypeVisitableExt, DefIdTree, InstanceDef, TyCtxt}; +use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt}; use rustc_span::symbol::Symbol; use super::PartitioningCx; diff --git a/compiler/rustc_parse/locales/en-US.ftl b/compiler/rustc_parse/locales/en-US.ftl index 4ddeeed5b7e0a..e76e91fc1b135 100644 --- a/compiler/rustc_parse/locales/en-US.ftl +++ b/compiler/rustc_parse/locales/en-US.ftl @@ -151,6 +151,10 @@ parse_missing_in_in_for_loop = missing `in` in `for` loop parse_missing_expression_in_for_loop = missing expression to iterate on in `for` loop .suggestion = try adding an expression to the `for` loop +parse_loop_else = `{$loop_kind}...else` loops are not supported + .note = consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run + .loop_keyword = `else` is attached to this loop + parse_missing_comma_after_match_arm = expected `,` following `match` arm .suggestion = missing a comma here to end this `match` arm diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index c746a87096476..1662db36d10f9 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -451,6 +451,17 @@ pub(crate) struct MissingExpressionInForLoop { pub span: Span, } +#[derive(Diagnostic)] +#[diag(parse_loop_else)] +#[note] +pub(crate) struct LoopElseNotSupported { + #[primary_span] + pub span: Span, + pub loop_kind: &'static str, + #[label(parse_loop_keyword)] + pub loop_kw: Span, +} + #[derive(Diagnostic)] #[diag(parse_missing_comma_after_match_arm)] pub(crate) struct MissingCommaAfterMatchArm { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 24d4c17f5d8ab..078be0e365224 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1401,7 +1401,7 @@ impl<'a> Parser<'a> { // 2 | foo(bar(; // | ^ expected expression self.bump(); - Ok(self.mk_expr_err(self.token.span)) + Ok(self.mk_expr_err(self.prev_token.span)) } else if self.token.uninterpolated_span().rust_2018() { // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly. if self.check_keyword(kw::Async) { @@ -2503,9 +2503,27 @@ impl<'a> Parser<'a> { let (attrs, loop_block) = self.parse_inner_attrs_and_block()?; let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label); + + self.recover_loop_else("for", lo)?; + Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs)) } + /// Recovers from an `else` clause after a loop (`for...else`, `while...else`) + fn recover_loop_else(&mut self, loop_kind: &'static str, loop_kw: Span) -> PResult<'a, ()> { + if self.token.is_keyword(kw::Else) && self.may_recover() { + let else_span = self.token.span; + self.bump(); + let else_clause = self.parse_else_expr()?; + self.sess.emit_err(errors::LoopElseNotSupported { + span: else_span.to(else_clause.span), + loop_kind, + loop_kw, + }); + } + Ok(()) + } + fn error_missing_in_for_loop(&mut self) { let (span, sub): (_, fn(_) -> _) = if self.token.is_ident_named(sym::of) { // Possibly using JS syntax (#75311). @@ -2530,6 +2548,9 @@ impl<'a> Parser<'a> { err.span_label(cond.span, "this `while` condition successfully parsed"); err })?; + + self.recover_loop_else("while", lo)?; + Ok(self.mk_expr_with_attrs( lo.to(self.prev_token.span), ExprKind::While(cond, body, opt_label), @@ -2541,6 +2562,7 @@ impl<'a> Parser<'a> { fn parse_expr_loop(&mut self, opt_label: Option