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:
commit
4d73a008ea
29 changed files with 595 additions and 206 deletions
53
Cargo.lock
53
Cargo.lock
|
|
@ -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]]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
})
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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(¶m.ty, itctx)
|
||||
self.lower_ty(¶m.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,
|
||||
|
|
|
|||
|
|
@ -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(|| {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>> {
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>> {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
38
tests/ui/lint/dead-code/allow-trait-or-impl.rs
Normal file
38
tests/ui/lint/dead-code/allow-trait-or-impl.rs
Normal 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() {}
|
||||
26
tests/ui/lint/dead-code/allow-trait-or-impl.stderr
Normal file
26
tests/ui/lint/dead-code/allow-trait-or-impl.stderr
Normal 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
|
||||
|
||||
29
tests/ui/lint/dead-code/allow-unused-trait.rs
Normal file
29
tests/ui/lint/dead-code/allow-unused-trait.rs
Normal 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() {}
|
||||
30
tests/ui/transmutability/non_scalar_alignment_value.rs
Normal file
30
tests/ui/transmutability/non_scalar_alignment_value.rs
Normal 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() {}
|
||||
35
tests/ui/transmutability/non_scalar_alignment_value.stderr
Normal file
35
tests/ui/transmutability/non_scalar_alignment_value.stderr
Normal 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
|
||||
|
||||
33
tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs
Normal file
33
tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs
Normal 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() {}
|
||||
|
|
@ -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() { }
|
||||
Loading…
Add table
Add a link
Reference in a new issue