Skip to content

Commit 76101ee

Browse files
committed
Auto merge of rust-lang#119722 - matthiaskrgr:rollup-y6w3c9h, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#116129 (Rewrite `pin` module documentation to clarify usage and invariants) - rust-lang#119703 (Impl trait diagnostic tweaks) - rust-lang#119705 (Support `~const` in associated functions in trait impls) - rust-lang#119708 (Unions are not `PointerLike`) - rust-lang#119711 (Delete unused makefile in tests/ui) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 75c68cf + bf20ade commit 76101ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1499
-597
lines changed

compiler/rustc_ast_lowering/messages.ftl

+2-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ ast_lowering_misplaced_double_dot =
106106
.note = only allowed in tuple, tuple struct, and slice patterns
107107
108108
ast_lowering_misplaced_impl_trait =
109-
`impl Trait` only allowed in function and inherent method argument and return types, not in {$position}
109+
`impl Trait` is not allowed in {$position}
110+
.note = `impl Trait` is only allowed in arguments and return types of functions and methods
110111
111112
ast_lowering_misplaced_relax_trait_bound =
112113
`?Trait` bounds are only permitted at the point where a type parameter is declared

compiler/rustc_ast_lowering/src/errors.rs

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub enum AssocTyParenthesesSub {
9090

9191
#[derive(Diagnostic)]
9292
#[diag(ast_lowering_misplaced_impl_trait, code = "E0562")]
93+
#[note]
9394
pub struct MisplacedImplTrait<'a> {
9495
#[primary_span]
9596
pub span: Span,

compiler/rustc_ast_lowering/src/item.rs

+23-16
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_hir::def::{DefKind, Res};
1212
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
1313
use rustc_hir::PredicateOrigin;
1414
use rustc_index::{Idx, IndexSlice, IndexVec};
15+
use rustc_middle::span_bug;
1516
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
1617
use rustc_span::edit_distance::find_best_match_for_name;
1718
use rustc_span::symbol::{kw, sym, Ident};
@@ -182,7 +183,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
182183
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
183184
}
184185
ItemKind::Static(box ast::StaticItem { ty: t, mutability: m, expr: e }) => {
185-
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
186+
let (ty, body_id) =
187+
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
186188
hir::ItemKind::Static(ty, *m, body_id)
187189
}
188190
ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
@@ -191,7 +193,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
191193
Const::No,
192194
id,
193195
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
194-
|this| this.lower_const_item(ty, span, expr.as_deref()),
196+
|this| {
197+
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
198+
},
195199
);
196200
hir::ItemKind::Const(ty, generics, body_id)
197201
}
@@ -448,8 +452,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
448452
ty: &Ty,
449453
span: Span,
450454
body: Option<&Expr>,
455+
impl_trait_position: ImplTraitPosition,
451456
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
452-
let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
457+
let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(impl_trait_position));
453458
(ty, self.lower_const_body(span, body))
454459
}
455460

@@ -572,23 +577,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
572577
// This is used to track which lifetimes have already been defined,
573578
// and which need to be replicated when lowering an async fn.
574579

575-
match parent_hir.node().expect_item().kind {
580+
let generics = match parent_hir.node().expect_item().kind {
576581
hir::ItemKind::Impl(impl_) => {
577582
self.is_in_trait_impl = impl_.of_trait.is_some();
583+
&impl_.generics
578584
}
579-
hir::ItemKind::Trait(_, _, generics, _, _) if self.tcx.features().effects => {
580-
self.host_param_id = generics
581-
.params
582-
.iter()
583-
.find(|param| {
584-
matches!(
585-
param.kind,
586-
hir::GenericParamKind::Const { is_host_effect: true, .. }
587-
)
588-
})
589-
.map(|param| param.def_id);
585+
hir::ItemKind::Trait(_, _, generics, _, _) => generics,
586+
kind => {
587+
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
590588
}
591-
_ => {}
589+
};
590+
591+
if self.tcx.features().effects {
592+
self.host_param_id = generics
593+
.params
594+
.iter()
595+
.find(|param| {
596+
matches!(param.kind, hir::GenericParamKind::Const { is_host_effect: true, .. })
597+
})
598+
.map(|param| param.def_id);
592599
}
593600

594601
match ctxt {

compiler/rustc_ast_lowering/src/lib.rs

+37-55
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,6 @@ enum ImplTraitPosition {
304304
ClosureParam,
305305
PointerParam,
306306
FnTraitParam,
307-
TraitParam,
308-
ImplParam,
309307
ExternFnReturn,
310308
ClosureReturn,
311309
PointerReturn,
@@ -324,29 +322,27 @@ impl std::fmt::Display for ImplTraitPosition {
324322
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
325323
let name = match self {
326324
ImplTraitPosition::Path => "paths",
327-
ImplTraitPosition::Variable => "variable bindings",
325+
ImplTraitPosition::Variable => "the type of variable bindings",
328326
ImplTraitPosition::Trait => "traits",
329327
ImplTraitPosition::AsyncBlock => "async blocks",
330328
ImplTraitPosition::Bound => "bounds",
331329
ImplTraitPosition::Generic => "generics",
332-
ImplTraitPosition::ExternFnParam => "`extern fn` params",
333-
ImplTraitPosition::ClosureParam => "closure params",
334-
ImplTraitPosition::PointerParam => "`fn` pointer params",
335-
ImplTraitPosition::FnTraitParam => "`Fn` trait params",
336-
ImplTraitPosition::TraitParam => "trait method params",
337-
ImplTraitPosition::ImplParam => "`impl` method params",
330+
ImplTraitPosition::ExternFnParam => "`extern fn` parameters",
331+
ImplTraitPosition::ClosureParam => "closure parameters",
332+
ImplTraitPosition::PointerParam => "`fn` pointer parameters",
333+
ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",
338334
ImplTraitPosition::ExternFnReturn => "`extern fn` return types",
339335
ImplTraitPosition::ClosureReturn => "closure return types",
340336
ImplTraitPosition::PointerReturn => "`fn` pointer return types",
341-
ImplTraitPosition::FnTraitReturn => "`Fn` trait return types",
337+
ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",
342338
ImplTraitPosition::GenericDefault => "generic parameter defaults",
343339
ImplTraitPosition::ConstTy => "const types",
344340
ImplTraitPosition::StaticTy => "static types",
345341
ImplTraitPosition::AssocTy => "associated types",
346342
ImplTraitPosition::FieldTy => "field types",
347-
ImplTraitPosition::Cast => "cast types",
343+
ImplTraitPosition::Cast => "cast expression types",
348344
ImplTraitPosition::ImplSelf => "impl headers",
349-
ImplTraitPosition::OffsetOf => "`offset_of!` params",
345+
ImplTraitPosition::OffsetOf => "`offset_of!` parameters",
350346
};
351347

352348
write!(f, "{name}")
@@ -364,19 +360,6 @@ enum FnDeclKind {
364360
Impl,
365361
}
366362

367-
impl FnDeclKind {
368-
fn param_impl_trait_allowed(&self) -> bool {
369-
matches!(self, FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait)
370-
}
371-
372-
fn return_impl_trait_allowed(&self) -> bool {
373-
match self {
374-
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true,
375-
_ => false,
376-
}
377-
}
378-
}
379-
380363
#[derive(Copy, Clone)]
381364
enum AstOwner<'a> {
382365
NonOwner,
@@ -1842,19 +1825,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18421825
inputs = &inputs[..inputs.len() - 1];
18431826
}
18441827
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1845-
let itctx = if kind.param_impl_trait_allowed() {
1846-
ImplTraitContext::Universal
1847-
} else {
1848-
ImplTraitContext::Disallowed(match kind {
1849-
FnDeclKind::Fn | FnDeclKind::Inherent => {
1850-
unreachable!("fn should allow APIT")
1851-
}
1852-
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
1853-
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
1854-
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
1855-
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
1856-
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
1857-
})
1828+
let itctx = match kind {
1829+
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1830+
ImplTraitContext::Universal
1831+
}
1832+
FnDeclKind::ExternFn => {
1833+
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1834+
}
1835+
FnDeclKind::Closure => {
1836+
ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1837+
}
1838+
FnDeclKind::Pointer => {
1839+
ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1840+
}
18581841
};
18591842
self.lower_ty_direct(&param.ty, &itctx)
18601843
}));
@@ -1866,26 +1849,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18661849
}
18671850
None => match &decl.output {
18681851
FnRetTy::Ty(ty) => {
1869-
let context = if kind.return_impl_trait_allowed() {
1870-
let fn_def_id = self.local_def_id(fn_node_id);
1871-
ImplTraitContext::ReturnPositionOpaqueTy {
1872-
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1852+
let itctx = match kind {
1853+
FnDeclKind::Fn
1854+
| FnDeclKind::Inherent
1855+
| FnDeclKind::Trait
1856+
| FnDeclKind::Impl => ImplTraitContext::ReturnPositionOpaqueTy {
1857+
origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)),
18731858
fn_kind: kind,
1859+
},
1860+
FnDeclKind::ExternFn => {
1861+
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1862+
}
1863+
FnDeclKind::Closure => {
1864+
ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1865+
}
1866+
FnDeclKind::Pointer => {
1867+
ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
18741868
}
1875-
} else {
1876-
ImplTraitContext::Disallowed(match kind {
1877-
FnDeclKind::Fn
1878-
| FnDeclKind::Inherent
1879-
| FnDeclKind::Trait
1880-
| FnDeclKind::Impl => {
1881-
unreachable!("fn should allow return-position impl trait in traits")
1882-
}
1883-
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn,
1884-
FnDeclKind::Closure => ImplTraitPosition::ClosureReturn,
1885-
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
1886-
})
18871869
};
1888-
hir::FnRetTy::Return(self.lower_ty(ty, &context))
1870+
hir::FnRetTy::Return(self.lower_ty(ty, &itctx))
18891871
}
18901872
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
18911873
},

compiler/rustc_target/src/abi/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ impl<'a> Layout<'a> {
120120
/// Whether the layout is from a type that implements [`std::marker::PointerLike`].
121121
///
122122
/// Currently, that means that the type is pointer-sized, pointer-aligned,
123-
/// and has a scalar ABI.
123+
/// and has a initialized (non-union), scalar ABI.
124124
pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool {
125125
self.size() == data_layout.pointer_size
126126
&& self.align().abi == data_layout.pointer_align.abi
127-
&& matches!(self.abi(), Abi::Scalar(..))
127+
&& matches!(self.abi(), Abi::Scalar(Scalar::Initialized { .. }))
128128
}
129129
}
130130

library/core/src/marker.rs

+47-24
Original file line numberDiff line numberDiff line change
@@ -899,25 +899,37 @@ marker_impls! {
899899
{T: ?Sized} &mut T,
900900
}
901901

902-
/// Types that can be safely moved after being pinned.
903-
///
904-
/// Rust itself has no notion of immovable types, and considers moves (e.g.,
905-
/// through assignment or [`mem::replace`]) to always be safe.
906-
///
907-
/// The [`Pin`][Pin] type is used instead to prevent moves through the type
908-
/// system. Pointers `P<T>` wrapped in the [`Pin<P<T>>`][Pin] wrapper can't be
909-
/// moved out of. See the [`pin` module] documentation for more information on
910-
/// pinning.
911-
///
912-
/// Implementing the `Unpin` trait for `T` lifts the restrictions of pinning off
913-
/// the type, which then allows moving `T` out of [`Pin<P<T>>`][Pin] with
914-
/// functions such as [`mem::replace`].
915-
///
916-
/// `Unpin` has no consequence at all for non-pinned data. In particular,
917-
/// [`mem::replace`] happily moves `!Unpin` data (it works for any `&mut T`, not
918-
/// just when `T: Unpin`). However, you cannot use [`mem::replace`] on data
919-
/// wrapped inside a [`Pin<P<T>>`][Pin] because you cannot get the `&mut T` you
920-
/// need for that, and *that* is what makes this system work.
902+
/// Types that do not require any pinning guarantees.
903+
///
904+
/// For information on what "pinning" is, see the [`pin` module] documentation.
905+
///
906+
/// Implementing the `Unpin` trait for `T` expresses the fact that `T` is pinning-agnostic:
907+
/// it shall not expose nor rely on any pinning guarantees. This, in turn, means that a
908+
/// `Pin`-wrapped pointer to such a type can feature a *fully unrestricted* API.
909+
/// In other words, if `T: Unpin`, a value of type `T` will *not* be bound by the invariants
910+
/// which pinning otherwise offers, even when "pinned" by a [`Pin<Ptr>`] pointing at it.
911+
/// When a value of type `T` is pointed at by a [`Pin<Ptr>`], [`Pin`] will not restrict access
912+
/// to the pointee value like it normally would, thus allowing the user to do anything that they
913+
/// normally could with a non-[`Pin`]-wrapped `Ptr` to that value.
914+
///
915+
/// The idea of this trait is to alleviate the reduced ergonomics of APIs that require the use
916+
/// of [`Pin`] for soundness for some types, but which also want to be used by other types that
917+
/// don't care about pinning. The prime example of such an API is [`Future::poll`]. There are many
918+
/// [`Future`] types that don't care about pinning. These futures can implement `Unpin` and
919+
/// therefore get around the pinning related restrictions in the API, while still allowing the
920+
/// subset of [`Future`]s which *do* require pinning to be implemented soundly.
921+
///
922+
/// For more discussion on the consequences of [`Unpin`] within the wider scope of the pinning
923+
/// system, see the [section about `Unpin`] in the [`pin` module].
924+
///
925+
/// `Unpin` has no consequence at all for non-pinned data. In particular, [`mem::replace`] happily
926+
/// moves `!Unpin` data, which would be immovable when pinned ([`mem::replace`] works for any
927+
/// `&mut T`, not just when `T: Unpin`).
928+
///
929+
/// *However*, you cannot use [`mem::replace`] on `!Unpin` data which is *pinned* by being wrapped
930+
/// inside a [`Pin<Ptr>`] pointing at it. This is because you cannot (safely) use a
931+
/// [`Pin<Ptr>`] to get an `&mut T` to its pointee value, which you would need to call
932+
/// [`mem::replace`], and *that* is what makes this system work.
921933
///
922934
/// So this, for example, can only be done on types implementing `Unpin`:
923935
///
@@ -935,11 +947,22 @@ marker_impls! {
935947
/// mem::replace(&mut *pinned_string, "other".to_string());
936948
/// ```
937949
///
938-
/// This trait is automatically implemented for almost every type.
939-
///
940-
/// [`mem::replace`]: crate::mem::replace
941-
/// [Pin]: crate::pin::Pin
942-
/// [`pin` module]: crate::pin
950+
/// This trait is automatically implemented for almost every type. The compiler is free
951+
/// to take the conservative stance of marking types as [`Unpin`] so long as all of the types that
952+
/// compose its fields are also [`Unpin`]. This is because if a type implements [`Unpin`], then it
953+
/// is unsound for that type's implementation to rely on pinning-related guarantees for soundness,
954+
/// *even* when viewed through a "pinning" pointer! It is the responsibility of the implementor of
955+
/// a type that relies upon pinning for soundness to ensure that type is *not* marked as [`Unpin`]
956+
/// by adding [`PhantomPinned`] field. For more details, see the [`pin` module] docs.
957+
///
958+
/// [`mem::replace`]: crate::mem::replace "mem replace"
959+
/// [`Future`]: crate::future::Future "Future"
960+
/// [`Future::poll`]: crate::future::Future::poll "Future poll"
961+
/// [`Pin`]: crate::pin::Pin "Pin"
962+
/// [`Pin<Ptr>`]: crate::pin::Pin "Pin"
963+
/// [`pin` module]: crate::pin "pin module"
964+
/// [section about `Unpin`]: crate::pin#unpin "pin module docs about unpin"
965+
/// [`unsafe`]: ../../std/keyword.unsafe.html "keyword unsafe"
943966
#[stable(feature = "pin", since = "1.33.0")]
944967
#[diagnostic::on_unimplemented(
945968
note = "consider using the `pin!` macro\nconsider using `Box::pin` if you need to access the pinned value outside of the current scope",

0 commit comments

Comments
 (0)