Skip to content

Commit 86ce982

Browse files
committed
Auto merge of rust-lang#129254 - matthiaskrgr:rollup-qm30weo, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#125854 (Move ZST ABI handling to `rustc_target`) - rust-lang#127623 (fix: fs::remove_dir_all: treat internal ENOENT as success) - rust-lang#128084 (Suggest adding Result return type for associated method in E0277.) - rust-lang#128902 (doc: std::env::var: Returns None for names with '=' or NUL byte) - rust-lang#129187 (bootstrap: fix clean's remove_dir_all implementation) - rust-lang#129235 (Check that `#[may_dangle]` is properly applied) - rust-lang#129245 (Typo) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6de928d + d0638a1 commit 86ce982

Some content is hidden

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

41 files changed

+1181
-179
lines changed

compiler/rustc_hir/src/hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,7 @@ pub struct LetExpr<'hir> {
13951395
pub pat: &'hir Pat<'hir>,
13961396
pub ty: Option<&'hir Ty<'hir>>,
13971397
pub init: &'hir Expr<'hir>,
1398-
/// `Recovered::Yes` when this let expressions is not in a syntanctically valid location.
1398+
/// `Recovered::Yes` when this let expressions is not in a syntactically valid location.
13991399
/// Used to prevent building MIR in such situations.
14001400
pub recovered: ast::Recovered,
14011401
}

compiler/rustc_passes/messages.ftl

+5-2
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ passes_macro_export_on_decl_macro =
444444
passes_macro_use =
445445
`#[{$name}]` only has an effect on `extern crate` and modules
446446
447+
passes_may_dangle =
448+
`#[may_dangle]` must be applied to a lifetime or type generic parameter in `Drop` impl
449+
447450
passes_maybe_string_interpolation = you might have meant to use string interpolation in this string literal
448451
passes_missing_const_err =
449452
attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const`
@@ -475,8 +478,8 @@ passes_multiple_start_functions =
475478
.previous = previous `#[start]` function here
476479
477480
passes_must_not_suspend =
478-
`must_not_suspend` attribute should be applied to a struct, enum, or trait
479-
.label = is not a struct, enum, or trait
481+
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
482+
.label = is not a struct, enum, union, or trait
480483
481484
passes_must_use_async =
482485
`must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within

compiler/rustc_passes/src/check_attr.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
189189
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
190190
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
191191
[sym::must_use, ..] => self.check_must_use(hir_id, attr, target),
192+
[sym::may_dangle, ..] => self.check_may_dangle(hir_id, attr),
192193
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
193194
[sym::rustc_allow_incoherent_impl, ..] => {
194195
self.check_allow_incoherent_impl(attr, span, target)
@@ -255,7 +256,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
255256
| sym::cfg_attr
256257
// need to be fixed
257258
| sym::cfi_encoding // FIXME(cfi_encoding)
258-
| sym::may_dangle // FIXME(dropck_eyepatch)
259259
| sym::pointee // FIXME(derive_smart_pointer)
260260
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
261261
| sym::used // handled elsewhere to restrict to static items
@@ -1363,7 +1363,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
13631363
}
13641364
}
13651365

1366-
/// Checks if `#[must_not_suspend]` is applied to a function.
1366+
/// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait.
13671367
fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) {
13681368
match target {
13691369
Target::Struct | Target::Enum | Target::Union | Target::Trait => {}
@@ -1373,6 +1373,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
13731373
}
13741374
}
13751375

1376+
/// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
1377+
fn check_may_dangle(&self, hir_id: HirId, attr: &Attribute) {
1378+
if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id)
1379+
&& matches!(
1380+
param.kind,
1381+
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. }
1382+
)
1383+
&& matches!(param.source, hir::GenericParamSource::Generics)
1384+
&& let parent_hir_id = self.tcx.parent_hir_id(hir_id)
1385+
&& let hir::Node::Item(item) = self.tcx.hir_node(parent_hir_id)
1386+
&& let hir::ItemKind::Impl(impl_) = item.kind
1387+
&& let Some(trait_) = impl_.of_trait
1388+
&& let Some(def_id) = trait_.trait_def_id()
1389+
&& self.tcx.is_lang_item(def_id, hir::LangItem::Drop)
1390+
{
1391+
return;
1392+
}
1393+
1394+
self.dcx().emit_err(errors::InvalidMayDangle { attr_span: attr.span });
1395+
}
1396+
13761397
/// Checks if `#[cold]` is applied to a non-function.
13771398
fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
13781399
match target {

compiler/rustc_passes/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,13 @@ pub struct NonExportedMacroInvalidAttrs {
737737
pub attr_span: Span,
738738
}
739739

740+
#[derive(Diagnostic)]
741+
#[diag(passes_may_dangle)]
742+
pub struct InvalidMayDangle {
743+
#[primary_span]
744+
pub attr_span: Span,
745+
}
746+
740747
#[derive(LintDiagnostic)]
741748
#[diag(passes_unused_duplicate)]
742749
pub struct UnusedDuplicate {

compiler/rustc_target/src/abi/call/mod.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
642642
pub fn make_indirect(&mut self) {
643643
match self.mode {
644644
PassMode::Direct(_) | PassMode::Pair(_, _) => {
645-
self.mode = Self::indirect_pass_mode(&self.layout);
645+
self.make_indirect_force();
646646
}
647647
PassMode::Indirect { attrs: _, meta_attrs: _, on_stack: false } => {
648648
// already indirect
@@ -652,6 +652,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
652652
}
653653
}
654654

655+
/// Same as make_indirect, but doesn't check the current `PassMode`.
656+
pub fn make_indirect_force(&mut self) {
657+
self.mode = Self::indirect_pass_mode(&self.layout);
658+
}
659+
655660
/// Pass this argument indirectly, by placing it at a fixed stack offset.
656661
/// This corresponds to the `byval` LLVM argument attribute.
657662
/// This is only valid for sized arguments.
@@ -871,10 +876,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
871876
}
872877
"x86_64" => match abi {
873878
spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
874-
spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(self),
879+
spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(cx, self),
875880
_ => {
876881
if cx.target_spec().is_like_windows {
877-
x86_win64::compute_abi_info(self)
882+
x86_win64::compute_abi_info(cx, self)
878883
} else {
879884
x86_64::compute_abi_info(cx, self)
880885
}
@@ -898,7 +903,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
898903
"csky" => csky::compute_abi_info(self),
899904
"mips" | "mips32r6" => mips::compute_abi_info(cx, self),
900905
"mips64" | "mips64r6" => mips64::compute_abi_info(cx, self),
901-
"powerpc" => powerpc::compute_abi_info(self),
906+
"powerpc" => powerpc::compute_abi_info(cx, self),
902907
"powerpc64" => powerpc64::compute_abi_info(cx, self),
903908
"s390x" => s390x::compute_abi_info(cx, self),
904909
"msp430" => msp430::compute_abi_info(self),
+14-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::abi::call::{ArgAbi, FnAbi};
2+
use crate::spec::HasTargetSpec;
23

34
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
45
if ret.layout.is_aggregate() {
@@ -8,23 +9,30 @@ fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
89
}
910
}
1011

11-
fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
12+
fn classify_arg<Ty>(cx: &impl HasTargetSpec, arg: &mut ArgAbi<'_, Ty>) {
13+
if arg.is_ignore() {
14+
// powerpc-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
15+
if cx.target_spec().os == "linux"
16+
&& matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc")
17+
&& arg.layout.is_zst()
18+
{
19+
arg.make_indirect_force();
20+
}
21+
return;
22+
}
1223
if arg.layout.is_aggregate() {
1324
arg.make_indirect();
1425
} else {
1526
arg.extend_integer_width_to(32);
1627
}
1728
}
1829

19-
pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
30+
pub fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
2031
if !fn_abi.ret.is_ignore() {
2132
classify_ret(&mut fn_abi.ret);
2233
}
2334

2435
for arg in fn_abi.args.iter_mut() {
25-
if arg.is_ignore() {
26-
continue;
27-
}
28-
classify_arg(arg);
36+
classify_arg(cx, arg);
2937
}
3038
}

compiler/rustc_target/src/abi/call/s390x.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use crate::abi::call::{ArgAbi, FnAbi, Reg};
55
use crate::abi::{HasDataLayout, TyAbiInterface};
6+
use crate::spec::HasTargetSpec;
67

78
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
89
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
@@ -15,12 +16,22 @@ fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
1516
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
1617
where
1718
Ty: TyAbiInterface<'a, C> + Copy,
18-
C: HasDataLayout,
19+
C: HasDataLayout + HasTargetSpec,
1920
{
2021
if !arg.layout.is_sized() {
2122
// Not touching this...
2223
return;
2324
}
25+
if arg.is_ignore() {
26+
// s390x-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
27+
if cx.target_spec().os == "linux"
28+
&& matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc")
29+
&& arg.layout.is_zst()
30+
{
31+
arg.make_indirect_force();
32+
}
33+
return;
34+
}
2435
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
2536
arg.extend_integer_width_to(64);
2637
return;
@@ -46,16 +57,13 @@ where
4657
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
4758
where
4859
Ty: TyAbiInterface<'a, C> + Copy,
49-
C: HasDataLayout,
60+
C: HasDataLayout + HasTargetSpec,
5061
{
5162
if !fn_abi.ret.is_ignore() {
5263
classify_ret(&mut fn_abi.ret);
5364
}
5465

5566
for arg in fn_abi.args.iter_mut() {
56-
if arg.is_ignore() {
57-
continue;
58-
}
5967
classify_arg(cx, arg);
6068
}
6169
}

compiler/rustc_target/src/abi/call/sparc64.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::abi::call::{
44
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, Reg, Uniform,
55
};
66
use crate::abi::{self, HasDataLayout, Scalar, Size, TyAbiInterface, TyAndLayout};
7+
use crate::spec::HasTargetSpec;
78

89
#[derive(Clone, Debug)]
910
pub struct Sdata {
@@ -211,15 +212,22 @@ where
211212
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
212213
where
213214
Ty: TyAbiInterface<'a, C> + Copy,
214-
C: HasDataLayout,
215+
C: HasDataLayout + HasTargetSpec,
215216
{
216217
if !fn_abi.ret.is_ignore() {
217218
classify_arg(cx, &mut fn_abi.ret, Size::from_bytes(32));
218219
}
219220

220221
for arg in fn_abi.args.iter_mut() {
221222
if arg.is_ignore() {
222-
continue;
223+
// sparc64-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
224+
if cx.target_spec().os == "linux"
225+
&& matches!(&*cx.target_spec().env, "gnu" | "musl" | "uclibc")
226+
&& arg.layout.is_zst()
227+
{
228+
arg.make_indirect_force();
229+
}
230+
return;
223231
}
224232
classify_arg(cx, arg, Size::from_bytes(16));
225233
}

compiler/rustc_target/src/abi/call/x86_win64.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::abi::call::{ArgAbi, FnAbi, Reg};
22
use crate::abi::{Abi, Float, Primitive};
3+
use crate::spec::HasTargetSpec;
34

45
// Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
56

6-
pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
7+
pub fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
78
let fixup = |a: &mut ArgAbi<'_, Ty>| {
89
match a.layout.abi {
910
Abi::Uninhabited | Abi::Aggregate { sized: false } => {}
@@ -37,6 +38,13 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
3738
}
3839
for arg in fn_abi.args.iter_mut() {
3940
if arg.is_ignore() {
41+
// x86_64-pc-windows-gnu doesn't ignore ZSTs.
42+
if cx.target_spec().os == "windows"
43+
&& cx.target_spec().env == "gnu"
44+
&& arg.layout.is_zst()
45+
{
46+
arg.make_indirect_force();
47+
}
4048
continue;
4149
}
4250
fixup(arg);

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+36-5
Original file line numberDiff line numberDiff line change
@@ -4610,6 +4610,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
46104610
})
46114611
}
46124612

4613+
// For E0277 when use `?` operator, suggest adding
4614+
// a suitable return type in `FnSig`, and a default
4615+
// return value at the end of the function's body.
46134616
pub(super) fn suggest_add_result_as_return_type(
46144617
&self,
46154618
obligation: &PredicateObligation<'tcx>,
@@ -4620,19 +4623,47 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
46204623
return;
46214624
}
46224625

4626+
// Only suggest for local function and associated method,
4627+
// because this suggest adding both return type in
4628+
// the `FnSig` and a default return value in the body, so it
4629+
// is not suitable for foreign function without a local body,
4630+
// and neighter for trait method which may be also implemented
4631+
// in other place, so shouldn't change it's FnSig.
4632+
fn choose_suggest_items<'tcx, 'hir>(
4633+
tcx: TyCtxt<'tcx>,
4634+
node: hir::Node<'hir>,
4635+
) -> Option<(&'hir hir::FnDecl<'hir>, hir::BodyId)> {
4636+
match node {
4637+
hir::Node::Item(item) if let hir::ItemKind::Fn(sig, _, body_id) = item.kind => {
4638+
Some((sig.decl, body_id))
4639+
}
4640+
hir::Node::ImplItem(item)
4641+
if let hir::ImplItemKind::Fn(sig, body_id) = item.kind =>
4642+
{
4643+
let parent = tcx.parent_hir_node(item.hir_id());
4644+
if let hir::Node::Item(item) = parent
4645+
&& let hir::ItemKind::Impl(imp) = item.kind
4646+
&& imp.of_trait.is_none()
4647+
{
4648+
return Some((sig.decl, body_id));
4649+
}
4650+
None
4651+
}
4652+
_ => None,
4653+
}
4654+
}
4655+
46234656
let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
4624-
if let hir::Node::Item(item) = node
4625-
&& let hir::ItemKind::Fn(sig, _, body_id) = item.kind
4626-
&& let hir::FnRetTy::DefaultReturn(ret_span) = sig.decl.output
4657+
if let Some((fn_decl, body_id)) = choose_suggest_items(self.tcx, node)
4658+
&& let hir::FnRetTy::DefaultReturn(ret_span) = fn_decl.output
46274659
&& self.tcx.is_diagnostic_item(sym::FromResidual, trait_pred.def_id())
46284660
&& trait_pred.skip_binder().trait_ref.args.type_at(0).is_unit()
46294661
&& let ty::Adt(def, _) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
46304662
&& self.tcx.is_diagnostic_item(sym::Result, def.did())
46314663
{
4632-
let body = self.tcx.hir().body(body_id);
46334664
let mut sugg_spans =
46344665
vec![(ret_span, " -> Result<(), Box<dyn std::error::Error>>".to_string())];
4635-
4666+
let body = self.tcx.hir().body(body_id);
46364667
if let hir::ExprKind::Block(b, _) = body.value.kind
46374668
&& b.expr.is_none()
46384669
{

0 commit comments

Comments
 (0)