Auto merge of #150726 - JonathanBrouwer:rollup-yseerwy, r=JonathanBrouwer

Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#144113 (Impls and impl items inherit `dead_code` lint level of the corresponding traits and trait items)
 - rust-lang/rust#149880 (rustc_codegen_llvm: update alignment for double on AIX)
 - rust-lang/rust#150122 (Refactor function names of `rustc_ast_lowering`)
 - rust-lang/rust#150412 (use PIDFD_GET_INFO ioctl when available)
 - rust-lang/rust#150670 (THIR pattern building: Move all `thir::Pat` creation into `rustc_mir_build::thir::pattern`)
 - rust-lang/rust#150695 (MGCA: pretty printing for struct expressions and tuple calls )
 - rust-lang/rust#150698 (Improve comment clarity in candidate_may_shadow)
 - rust-lang/rust#150706 (Update wasm-component-ld)
 - rust-lang/rust#150707 (Fix ICE when transmute Assume field is invalid)
 - rust-lang/rust#150708 (Enable merge queue in new bors)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2026-01-06 15:22:37 +00:00
commit 4d73a008ea
29 changed files with 595 additions and 206 deletions

View file

@ -6221,9 +6221,9 @@ dependencies = [
[[package]]
name = "wasi-preview1-component-adapter-provider"
version = "38.0.4"
version = "40.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ec3ef3783e18f2457796ed91b1e6c2adc46f2905f740d1527ab3053fe8e5682"
checksum = "bb5e2b9858989c3a257de4ca169977f4f79897b64e4f482f188f4fcf8ac557d1"
[[package]]
name = "wasm-bindgen"
@ -6272,17 +6272,18 @@ dependencies = [
[[package]]
name = "wasm-component-ld"
version = "0.5.19"
version = "0.5.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bfc50dd0b883d841bc1dba5ff7020ca52fa7b2c3bb1266d8bf6a09dd032e115"
checksum = "846d20ed66ae37b7a237e36dfcd2fdc979eae82a46cdb0586f9bba80782fd789"
dependencies = [
"anyhow",
"clap",
"clap_lex",
"lexopt",
"libc",
"tempfile",
"wasi-preview1-component-adapter-provider",
"wasmparser 0.241.2",
"wasmparser 0.243.0",
"wat",
"windows-sys 0.61.2",
"winsplit",
@ -6309,24 +6310,24 @@ dependencies = [
[[package]]
name = "wasm-encoder"
version = "0.241.2"
version = "0.243.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01164c9dda68301e34fdae536c23ed6fe90ce6d97213ccc171eebbd3d02d6b8"
checksum = "c55db9c896d70bd9fa535ce83cd4e1f2ec3726b0edd2142079f594fc3be1cb35"
dependencies = [
"leb128fmt",
"wasmparser 0.241.2",
"wasmparser 0.243.0",
]
[[package]]
name = "wasm-metadata"
version = "0.241.2"
version = "0.243.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876fe286f2fa416386deedebe8407e6f19e0b5aeaef3d03161e77a15fa80f167"
checksum = "eae05bf9579f45a62e8d0a4e3f52eaa8da518883ac5afa482ec8256c329ecd56"
dependencies = [
"anyhow",
"indexmap",
"wasm-encoder 0.241.2",
"wasmparser 0.241.2",
"wasm-encoder 0.243.0",
"wasmparser 0.243.0",
]
[[package]]
@ -6351,9 +6352,9 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.241.2"
version = "0.243.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46d90019b1afd4b808c263e428de644f3003691f243387d30d673211ee0cb8e8"
checksum = "f6d8db401b0528ec316dfbe579e6ab4152d61739cfe076706d2009127970159d"
dependencies = [
"bitflags",
"hashbrown 0.15.5",
@ -6364,22 +6365,22 @@ dependencies = [
[[package]]
name = "wast"
version = "241.0.2"
version = "243.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63f66e07e2ddf531fef6344dbf94d112df7c2f23ed6ffb10962e711500b8d816"
checksum = "df21d01c2d91e46cb7a221d79e58a2d210ea02020d57c092e79255cc2999ca7f"
dependencies = [
"bumpalo",
"leb128fmt",
"memchr",
"unicode-width 0.2.2",
"wasm-encoder 0.241.2",
"wasm-encoder 0.243.0",
]
[[package]]
name = "wat"
version = "1.241.2"
version = "1.243.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45f923705c40830af909c5dec2352ec2821202e4a66008194585e1917458a26d"
checksum = "226a9a91cd80a50449312fef0c75c23478fcecfcc4092bdebe1dc8e760ef521b"
dependencies = [
"wast",
]
@ -6775,9 +6776,9 @@ dependencies = [
[[package]]
name = "wit-component"
version = "0.241.2"
version = "0.243.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0c57df25e7ee612d946d3b7646c1ddb2310f8280aa2c17e543b66e0812241"
checksum = "36f9fc53513e461ce51dcf17a3e331752cb829f1d187069e54af5608fc998fe4"
dependencies = [
"anyhow",
"bitflags",
@ -6786,17 +6787,17 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"wasm-encoder 0.241.2",
"wasm-encoder 0.243.0",
"wasm-metadata",
"wasmparser 0.241.2",
"wasmparser 0.243.0",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.241.2"
version = "0.243.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ef1c6ad67f35c831abd4039c02894de97034100899614d1c44e2268ad01c91"
checksum = "df983a8608e513d8997f435bb74207bf0933d0e49ca97aa9d8a6157164b9b7fc"
dependencies = [
"anyhow",
"id-arena",
@ -6807,7 +6808,7 @@ dependencies = [
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser 0.241.2",
"wasmparser 0.243.0",
]
[[package]]

View file

@ -98,7 +98,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Let statements are allowed to have impl trait in bindings.
let super_ = l.super_.map(|span| self.lower_span(span));
let ty = l.ty.as_ref().map(|t| {
self.lower_ty(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable))
self.lower_ty_alloc(t, self.impl_trait_in_bindings_ctxt(ImplTraitPosition::Variable))
});
let init = l.kind.init().map(|init| self.lower_expr(init));
let hir_id = self.lower_node_id(l.id);

View file

@ -158,14 +158,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::Cast(expr, ty) => {
let expr = self.lower_expr(expr);
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
let ty = self
.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
hir::ExprKind::Cast(expr, ty)
}
ExprKind::Type(expr, ty) => {
let expr = self.lower_expr(expr);
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
let ty = self
.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
hir::ExprKind::Type(expr, ty)
}
ExprKind::AddrOf(k, m, ohs) => {
@ -335,7 +335,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::FormatArgs(fmt) => self.lower_format_args(e.span, fmt),
ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf(
self.lower_ty(
self.lower_ty_alloc(
container,
ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf),
),
@ -371,7 +371,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
*kind,
self.lower_expr(expr),
ty.as_ref().map(|ty| {
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast))
self.lower_ty_alloc(
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Cast),
)
}),
),
@ -617,7 +620,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
if let Some(ty) = opt_ty {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path));
let ty = self.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path));
let block_expr = self.arena.alloc(self.expr_block(whole_block));
hir::ExprKind::Type(block_expr, ty)
} else {

View file

@ -264,8 +264,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
define_opaque,
}) => {
let ident = self.lower_ident(*ident);
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let ty = self
.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let body_id = self.lower_const_body(span, e.as_deref());
self.lower_define_opaque(hir_id, define_opaque);
hir::ItemKind::Static(*m, ident, ty, body_id)
@ -279,8 +279,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = this
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let ty = this.lower_ty_alloc(
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
);
let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), span);
(ty, rhs)
},
@ -379,7 +381,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
}
Some(ty) => this.lower_ty(
Some(ty) => this.lower_ty_alloc(
ty,
ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias {
@ -453,7 +455,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
.as_deref()
.map(|of_trait| this.lower_trait_impl_header(of_trait));
let lowered_ty = this.lower_ty(
let lowered_ty = this.lower_ty_alloc(
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
);
@ -758,8 +760,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
safety,
define_opaque,
}) => {
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let ty = self
.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
if define_opaque.is_some() {
self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
@ -870,7 +872,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
(index, f): (usize, &FieldDef),
) -> hir::FieldDef<'hir> {
let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
let ty =
self.lower_ty_alloc(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs, f.span, Target::Field);
hir::FieldDef {
@ -908,8 +911,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = this
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let ty = this.lower_ty_alloc(
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
);
let rhs = rhs
.as_ref()
.map(|rhs| this.lower_const_item_rhs(attrs, Some(rhs), i.span));
@ -1008,7 +1013,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = ty.as_ref().map(|x| {
this.lower_ty(
this.lower_ty_alloc(
x,
ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
)
@ -1120,8 +1125,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = this
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let ty = this.lower_ty_alloc(
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
);
this.lower_define_opaque(hir_id, &define_opaque);
let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), i.span);
hir::ImplItemKind::Const(ty, rhs)
@ -1180,7 +1187,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Type(ty)
}
Some(ty) => {
let ty = this.lower_ty(
let ty = this.lower_ty_alloc(
ty,
ImplTraitContext::OpaqueTy {
origin: hir::OpaqueTyOrigin::TyAlias {
@ -1916,7 +1923,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
bound_generic_params,
hir::GenericParamSource::Binder,
),
bounded_ty: self.lower_ty(
bounded_ty: self.lower_ty_alloc(
bounded_ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
@ -1945,10 +1952,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
lhs_ty: self
.lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
rhs_ty: self
.lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
lhs_ty: self.lower_ty_alloc(
lhs_ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
rhs_ty: self.lower_ty_alloc(
rhs_ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
})
}
});

View file

@ -1125,8 +1125,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let kind = match &constraint.kind {
AssocItemConstraintKind::Equality { term } => {
let term = match term {
Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(),
Term::Const(c) => self.lower_anon_const_to_const_arg_and_alloc(c).into(),
};
hir::AssocItemConstraintKind::Equality { term }
}
@ -1250,17 +1250,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
_ => {}
}
GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
}
ast::GenericArg::Const(ct) => {
GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap())
}
ast::GenericArg::Const(ct) => GenericArg::Const(
self.lower_anon_const_to_const_arg_and_alloc(ct).try_as_ambig_ct().unwrap(),
),
}
}
#[instrument(level = "debug", skip(self))]
fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
self.arena.alloc(self.lower_ty_direct(t, itctx))
fn lower_ty_alloc(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
self.arena.alloc(self.lower_ty(t, itctx))
}
fn lower_path_ty(
@ -1324,11 +1324,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.ty(span, hir::TyKind::Tup(tys))
}
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
let kind = match &t.kind {
TyKind::Infer => hir::TyKind::Infer(()),
TyKind::Err(guar) => hir::TyKind::Err(*guar),
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)),
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
TyKind::Ref(region, mt) => {
let lifetime = self.lower_ty_direct_lifetime(t, *region);
@ -1362,15 +1362,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
generic_params,
inner_ty: self.lower_ty(&f.inner_ty, itctx),
inner_ty: self.lower_ty_alloc(&f.inner_ty, itctx),
}))
}
TyKind::Never => hir::TyKind::Never,
TyKind::Tup(tys) => hir::TyKind::Tup(
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty(ty, itctx))),
),
TyKind::Paren(ty) => {
return self.lower_ty_direct(ty, itctx);
return self.lower_ty(ty, itctx);
}
TyKind::Path(qself, path) => {
return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
@ -1393,7 +1393,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
))
}
TyKind::Array(ty, length) => hir::TyKind::Array(
self.lower_ty(ty, itctx),
self.lower_ty_alloc(ty, itctx),
self.lower_array_length_to_const_arg(length),
),
TyKind::TraitObject(bounds, kind) => {
@ -1493,7 +1493,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
TyKind::Pat(ty, pat) => {
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))
}
TyKind::MacCall(_) => {
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
@ -1693,7 +1693,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
}
};
self.lower_ty_direct(&param.ty, itctx)
self.lower_ty(&param.ty, itctx)
}));
let output = match coro {
@ -1732,7 +1732,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
}
};
hir::FnRetTy::Return(self.lower_ty(ty, itctx))
hir::FnRetTy::Return(self.lower_ty_alloc(ty, itctx))
}
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
},
@ -1843,7 +1843,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
// `impl Future` opaque type that `async fn` implicitly
// generates.
self.lower_ty(ty, itctx)
self.lower_ty_alloc(ty, itctx)
}
FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
};
@ -2036,7 +2036,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
})
.map(|def| {
self.lower_ty(
self.lower_ty_alloc(
def,
ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
)
@ -2047,8 +2047,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
}
GenericParamKind::Const { ty, span: _, default } => {
let ty = self
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
let ty = self.lower_ty_alloc(
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
);
// Not only do we deny const param defaults in binders but we also map them to `None`
// since later compiler stages cannot handle them (and shouldn't need to be able to).
@ -2064,7 +2066,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
false
}
})
.map(|def| self.lower_anon_const_to_const_arg(def));
.map(|def| self.lower_anon_const_to_const_arg_and_alloc(def));
(
hir::ParamName::Plain(self.lower_ident(param.ident)),
@ -2198,7 +2200,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
hir::MutTy { ty: self.lower_ty_alloc(&mt.ty, itctx), mutbl: mt.mutbl }
}
#[instrument(level = "debug", skip(self), ret)]
@ -2286,7 +2288,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
}
_ => self.lower_anon_const_to_const_arg(c),
_ => self.lower_anon_const_to_const_arg_and_alloc(c),
}
}
@ -2365,7 +2367,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::ConstItemRhs<'hir> {
match rhs {
Some(ConstItemRhs::TypeConst(anon)) => {
hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg(anon))
hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon))
}
None if attr::contains_name(attrs, sym::type_const) => {
let const_arg = ConstArg {
@ -2412,7 +2414,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let def_id = self.local_def_id(anon_const.id);
let def_kind = self.tcx.def_kind(def_id);
assert_eq!(DefKind::AnonConst, def_kind);
self.lower_anon_const_to_const_arg_direct(anon_const)
self.lower_anon_const_to_const_arg(anon_const)
} else {
self.lower_expr_to_const_arg_direct(arg)
};
@ -2465,7 +2467,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let def_kind = self.tcx.def_kind(def_id);
assert_eq!(DefKind::AnonConst, def_kind);
self.lower_anon_const_to_const_arg_direct(anon_const)
self.lower_anon_const_to_const_arg(anon_const)
} else {
self.lower_expr_to_const_arg_direct(&f.expr)
};
@ -2506,12 +2508,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// See [`hir::ConstArg`] for when to use this function vs
/// [`Self::lower_anon_const_to_anon_const`].
fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
fn lower_anon_const_to_const_arg_and_alloc(
&mut self,
anon: &AnonConst,
) -> &'hir hir::ConstArg<'hir> {
self.arena.alloc(self.lower_anon_const_to_const_arg(anon))
}
#[instrument(level = "debug", skip(self))]
fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
let tcx = self.tcx;
// We cannot change parsing depending on feature gates available,

View file

@ -444,16 +444,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let pat_hir_id = self.lower_node_id(pattern.id);
let node = match &pattern.kind {
TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range(
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| {
self.lower_ty_pat_range_end(
hir::LangItem::RangeMin,
span.shrink_to_lo(),
base_type,
)
}),
e1.as_deref()
.map(|e| self.lower_anon_const_to_const_arg_and_alloc(e))
.unwrap_or_else(|| {
self.lower_ty_pat_range_end(
hir::LangItem::RangeMin,
span.shrink_to_lo(),
base_type,
)
}),
e2.as_deref()
.map(|e| match end {
RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e),
RangeEnd::Included(..) => self.lower_anon_const_to_const_arg_and_alloc(e),
RangeEnd::Excluded => self.lower_excluded_range_end(e),
})
.unwrap_or_else(|| {

View file

@ -36,7 +36,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let qself = qself
.as_ref()
// Reject cases like `<impl Trait>::Assoc` and `<impl Trait as Trait>::Assoc`.
.map(|q| self.lower_ty(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)));
.map(|q| {
self.lower_ty_alloc(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path))
});
let partial_res =
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
@ -510,7 +512,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// we generally don't permit such things (see #51008).
let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
}));
let output_ty = match output {
// Only allow `impl Trait` in return position. i.e.:
@ -520,9 +522,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// ```
FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => {
if self.tcx.features().impl_trait_in_fn_trait_return() {
self.lower_ty(ty, itctx)
self.lower_ty_alloc(ty, itctx)
} else {
self.lower_ty(
self.lower_ty_alloc(
ty,
ImplTraitContext::FeatureGated(
ImplTraitPosition::FnTraitReturn,
@ -531,9 +533,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}
}
FnRetTy::Ty(ty) => {
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
}
FnRetTy::Ty(ty) => self
.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
};
let args = smallvec![GenericArg::Type(

View file

@ -211,6 +211,10 @@ pub(crate) unsafe fn create_module<'ll>(
// LLVM 22 updated the NVPTX layout to indicate 256-bit vector load/store: https://github.com/llvm/llvm-project/pull/155198
target_data_layout = target_data_layout.replace("-i256:256", "");
}
if sess.target.arch == Arch::PowerPC64 {
// LLVM 22 updated the ABI alignment for double on AIX: https://github.com/llvm/llvm-project/pull/144673
target_data_layout = target_data_layout.replace("-f64:32:64", "");
}
}
// Ensure the data-layout values hardcoded remain the defaults.

View file

@ -17,9 +17,9 @@ use rustc_ast_pretty::pprust::state::MacHeader;
use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir::attrs::{AttributeKind, PrintAttribute};
use rustc_hir::{
BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term,
TyPatKind,
BindingMode, ByRef, ConstArg, ConstArgExprField, ConstArgKind, GenericArg, GenericBound,
GenericParam, GenericParamKind, HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind,
PreciseCapturingArg, RangeEnd, Term, TyPatKind,
};
use rustc_span::source_map::SourceMap;
use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym};
@ -1141,9 +1141,8 @@ impl<'a> State<'a> {
fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) {
match &const_arg.kind {
// FIXME(mgca): proper printing for struct exprs
ConstArgKind::Struct(..) => self.word("/* STRUCT EXPR */"),
ConstArgKind::TupleCall(..) => self.word("/* TUPLE CALL */"),
ConstArgKind::Struct(qpath, fields) => self.print_const_struct(qpath, fields),
ConstArgKind::TupleCall(qpath, args) => self.print_const_ctor(qpath, args),
ConstArgKind::Path(qpath) => self.print_qpath(qpath, true),
ConstArgKind::Anon(anon) => self.print_anon_const(anon),
ConstArgKind::Error(_, _) => self.word("/*ERROR*/"),
@ -1151,6 +1150,31 @@ impl<'a> State<'a> {
}
}
fn print_const_struct(&mut self, qpath: &hir::QPath<'_>, fields: &&[&ConstArgExprField<'_>]) {
self.print_qpath(qpath, true);
self.word(" ");
self.word("{");
if !fields.is_empty() {
self.nbsp();
}
self.commasep(Inconsistent, *fields, |s, field| {
s.word(field.field.as_str().to_string());
s.word(":");
s.nbsp();
s.print_const_arg(field.expr);
});
self.word("}");
}
fn print_const_ctor(&mut self, qpath: &hir::QPath<'_>, args: &&[&ConstArg<'_, ()>]) {
self.print_qpath(qpath, true);
self.word("(");
self.commasep(Inconsistent, *args, |s, arg| {
s.print_const_arg(arg);
});
self.word(")");
}
fn print_call_post(&mut self, args: &[hir::Expr<'_>]) {
self.popen();
self.commasep_exprs(Inconsistent, args);

View file

@ -190,8 +190,8 @@ impl PickConstraintsForShadowed {
// An item never shadows itself
candidate.item.def_id != self.def_id
// and we're only concerned about inherent impls doing the shadowing.
// Shadowing can only occur if the shadowed is further along
// the Receiver dereferencing chain than the shadowed.
// Shadowing can only occur if the impl being shadowed is further along
// the Receiver dereferencing chain than the impl doing the shadowing.
&& match candidate.kind {
CandidateKind::InherentImplCandidate { receiver_steps, .. } => match self.receiver_steps {
Some(shadowed_receiver_steps) => receiver_steps > shadowed_receiver_steps,

View file

@ -2,8 +2,6 @@ use rustc_hir as hir;
use rustc_index::Idx;
use rustc_middle::middle::region;
use rustc_middle::thir::*;
use rustc_middle::ty;
use rustc_middle::ty::CanonicalUserTypeAnnotation;
use tracing::debug;
use crate::thir::cx::ThirBuildCx;
@ -73,29 +71,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
let else_block = local.els.map(|els| self.mirror_block(els));
let mut pattern = self.pattern_from_hir(local.pat);
let pattern = self.pattern_from_hir_with_annotation(local.pat, local.ty);
debug!(?pattern);
if let Some(ty) = &local.ty
&& let Some(&user_ty) =
self.typeck_results.user_provided_types().get(ty.hir_id)
{
debug!("mirror_stmts: user_ty={:?}", user_ty);
let annotation = CanonicalUserTypeAnnotation {
user_ty: Box::new(user_ty),
span: ty.span,
inferred_ty: self.typeck_results.node_type(ty.hir_id),
};
pattern = Box::new(Pat {
ty: pattern.ty,
span: pattern.span,
kind: PatKind::AscribeUserType {
ascription: Ascription { annotation, variance: ty::Covariant },
subpattern: pattern,
},
});
}
let span = match local.init {
Some(init) => local.span.with_hi(init.span.hi()),
None => local.span,

View file

@ -12,9 +12,6 @@ use rustc_hir::{self as hir, HirId, find_attr};
use rustc_middle::bug;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, TyCtxt};
use tracing::instrument;
use crate::thir::pattern::pat_from_hir;
/// Query implementation for [`TyCtxt::thir_body`].
pub(crate) fn thir_body(
@ -111,9 +108,22 @@ impl<'tcx> ThirBuildCx<'tcx> {
}
}
#[instrument(level = "debug", skip(self))]
fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
pat_from_hir(self.tcx, self.typing_env, self.typeck_results, p)
fn pattern_from_hir(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
self.pattern_from_hir_with_annotation(pat, None)
}
fn pattern_from_hir_with_annotation(
&mut self,
pat: &'tcx hir::Pat<'tcx>,
let_stmt_type: Option<&hir::Ty<'tcx>>,
) -> Box<Pat<'tcx>> {
crate::thir::pattern::pat_from_hir(
self.tcx,
self.typing_env,
self.typeck_results,
pat,
let_stmt_type,
)
}
fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {

View file

@ -39,11 +39,14 @@ struct PatCtxt<'tcx> {
rust_2024_migration: Option<PatMigration<'tcx>>,
}
#[instrument(level = "debug", skip(tcx, typing_env, typeck_results), ret)]
pub(super) fn pat_from_hir<'tcx>(
tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
pat: &'tcx hir::Pat<'tcx>,
// Present if `pat` came from a let statement with an explicit type annotation
let_stmt_type: Option<&hir::Ty<'tcx>>,
) -> Box<Pat<'tcx>> {
let mut pcx = PatCtxt {
tcx,
@ -54,12 +57,35 @@ pub(super) fn pat_from_hir<'tcx>(
.get(pat.hir_id)
.map(PatMigration::new),
};
let result = pcx.lower_pattern(pat);
debug!("pat_from_hir({:?}) = {:?}", pat, result);
let mut thir_pat = pcx.lower_pattern(pat);
// If this pattern came from a let statement with an explicit type annotation
// (e.g. `let x: Foo = ...`), retain that user type information in the THIR pattern.
if let Some(let_stmt_type) = let_stmt_type
&& let Some(&user_ty) = typeck_results.user_provided_types().get(let_stmt_type.hir_id)
{
debug!(?user_ty);
let annotation = CanonicalUserTypeAnnotation {
user_ty: Box::new(user_ty),
span: let_stmt_type.span,
inferred_ty: typeck_results.node_type(let_stmt_type.hir_id),
};
thir_pat = Box::new(Pat {
ty: thir_pat.ty,
span: thir_pat.span,
kind: PatKind::AscribeUserType {
ascription: Ascription { annotation, variance: ty::Covariant },
subpattern: thir_pat,
},
});
}
if let Some(m) = pcx.rust_2024_migration {
m.emit(tcx, pat.hir_id);
}
result
thir_pat
}
impl<'tcx> PatCtxt<'tcx> {

View file

@ -778,6 +778,15 @@ fn maybe_record_as_seed<'tcx>(
match tcx.def_kind(parent) {
DefKind::Impl { of_trait: false } | DefKind::Trait => {}
DefKind::Impl { of_trait: true } => {
if let Some(trait_item_def_id) =
tcx.associated_item(owner_id.def_id).trait_item_def_id()
&& let Some(trait_item_local_def_id) = trait_item_def_id.as_local()
&& let Some(comes_from_allow) =
has_allow_dead_code_or_lang_attr(tcx, trait_item_local_def_id)
{
worklist.push((owner_id.def_id, comes_from_allow));
}
// We only care about associated items of traits,
// because they cannot be visited directly,
// so we later mark them as live if their corresponding traits
@ -791,6 +800,14 @@ fn maybe_record_as_seed<'tcx>(
}
DefKind::Impl { of_trait: true } => {
if allow_dead_code.is_none() {
if let Some(trait_def_id) =
tcx.impl_trait_ref(owner_id.def_id).skip_binder().def_id.as_local()
&& let Some(comes_from_allow) =
has_allow_dead_code_or_lang_attr(tcx, trait_def_id)
{
worklist.push((owner_id.def_id, comes_from_allow));
}
unsolved_items.push(owner_id.def_id);
}
}

View file

@ -17,7 +17,8 @@ pub(crate) fn target() -> Target {
std: None, // ?
},
pointer_width: 64,
data_layout: "E-m:a-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512".into(),
data_layout: "E-m:a-Fi64-i64:64-i128:128-n32:64-f64:32:64-S128-v256:256:256-v512:512:512"
.into(),
arch: Arch::PowerPC64,
options: base,
}

View file

@ -155,14 +155,14 @@ mod rustc {
.enumerate()
.find(|(_, field_def)| name == field_def.name)
.unwrap_or_else(|| panic!("There were no fields named `{name}`."));
fields[field_idx].to_leaf() == ScalarInt::TRUE
fields[field_idx].try_to_leaf().map(|leaf| leaf == ScalarInt::TRUE)
};
Some(Self {
alignment: get_field(sym::alignment),
lifetimes: get_field(sym::lifetimes),
safety: get_field(sym::safety),
validity: get_field(sym::validity),
alignment: get_field(sym::alignment)?,
lifetimes: get_field(sym::lifetimes)?,
safety: get_field(sym::safety)?,
validity: get_field(sym::validity)?,
})
}
}

View file

@ -67,8 +67,10 @@ impl PidFd {
/// Waits for the child to exit completely, returning the status that it exited with.
///
/// Unlike [`Child::wait`] it does not ensure that the stdin handle is closed.
/// Additionally it will not return an `ExitStatus` if the child
/// has already been reaped. Instead an error will be returned.
///
/// Additionally on kernels prior to 6.15 only the first attempt to
/// reap a child will return an ExitStatus, further attempts
/// will return an Error.
///
/// [`Child::wait`]: process::Child::wait
pub fn wait(&self) -> Result<ExitStatus> {
@ -77,8 +79,8 @@ impl PidFd {
/// Attempts to collect the exit status of the child if it has already exited.
///
/// Unlike [`Child::try_wait`] this method will return an Error
/// if the child has already been reaped.
/// On kernels prior to 6.15, and unlike [`Child::try_wait`], only the first attempt
/// to reap a child will return an ExitStatus, further attempts will return an Error.
///
/// [`Child::try_wait`]: process::Child::try_wait
pub fn try_wait(&self) -> Result<Option<ExitStatus>> {

View file

@ -1,5 +1,5 @@
use crate::io;
use crate::os::fd::{AsRawFd, FromRawFd, RawFd};
use crate::os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::sys::fd::FileDesc;
use crate::sys::process::ExitStatus;
use crate::sys::{AsInner, FromInner, IntoInner, cvt};
@ -15,6 +15,73 @@ impl PidFd {
self.send_signal(libc::SIGKILL)
}
#[cfg(any(test, target_env = "gnu", target_env = "musl"))]
pub(crate) fn current_process() -> io::Result<PidFd> {
let pid = crate::process::id();
let pidfd = cvt(unsafe { libc::syscall(libc::SYS_pidfd_open, pid, 0) })?;
Ok(unsafe { PidFd::from_raw_fd(pidfd as RawFd) })
}
#[cfg(any(test, target_env = "gnu", target_env = "musl"))]
pub(crate) fn pid(&self) -> io::Result<u32> {
use crate::sys::weak::weak;
// since kernel 6.13
// https://lore.kernel.org/all/20241010155401.2268522-1-luca.boccassi@gmail.com/
let mut pidfd_info: libc::pidfd_info = unsafe { crate::mem::zeroed() };
pidfd_info.mask = libc::PIDFD_INFO_PID as u64;
match cvt(unsafe { libc::ioctl(self.0.as_raw_fd(), libc::PIDFD_GET_INFO, &mut pidfd_info) })
{
Ok(_) => {}
Err(e) if e.raw_os_error() == Some(libc::EINVAL) => {
// kernel doesn't support that ioctl, try the glibc helper that looks at procfs
weak!(
fn pidfd_getpid(pidfd: RawFd) -> libc::pid_t;
);
if let Some(pidfd_getpid) = pidfd_getpid.get() {
let pid: libc::c_int = cvt(unsafe { pidfd_getpid(self.0.as_raw_fd()) })?;
return Ok(pid as u32);
}
return Err(e);
}
Err(e) => return Err(e),
}
Ok(pidfd_info.pid)
}
fn exit_for_reaped_child(&self) -> io::Result<ExitStatus> {
// since kernel 6.15
// https://lore.kernel.org/linux-fsdevel/20250305-work-pidfs-kill_on_last_close-v3-0-c8c3d8361705@kernel.org/T/
let mut pidfd_info: libc::pidfd_info = unsafe { crate::mem::zeroed() };
pidfd_info.mask = libc::PIDFD_INFO_EXIT as u64;
cvt(unsafe { libc::ioctl(self.0.as_raw_fd(), libc::PIDFD_GET_INFO, &mut pidfd_info) })?;
Ok(ExitStatus::new(pidfd_info.exit_code))
}
fn waitid(&self, options: libc::c_int) -> io::Result<Option<ExitStatus>> {
let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() };
let r = cvt(unsafe {
libc::waitid(libc::P_PIDFD, self.0.as_raw_fd() as u32, &mut siginfo, options)
});
match r {
Err(waitid_err) if waitid_err.raw_os_error() == Some(libc::ECHILD) => {
// already reaped
match self.exit_for_reaped_child() {
Ok(exit_status) => return Ok(Some(exit_status)),
Err(_) => return Err(waitid_err),
}
}
Err(e) => return Err(e),
Ok(_) => {}
}
if unsafe { siginfo.si_pid() } == 0 {
Ok(None)
} else {
Ok(Some(ExitStatus::from_waitid_siginfo(siginfo)))
}
}
pub(crate) fn send_signal(&self, signal: i32) -> io::Result<()> {
cvt(unsafe {
libc::syscall(
@ -29,29 +96,15 @@ impl PidFd {
}
pub fn wait(&self) -> io::Result<ExitStatus> {
let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() };
cvt(unsafe {
libc::waitid(libc::P_PIDFD, self.0.as_raw_fd() as u32, &mut siginfo, libc::WEXITED)
})?;
Ok(ExitStatus::from_waitid_siginfo(siginfo))
let r = self.waitid(libc::WEXITED)?;
match r {
Some(exit_status) => Ok(exit_status),
None => unreachable!("waitid with WEXITED should not return None"),
}
}
pub fn try_wait(&self) -> io::Result<Option<ExitStatus>> {
let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() };
cvt(unsafe {
libc::waitid(
libc::P_PIDFD,
self.0.as_raw_fd() as u32,
&mut siginfo,
libc::WEXITED | libc::WNOHANG,
)
})?;
if unsafe { siginfo.si_pid() } == 0 {
Ok(None)
} else {
Ok(Some(ExitStatus::from_waitid_siginfo(siginfo)))
}
self.waitid(libc::WEXITED | libc::WNOHANG)
}
}
@ -78,3 +131,9 @@ impl FromRawFd for PidFd {
Self(FileDesc::from_raw_fd(fd))
}
}
impl IntoRawFd for PidFd {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}

View file

@ -1,8 +1,11 @@
use super::PidFd as InternalPidFd;
use crate::assert_matches::assert_matches;
use crate::os::fd::{AsRawFd, RawFd};
use crate::io::ErrorKind;
use crate::os::fd::AsRawFd;
use crate::os::linux::process::{ChildExt, CommandExt as _};
use crate::os::unix::process::{CommandExt as _, ExitStatusExt};
use crate::process::Command;
use crate::sys::AsInner;
#[test]
fn test_command_pidfd() {
@ -48,11 +51,22 @@ fn test_command_pidfd() {
let mut cmd = Command::new("false");
let mut child = unsafe { cmd.pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap();
assert!(child.id() > 0 && child.id() < -1i32 as u32);
let id = child.id();
assert!(id > 0 && id < -1i32 as u32, "spawning with pidfd still returns a sane pid");
if pidfd_open_available {
assert!(child.pidfd().is_ok())
}
if let Ok(pidfd) = child.pidfd() {
match pidfd.as_inner().pid() {
Ok(pid) => assert_eq!(pid, id),
Err(e) if e.kind() == ErrorKind::InvalidInput => { /* older kernel */ }
Err(e) => panic!("unexpected error getting pid from pidfd: {}", e),
}
}
child.wait().expect("error waiting on child");
}
@ -77,9 +91,15 @@ fn test_pidfd() {
assert_eq!(status.signal(), Some(libc::SIGKILL));
// Trying to wait again for a reaped child is safe since there's no pid-recycling race.
// But doing so will return an error.
// But doing so may return an error.
let res = fd.wait();
assert_matches!(res, Err(e) if e.raw_os_error() == Some(libc::ECHILD));
match res {
// older kernels
Err(e) if e.raw_os_error() == Some(libc::ECHILD) => {}
// 6.15+
Ok(exit) if exit.signal() == Some(libc::SIGKILL) => {}
other => panic!("expected ECHILD error, got {:?}", other),
}
// Ditto for additional attempts to kill an already-dead child.
let res = fd.kill();
@ -87,13 +107,5 @@ fn test_pidfd() {
}
fn probe_pidfd_support() -> bool {
// pidfds require the pidfd_open syscall
let our_pid = crate::process::id();
let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) };
if pidfd >= 0 {
unsafe { libc::close(pidfd as RawFd) };
true
} else {
false
}
InternalPidFd::current_process().is_ok()
}

View file

@ -482,10 +482,6 @@ impl Command {
) -> libc::c_int;
);
weak!(
fn pidfd_getpid(pidfd: libc::c_int) -> libc::c_int;
);
static PIDFD_SUPPORTED: Atomic<u8> = AtomicU8::new(0);
const UNKNOWN: u8 = 0;
const SPAWN: u8 = 1;
@ -502,24 +498,26 @@ impl Command {
}
if support == UNKNOWN {
support = NO;
let our_pid = crate::process::id();
let pidfd = cvt(unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) } as c_int);
match pidfd {
match PidFd::current_process() {
Ok(pidfd) => {
// if pidfd_open works then we at least know the fork path is available.
support = FORK_EXEC;
if let Some(Ok(pid)) = pidfd_getpid.get().map(|f| cvt(unsafe { f(pidfd) } as i32)) {
if pidfd_spawnp.get().is_some() && pid as u32 == our_pid {
support = SPAWN
}
// but for the fast path we need both spawnp and the
// pidfd -> pid conversion to work.
if pidfd_spawnp.get().is_some() && let Ok(pid) = pidfd.pid() {
assert_eq!(pid, crate::process::id(), "sanity check");
support = SPAWN;
}
unsafe { libc::close(pidfd) };
}
Err(e) if e.raw_os_error() == Some(libc::EMFILE) => {
// We're temporarily(?) out of file descriptors. In this case obtaining a pidfd would also fail
// We're temporarily(?) out of file descriptors. In this case pidfd_spawnp would also fail
// Don't update the support flag so we can probe again later.
return Err(e)
}
_ => {}
_ => {
// pidfd_open not available? likely an old kernel without pidfd support.
}
}
PIDFD_SUPPORTED.store(support, Ordering::Relaxed);
if support == FORK_EXEC {
@ -791,13 +789,17 @@ impl Command {
}
spawn_res?;
let pid = match cvt(pidfd_getpid.get().unwrap()(pidfd)) {
use crate::os::fd::{FromRawFd, IntoRawFd};
let pidfd = PidFd::from_raw_fd(pidfd);
let pid = match pidfd.pid() {
Ok(pid) => pid,
Err(e) => {
// The child has been spawned and we are holding its pidfd.
// But we cannot obtain its pid even though pidfd_getpid support was verified earlier.
// This might happen if libc can't open procfs because the file descriptor limit has been reached.
libc::close(pidfd);
// But we cannot obtain its pid even though pidfd_spawnp and getpid support
// was verified earlier.
// This is quite unlikely, but might happen if the ioctl is not supported,
// glibc tries to use procfs and we're out of file descriptors.
return Err(Error::new(
e.kind(),
"pidfd_spawnp succeeded but the child's PID could not be obtained",
@ -805,7 +807,7 @@ impl Command {
}
};
return Ok(Some(Process::new(pid, pidfd)));
return Ok(Some(Process::new(pid as i32, pidfd.into_raw_fd())));
}
// Safety: -1 indicates we don't have a pidfd.

View file

@ -29,8 +29,7 @@ labels_blocking_approval = [
# If CI runs quicker than this duration, consider it to be a failure
min_ci_time = 600
# Flip this once new bors is used for actual merges on this repository
merge_queue_enabled = false
merge_queue_enabled = true
report_merge_conflicts = true
[labels]
@ -55,7 +54,9 @@ try_failed = [
"-S-waiting-on-review",
"-S-waiting-on-crater"
]
auto_build_succeeded = ["+merged-by-bors"]
auto_build_succeeded = [
"+merged-by-bors"
]
auto_build_failed = [
"+S-waiting-on-review",
"-S-blocked",

View file

@ -10,4 +10,4 @@ name = "wasm-component-ld"
path = "src/main.rs"
[dependencies]
wasm-component-ld = "0.5.19"
wasm-component-ld = "0.5.20"

View file

@ -0,0 +1,38 @@
#![deny(dead_code)]
pub mod a {
pub trait Foo { }
impl Foo for u32 { }
struct PrivateType; //~ ERROR struct `PrivateType` is never constructed
impl Foo for PrivateType { } // <-- warns as dead, even though Foo is public
struct AnotherPrivateType; //~ ERROR struct `AnotherPrivateType` is never constructed
impl Foo for AnotherPrivateType { } // <-- warns as dead, even though Foo is public
}
pub mod b {
#[allow(dead_code)]
pub trait Foo { }
impl Foo for u32 { }
struct PrivateType;
impl Foo for PrivateType { } // <-- no warning, trait is "allowed"
struct AnotherPrivateType;
impl Foo for AnotherPrivateType { } // <-- no warning, trait is "allowed"
}
pub mod c {
pub trait Foo { }
impl Foo for u32 { }
struct PrivateType;
#[allow(dead_code)]
impl Foo for PrivateType { } // <-- no warning, impl is allowed
struct AnotherPrivateType; //~ ERROR struct `AnotherPrivateType` is never constructed
impl Foo for AnotherPrivateType { } // <-- warns as dead, even though Foo is public
}
fn main() {}

View file

@ -0,0 +1,26 @@
error: struct `PrivateType` is never constructed
--> $DIR/allow-trait-or-impl.rs:7:12
|
LL | struct PrivateType;
| ^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/allow-trait-or-impl.rs:1:9
|
LL | #![deny(dead_code)]
| ^^^^^^^^^
error: struct `AnotherPrivateType` is never constructed
--> $DIR/allow-trait-or-impl.rs:10:12
|
LL | struct AnotherPrivateType;
| ^^^^^^^^^^^^^^^^^^
error: struct `AnotherPrivateType` is never constructed
--> $DIR/allow-trait-or-impl.rs:34:12
|
LL | struct AnotherPrivateType;
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors

View file

@ -0,0 +1,29 @@
//@ check-pass
#![deny(dead_code)]
#[allow(dead_code)]
trait Foo {
const FOO: u32;
type Baz;
fn foobar();
}
const fn bar(x: u32) -> u32 {
x
}
struct Qux;
struct FooBar;
impl Foo for u32 {
const FOO: u32 = bar(0);
type Baz = Qux;
fn foobar() {
let _ = FooBar;
}
}
fn main() {}

View file

@ -0,0 +1,30 @@
#![feature(min_generic_const_args)]
//~^ WARN the feature `min_generic_const_args` is incomplete
#![feature(transmutability)]
mod assert {
use std::mem::{Assume, TransmuteFrom};
struct Dst {}
fn is_maybe_transmutable()
where
Dst: TransmuteFrom<
(),
{
Assume {
alignment: Assume {},
//~^ ERROR struct expression with missing field initialiser for `alignment`
//~| ERROR struct expression with missing field initialiser for `lifetimes`
//~| ERROR struct expression with missing field initialiser for `safety`
//~| ERROR struct expression with missing field initialiser for `validity`
lifetimes: const { true },
safety: const { true },
validity: const { true },
}
},
>,
{
}
}
fn main() {}

View file

@ -0,0 +1,35 @@
warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/non_scalar_alignment_value.rs:1:12
|
LL | #![feature(min_generic_const_args)]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information
= note: `#[warn(incomplete_features)]` on by default
error: struct expression with missing field initialiser for `alignment`
--> $DIR/non_scalar_alignment_value.rs:15:32
|
LL | alignment: Assume {},
| ^^^^^^
error: struct expression with missing field initialiser for `lifetimes`
--> $DIR/non_scalar_alignment_value.rs:15:32
|
LL | alignment: Assume {},
| ^^^^^^
error: struct expression with missing field initialiser for `safety`
--> $DIR/non_scalar_alignment_value.rs:15:32
|
LL | alignment: Assume {},
| ^^^^^^
error: struct expression with missing field initialiser for `validity`
--> $DIR/non_scalar_alignment_value.rs:15:32
|
LL | alignment: Assume {},
| ^^^^^^
error: aborting due to 4 previous errors; 1 warning emitted

View file

@ -0,0 +1,33 @@
//@ compile-flags: -Zunpretty=hir
//@ check-pass
#![feature(min_generic_const_args, adt_const_params)]
#![expect(incomplete_features)]
#![allow(dead_code)]
use std::marker::ConstParamTy;
struct Point(u32, u32);
struct Point3();
struct Point1 {
a: u32,
b: u32,
}
struct Point2 {}
fn with_point<const P: Point>() {}
fn with_point1<const P: Point1>() {}
fn with_point2<const P: Point2>() {}
fn with_point3<const P: Point3>() {}
fn test<const N: u32>() {
with_point::<{ Point(N, N) }>();
with_point1::<{ Point1 { a: N, b: N } }>();
with_point2::<{ Point2 {} }>();
with_point3::<{ Point3() }>();
}
fn main() {}

View file

@ -0,0 +1,39 @@
//@ compile-flags: -Zunpretty=hir
//@ check-pass
#![feature(min_generic_const_args, adt_const_params)]
#![expect(incomplete_features)]
#![allow(dead_code)]
#[attr = MacroUse {arguments: UseAll}]
extern crate std;
#[prelude_import]
use ::std::prelude::rust_2015::*;
use std::marker::ConstParamTy;
struct Point(u32, u32);
struct Point3();
struct Point1 {
a: u32,
b: u32,
}
struct Point2 {
}
fn with_point<const P: Point>() { }
fn with_point1<const P: Point1>() { }
fn with_point2<const P: Point2>() { }
fn with_point3<const P: Point3>() { }
fn test<const N:
u32>() {
with_point::<Point(N, N)>();
with_point1::<Point1 { a: N, b: N}>();
with_point2::<Point2 {}>();
with_point3::<Point3()>();
}
fn main() { }