diff options
Diffstat (limited to 'compiler/rustc_ty_utils/src')
| -rw-r--r-- | compiler/rustc_ty_utils/src/abi.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/consts.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/implied_bounds.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/layout.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/ty.rs | 10 |
6 files changed, 55 insertions, 40 deletions
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index d644cbccea1..d1197774fe9 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -254,7 +254,12 @@ fn adjust_for_rust_scalar<'tcx>( // The aliasing rules for `Box<T>` are still not decided, but currently we emit // `noalias` for it. This can be turned off using an unstable flag. // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326 - let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true); + let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias; + + // LLVM prior to version 12 had known miscompiles in the presence of noalias attributes + // (see #54878), so it was conditionally disabled, but we don't support earlier + // versions at all anymore. We still support turning it off using -Zmutable-noalias. + let noalias_mut_ref = cx.tcx.sess.opts.unstable_opts.mutable_noalias; // `&mut` pointer parameters never alias other parameters, // or mutable global data @@ -263,29 +268,21 @@ fn adjust_for_rust_scalar<'tcx>( // and can be marked as both `readonly` and `noalias`, as // LLVM's definition of `noalias` is based solely on memory // dependencies rather than pointer equality - // - // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute - // for UniqueBorrowed arguments, so that the codegen backend can decide whether - // or not to actually emit the attribute. It can also be controlled with the - // `-Zmutable-noalias` debugging option. let no_alias = match kind { - PointerKind::SharedMutable - | PointerKind::UniqueBorrowed - | PointerKind::UniqueBorrowedPinned => false, + PointerKind::SharedMutable | PointerKind::UniqueBorrowedPinned => false, + PointerKind::UniqueBorrowed => noalias_mut_ref, PointerKind::UniqueOwned => noalias_for_box, - PointerKind::Frozen => !is_return, + PointerKind::Frozen => true, }; - if no_alias { + // We can never add `noalias` in return position; that LLVM attribute has some very surprising semantics + // (see <https://github.com/rust-lang/unsafe-code-guidelines/issues/385#issuecomment-1368055745>). + if no_alias && !is_return { attrs.set(ArgAttribute::NoAlias); } if kind == PointerKind::Frozen && !is_return { attrs.set(ArgAttribute::ReadOnly); } - - if kind == PointerKind::UniqueBorrowed && !is_return { - attrs.set(ArgAttribute::NoAliasMutRef); - } } } } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index f8ff31f971b..a9b4e1420ea 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -267,8 +267,8 @@ struct IsThirPolymorphic<'a, 'tcx> { thir: &'a thir::Thir<'tcx>, } -fn error<'tcx>( - tcx: TyCtxt<'tcx>, +fn error( + tcx: TyCtxt<'_>, sub: GenericConstantTooComplexSub, root_span: Span, ) -> Result<!, ErrorGuaranteed> { @@ -281,8 +281,8 @@ fn error<'tcx>( Err(reported) } -fn maybe_supported_error<'tcx>( - tcx: TyCtxt<'tcx>, +fn maybe_supported_error( + tcx: TyCtxt<'_>, sub: GenericConstantTooComplexSub, root_span: Span, ) -> Result<!, ErrorGuaranteed> { @@ -349,10 +349,10 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> { } /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead. -pub fn thir_abstract_const<'tcx>( - tcx: TyCtxt<'tcx>, +pub fn thir_abstract_const( + tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>, -) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> { +) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> { if tcx.features().generic_const_exprs { match tcx.def_kind(def.did) { // FIXME(generic_const_exprs): We currently only do this for anonymous constants, diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index f0d8c240ea5..b7a24a22c53 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -6,7 +6,7 @@ pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { assumed_wf_types, ..*providers }; } -fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::List<Ty<'tcx>> { +fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { match tcx.def_kind(def_id) { DefKind::Fn => { let sig = tcx.fn_sig(def_id); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 2da98d33429..8d46ba320fc 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -194,7 +194,7 @@ fn resolve_associated_item<'tcx>( && trait_item_id != leaf_def.item.def_id && let Some(leaf_def_item) = leaf_def.item.def_id.as_local() { - tcx.compare_assoc_const_impl_item_with_trait_item(( + tcx.compare_impl_const(( leaf_def_item, trait_item_id, ))?; diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index c761a4dbe45..6aa016133ca 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -155,17 +155,37 @@ fn layout_of_uncached<'tcx>( } let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env); - let metadata = match unsized_part.kind() { - ty::Foreign(..) => { + + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { + let metadata_ty = tcx.normalize_erasing_regions( + param_env, + tcx.mk_projection(metadata_def_id, [pointee]), + ); + let metadata_layout = cx.layout_of(metadata_ty)?; + // If the metadata is a 1-zst, then the pointer is thin. + if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 { return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); } - ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), - ty::Dynamic(..) => { - let mut vtable = scalar_unit(Pointer); - vtable.valid_range_mut().start = 1; - vtable + + let Abi::Scalar(metadata) = metadata_layout.abi else { + return Err(LayoutError::Unknown(unsized_part)); + }; + metadata + } else { + match unsized_part.kind() { + ty::Foreign(..) => { + return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + } + ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), + ty::Dynamic(..) => { + let mut vtable = scalar_unit(Pointer); + vtable.valid_range_mut().start = 1; + vtable + } + _ => { + return Err(LayoutError::Unknown(unsized_part)); + } } - _ => return Err(LayoutError::Unknown(unsized_part)), }; // Effectively a (ptr, meta) tuple. @@ -489,8 +509,8 @@ enum SavedLocalEligibility { // of any variant. /// Compute the eligibility and assignment of each local. -fn generator_saved_local_eligibility<'tcx>( - info: &GeneratorLayout<'tcx>, +fn generator_saved_local_eligibility( + info: &GeneratorLayout<'_>, ) -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) { use SavedLocalEligibility::*; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 5279fc69a31..87923ebbe4b 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; +use rustc_session::config::TraitSolver; use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>( @@ -121,7 +122,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // are any errors at that point, so outside of type inference you can be // sure that this will succeed without errors anyway. - if tcx.sess.opts.unstable_opts.chalk { + if tcx.sess.opts.unstable_opts.trait_solver == TraitSolver::Chalk { let environment = well_formed_types_in_env(tcx, def_id); predicates.extend(environment); } @@ -161,7 +162,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..), .. }) => { - let parent_hir_id = tcx.hir().get_parent_node(hir_id); + let parent_hir_id = tcx.hir().parent_id(hir_id); match tcx.hir().get(parent_hir_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), @@ -225,10 +226,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { /// that are assumed to be well-formed (because they come from the environment). /// /// Used only in chalk mode. -fn well_formed_types_in_env<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: DefId, -) -> &'tcx ty::List<Predicate<'tcx>> { +fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Predicate<'_>> { use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind}; use rustc_middle::ty::subst::GenericArgKind; |
