diff options
Diffstat (limited to 'compiler/rustc_ty_utils/src/abi.rs')
-rw-r--r-- | compiler/rustc_ty_utils/src/abi.rs | 73 |
1 files changed, 35 insertions, 38 deletions
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 91a505a72..35c9f95eb 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -41,7 +41,7 @@ fn fn_sig_for_fn_abi<'tcx>( // We normalize the `fn_sig` again after substituting at a later point. let mut sig = match *ty.kind() { ty::FnDef(def_id, substs) => tcx - .bound_fn_sig(def_id) + .fn_sig(def_id) .map_bound(|fn_sig| { tcx.normalize_erasing_regions(tcx.param_env(def_id), fn_sig) }) @@ -54,7 +54,7 @@ fn fn_sig_for_fn_abi<'tcx>( sig = sig.map_bound(|mut sig| { let mut inputs_and_output = sig.inputs_and_output.to_vec(); inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]); - sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); + sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); sig }); } @@ -63,14 +63,14 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Closure(def_id, substs) => { let sig = substs.as_closure().sig(); - let bound_vars = tcx.mk_bound_variable_kinds( + let bound_vars = tcx.mk_bound_variable_kinds_from_iter( sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), ); let br = ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BoundRegionKind::BrEnv, }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); + let env_region = tcx.mk_re_late_bound(ty::INNERMOST, br); let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); let sig = sig.skip_binder(); @@ -88,19 +88,18 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Generator(did, substs, _) => { let sig = substs.as_generator().poly_sig(); - let bound_vars = tcx.mk_bound_variable_kinds( + let bound_vars = tcx.mk_bound_variable_kinds_from_iter( sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), ); let br = ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BoundRegionKind::BrEnv, }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); - let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); + let env_ty = tcx.mk_mut_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), ty); let pin_did = tcx.require_lang_item(LangItem::Pin, None); let pin_adt_ref = tcx.adt_def(pin_did); - let pin_substs = tcx.intern_substs(&[env_ty.into()]); + let pin_substs = tcx.mk_substs(&[env_ty.into()]); let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs); let sig = sig.skip_binder(); @@ -112,7 +111,7 @@ fn fn_sig_for_fn_abi<'tcx>( // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>` let poll_did = tcx.require_lang_item(LangItem::Poll, None); let poll_adt_ref = tcx.adt_def(poll_did); - let poll_substs = tcx.intern_substs(&[sig.return_ty.into()]); + let poll_substs = tcx.mk_substs(&[sig.return_ty.into()]); let ret_ty = tcx.mk_adt(poll_adt_ref, poll_substs); // We have to replace the `ResumeTy` that is used for type and borrow checking @@ -134,7 +133,7 @@ fn fn_sig_for_fn_abi<'tcx>( // The signature should be `Generator::resume(_, Resume) -> GeneratorState<Yield, Return>` let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); + let state_substs = tcx.mk_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); (sig.resume_ty, ret_ty) @@ -142,8 +141,8 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Binder::bind_with_vars( tcx.mk_fn_sig( - [env_ty, resume_ty].iter(), - &ret_ty, + [env_ty, resume_ty], + ret_ty, false, hir::Unsafety::Normal, rustc_target::spec::abi::Abi::Rust, @@ -207,11 +206,8 @@ fn fn_abi_of_instance<'tcx>( let sig = fn_sig_for_fn_abi(tcx, instance, param_env); - let caller_location = if instance.def.requires_caller_location(tcx) { - Some(tcx.caller_location_ty()) - } else { - None - }; + let caller_location = + instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()); fn_abi_new_uncached( &LayoutCx { tcx, param_env }, @@ -244,7 +240,7 @@ fn adjust_for_rust_scalar<'tcx>( } // Only pointer types handled below. - let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return }; + let Scalar::Initialized { value: Pointer(_), valid_range} = scalar else { return }; if !valid_range.contains(0) { attrs.set(ArgAttribute::NonNull); @@ -254,15 +250,18 @@ fn adjust_for_rust_scalar<'tcx>( if let Some(kind) = pointee.safe { attrs.pointee_align = Some(pointee.align); - // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable - // for the entire duration of the function as they can be deallocated - // at any time. Same for shared mutable references. If LLVM had a - // way to say "dereferenceable on entry" we could use it here. + // `Box` are not necessarily dereferenceable for the entire duration of the function as + // they can be deallocated at any time. Same for non-frozen shared references (see + // <https://github.com/rust-lang/rust/pull/98017>), and for mutable references to + // potentially self-referential types (see + // <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>). If LLVM had a way + // to say "dereferenceable on entry" we could use it here. attrs.pointee_size = match kind { - PointerKind::UniqueBorrowed - | PointerKind::UniqueBorrowedPinned - | PointerKind::Frozen => pointee.size, - PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO, + PointerKind::Box { .. } + | PointerKind::SharedRef { frozen: false } + | PointerKind::MutableRef { unpin: false } => Size::ZERO, + PointerKind::SharedRef { frozen: true } + | PointerKind::MutableRef { unpin: true } => pointee.size, }; // The aliasing rules for `Box<T>` are still not decided, but currently we emit @@ -275,18 +274,16 @@ fn adjust_for_rust_scalar<'tcx>( // 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 + // `&T` where `T` contains no `UnsafeCell<U>` is immutable, 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. However this only applies to arguments, + // not return values. // - // `&T` where `T` contains no `UnsafeCell<U>` is immutable, - // 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 + // `&mut T` and `Box<T>` where `T: Unpin` are unique and hence `noalias`. let no_alias = match kind { - PointerKind::SharedMutable | PointerKind::UniqueBorrowedPinned => false, - PointerKind::UniqueBorrowed => noalias_mut_ref, - PointerKind::UniqueOwned => noalias_for_box, - PointerKind::Frozen => true, + PointerKind::SharedRef { frozen } => frozen, + PointerKind::MutableRef { unpin } => unpin && noalias_mut_ref, + PointerKind::Box { unpin } => unpin && noalias_for_box, }; // 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>). @@ -294,7 +291,7 @@ fn adjust_for_rust_scalar<'tcx>( attrs.set(ArgAttribute::NoAlias); } - if kind == PointerKind::Frozen && !is_return { + if matches!(kind, PointerKind::SharedRef { frozen: true }) && !is_return { attrs.set(ArgAttribute::ReadOnly); } } @@ -479,7 +476,7 @@ fn fn_abi_adjust_for_abi<'tcx>( } let size = arg.layout.size; - if arg.layout.is_unsized() || size > Pointer.size(cx) { + if arg.layout.is_unsized() || size > Pointer(AddressSpace::DATA).size(cx) { arg.make_indirect(); } else { // We want to pass small aggregates as immediates, but using |