Skip to content

Commit 61885df

Browse files
committed
Auto merge of rust-lang#87980 - Manishearth:rollup-vkuix3y, r=Manishearth
Rollup of 4 pull requests Successful merges: - rust-lang#87916 (Implement `black_box` using intrinsic) - rust-lang#87922 (Add c_enum_min_bits target spec field, use for arm-none and thumb-none targets) - rust-lang#87953 (Improve formatting of closure capture migration suggestion for multi-line closures.) - rust-lang#87965 (Silence non_fmt_panic from external macros.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0fa3190 + 2d27976 commit 61885df

34 files changed

+667
-113
lines changed

compiler/rustc_lint/src/non_fmt_panic.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::{LateContext, LateLintPass, LintContext};
22
use rustc_ast as ast;
33
use rustc_errors::{pluralize, Applicability};
44
use rustc_hir as hir;
5+
use rustc_middle::lint::in_external_macro;
56
use rustc_middle::ty;
67
use rustc_parse_format::{ParseMode, Parser, Piece};
78
use rustc_session::lint::FutureIncompatibilityReason;
@@ -75,6 +76,11 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
7576

7677
let (span, panic, symbol_str) = panic_call(cx, f);
7778

79+
if in_external_macro(cx.sess(), span) {
80+
// Nothing that can be done about it in the current crate.
81+
return;
82+
}
83+
7884
// Find the span of the argument to `panic!()`, before expansion in the
7985
// case of `panic!(some_macro!())`.
8086
// We don't use source_callsite(), because this `panic!(..)` might itself
@@ -152,6 +158,13 @@ fn check_panic_str<'tcx>(
152158
return;
153159
}
154160

161+
let (span, _, _) = panic_call(cx, f);
162+
163+
if in_external_macro(cx.sess(), span) && in_external_macro(cx.sess(), arg.span) {
164+
// Nothing that can be done about it in the current crate.
165+
return;
166+
}
167+
155168
let fmt_span = arg.span.source_callsite();
156169

157170
let (snippet, style) = match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) {
@@ -167,8 +180,6 @@ fn check_panic_str<'tcx>(
167180
Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
168181
let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
169182

170-
let (span, _, _) = panic_call(cx, f);
171-
172183
if n_arguments > 0 && fmt_parser.errors.is_empty() {
173184
let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] {
174185
[] => vec![fmt_span],

compiler/rustc_middle/src/ty/layout.rs

+8-16
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,6 @@ impl IntegerExt for Integer {
112112
let unsigned_fit = Integer::fit_unsigned(cmp::max(min as u128, max as u128));
113113
let signed_fit = cmp::max(Integer::fit_signed(min), Integer::fit_signed(max));
114114

115-
let mut min_from_extern = None;
116-
let min_default = I8;
117-
118115
if let Some(ity) = repr.int {
119116
let discr = Integer::from_attr(&tcx, ity);
120117
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
@@ -128,19 +125,14 @@ impl IntegerExt for Integer {
128125
return (discr, ity.is_signed());
129126
}
130127

131-
if repr.c() {
132-
match &tcx.sess.target.arch[..] {
133-
"hexagon" => min_from_extern = Some(I8),
134-
// WARNING: the ARM EABI has two variants; the one corresponding
135-
// to `at_least == I32` appears to be used on Linux and NetBSD,
136-
// but some systems may use the variant corresponding to no
137-
// lower bound. However, we don't run on those yet...?
138-
"arm" => min_from_extern = Some(I32),
139-
_ => min_from_extern = Some(I32),
140-
}
141-
}
142-
143-
let at_least = min_from_extern.unwrap_or(min_default);
128+
let at_least = if repr.c() {
129+
// This is usually I32, however it can be different on some platforms,
130+
// notably hexagon and arm-none/thumb-none
131+
tcx.data_layout().c_enum_min_size
132+
} else {
133+
// repr(Rust) enums try to be as small as possible
134+
I8
135+
};
144136

145137
// If there are no negative values, we can use the unsigned fit.
146138
if min >= 0 {

compiler/rustc_target/src/abi/mod.rs

+17
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub struct TargetDataLayout {
3636
pub vector_align: Vec<(Size, AbiAndPrefAlign)>,
3737

3838
pub instruction_address_space: AddressSpace,
39+
40+
/// Minimum size of #[repr(C)] enums (default I32 bits)
41+
pub c_enum_min_size: Integer,
3942
}
4043

4144
impl Default for TargetDataLayout {
@@ -60,6 +63,7 @@ impl Default for TargetDataLayout {
6063
(Size::from_bits(128), AbiAndPrefAlign::new(align(128))),
6164
],
6265
instruction_address_space: AddressSpace::DATA,
66+
c_enum_min_size: Integer::I32,
6367
}
6468
}
6569
}
@@ -173,6 +177,8 @@ impl TargetDataLayout {
173177
));
174178
}
175179

180+
dl.c_enum_min_size = Integer::from_size(Size::from_bits(target.c_enum_min_bits))?;
181+
176182
Ok(dl)
177183
}
178184

@@ -610,6 +616,17 @@ impl Integer {
610616
}
611617
I8
612618
}
619+
620+
fn from_size(size: Size) -> Result<Self, String> {
621+
match size.bits() {
622+
8 => Ok(Integer::I8),
623+
16 => Ok(Integer::I16),
624+
32 => Ok(Integer::I32),
625+
64 => Ok(Integer::I64),
626+
128 => Ok(Integer::I128),
627+
_ => Err(format!("rust does not support integers with {} bits", size.bits())),
628+
}
629+
}
613630
}
614631

615632
/// Fundamental unit of memory access and layout.

compiler/rustc_target/src/spec/armebv7r_none_eabi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub fn target() -> Target {
2020
panic_strategy: PanicStrategy::Abort,
2121
max_atomic_width: Some(32),
2222
emit_debug_gdb_scripts: false,
23+
// GCC and Clang default to 8 for arm-none here
24+
c_enum_min_bits: 8,
2325
..Default::default()
2426
},
2527
}

compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ pub fn target() -> Target {
2121
features: "+vfp3,-d32,-fp16".to_string(),
2222
max_atomic_width: Some(32),
2323
emit_debug_gdb_scripts: false,
24+
// GCC and Clang default to 8 for arm-none here
25+
c_enum_min_bits: 8,
2426
..Default::default()
2527
},
2628
}

compiler/rustc_target/src/spec/armv7a_none_eabi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub fn target() -> Target {
2828
max_atomic_width: Some(64),
2929
panic_strategy: PanicStrategy::Abort,
3030
emit_debug_gdb_scripts: false,
31+
c_enum_min_bits: 8,
3132
..Default::default()
3233
};
3334
Target {

compiler/rustc_target/src/spec/armv7a_none_eabihf.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub fn target() -> Target {
1919
max_atomic_width: Some(64),
2020
panic_strategy: PanicStrategy::Abort,
2121
emit_debug_gdb_scripts: false,
22+
// GCC and Clang default to 8 for arm-none here
23+
c_enum_min_bits: 8,
2224
..Default::default()
2325
};
2426
Target {

compiler/rustc_target/src/spec/armv7r_none_eabi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub fn target() -> Target {
1919
panic_strategy: PanicStrategy::Abort,
2020
max_atomic_width: Some(32),
2121
emit_debug_gdb_scripts: false,
22+
// GCC and Clang default to 8 for arm-none here
23+
c_enum_min_bits: 8,
2224
..Default::default()
2325
},
2426
}

compiler/rustc_target/src/spec/armv7r_none_eabihf.rs

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub fn target() -> Target {
2020
features: "+vfp3,-d32,-fp16".to_string(),
2121
max_atomic_width: Some(32),
2222
emit_debug_gdb_scripts: false,
23+
// GCC and Clang default to 8 for arm-none here
24+
c_enum_min_bits: 8,
2325
..Default::default()
2426
},
2527
}

compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ pub fn target() -> Target {
1313
base.dynamic_linking = true;
1414
base.executables = true;
1515

16+
base.c_enum_min_bits = 8;
17+
1618
Target {
1719
llvm_target: "hexagon-unknown-linux-musl".to_string(),
1820
pointer_width: 32,

compiler/rustc_target/src/spec/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,9 @@ pub struct TargetOptions {
13361336

13371337
/// If present it's a default value to use for adjusting the C ABI.
13381338
pub default_adjusted_cabi: Option<Abi>,
1339+
1340+
/// Minimum number of bits in #[repr(C)] enum. Defaults to 32.
1341+
pub c_enum_min_bits: u64,
13391342
}
13401343

13411344
impl Default for TargetOptions {
@@ -1440,6 +1443,7 @@ impl Default for TargetOptions {
14401443
split_debuginfo: SplitDebuginfo::Off,
14411444
supported_sanitizers: SanitizerSet::empty(),
14421445
default_adjusted_cabi: None,
1446+
c_enum_min_bits: 32,
14431447
}
14441448
}
14451449
}
@@ -1604,6 +1608,12 @@ impl Target {
16041608
base.$key_name = s;
16051609
}
16061610
} );
1611+
($key_name:ident, u64) => ( {
1612+
let name = (stringify!($key_name)).replace("_", "-");
1613+
if let Some(s) = obj.remove_key(&name).and_then(|j| Json::as_u64(&j)) {
1614+
base.$key_name = s;
1615+
}
1616+
} );
16071617
($key_name:ident, Option<u32>) => ( {
16081618
let name = (stringify!($key_name)).replace("_", "-");
16091619
if let Some(s) = obj.remove_key(&name).and_then(|j| Json::as_u64(&j)) {
@@ -2017,6 +2027,7 @@ impl Target {
20172027
key!(split_debuginfo, SplitDebuginfo)?;
20182028
key!(supported_sanitizers, SanitizerSet)?;
20192029
key!(default_adjusted_cabi, Option<Abi>)?;
2030+
key!(c_enum_min_bits, u64);
20202031

20212032
if base.is_builtin {
20222033
// This can cause unfortunate ICEs later down the line.
@@ -2255,6 +2266,7 @@ impl ToJson for Target {
22552266
target_option_val!(has_thumb_interworking);
22562267
target_option_val!(split_debuginfo);
22572268
target_option_val!(supported_sanitizers);
2269+
target_option_val!(c_enum_min_bits);
22582270

22592271
if let Some(abi) = self.default_adjusted_cabi {
22602272
d.insert("default-adjusted-cabi".to_string(), Abi::name(abi).to_json());

compiler/rustc_target/src/spec/thumb_base.rs

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ pub fn opts() -> TargetOptions {
5353
// LLVM is eager to trash the link register when calling `noreturn` functions, which
5454
// breaks debugging. Preserve LR by default to prevent that from happening.
5555
frame_pointer: FramePointer::Always,
56+
// ARM supports multiple ABIs for enums, the linux one matches the default of 32 here
57+
// but any arm-none or thumb-none target will be defaulted to 8 on GCC and clang
58+
c_enum_min_bits: 8,
5659
..Default::default()
5760
}
5861
}

compiler/rustc_typeck/src/check/upvar.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -649,11 +649,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
649649
match self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
650650
Ok(s) => {
651651
let trimmed = s.trim_start();
652+
let mut lines = trimmed.lines();
653+
let line1 = lines.next().unwrap_or_default();
652654

653655
// If the closure contains a block then replace the opening brace
654656
// with "{ let _ = (..); "
655-
let sugg = if let Some('{') = trimmed.chars().next() {
656-
format!("{{ {}; {}", migration_string, &trimmed[1..])
657+
let sugg = if line1.trim_end() == "{" {
658+
// This is a multi-line closure with just a `{` on the first line,
659+
// so we put the `let` on its own line.
660+
// We take the indentation from the next non-empty line.
661+
let line2 = lines.filter(|line| !line.is_empty()).next().unwrap_or_default();
662+
let indent = line2.split_once(|c: char| !c.is_whitespace()).unwrap_or_default().0;
663+
format!("{{\n{}{};{}", indent, migration_string, &trimmed[line1.len()..])
664+
} else if line1.starts_with('{') {
665+
format!("{{ {}; {}", migration_string, &trimmed[1..].trim_start())
657666
} else {
658667
format!("{{ {}; {} }}", migration_string, s)
659668
};

src/test/ui/auxiliary/fancy-panic.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#[macro_export]
22
macro_rules! fancy_panic {
3+
() => {
4+
panic!("{}");
5+
};
36
($msg:expr) => {
47
panic!($msg)
58
};

src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ impl Clone for U {
5555

5656
fn test_clone_trait() {
5757
let f = U(S(String::from("Hello World")), T(0));
58-
let c = || { let _ = &f;
58+
let c = || {
59+
let _ = &f;
5960
//~^ ERROR: `Clone` trait implementation for closure and drop order
6061
//~| NOTE: in Rust 2018, this closure would implement `Clone` as `f` implements `Clone`, but in Rust 2021, this closure would no longer implement `Clone` as `f.1` does not implement `Clone`
6162
//~| NOTE: for more information, see

src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ LL | }
5858
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
5959
help: add a dummy let to cause `f` to be fully captured
6060
|
61-
LL ~ let c = || { let _ = &f;
61+
LL ~ let c = || {
62+
LL + let _ = &f;
6263
LL +
6364
LL +
6465
LL +
6566
LL +
66-
LL + let f_1 = f.1;
6767
...
6868

6969
error: aborting due to 3 previous errors

src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed

+14-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ fn test1_all_need_migration() {
1212
let t1 = (String::new(), String::new());
1313
let t2 = (String::new(), String::new());
1414

15-
let c = || { let _ = (&t, &t1, &t2);
15+
let c = || {
16+
let _ = (&t, &t1, &t2);
1617
//~^ ERROR: drop order
1718
//~| NOTE: for more information, see
1819
//~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
@@ -38,7 +39,8 @@ fn test2_only_precise_paths_need_migration() {
3839
let t1 = (String::new(), String::new());
3940
let t2 = (String::new(), String::new());
4041

41-
let c = || { let _ = (&t, &t1);
42+
let c = || {
43+
let _ = (&t, &t1);
4244
//~^ ERROR: drop order
4345
//~| NOTE: for more information, see
4446
//~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
@@ -59,7 +61,8 @@ fn test2_only_precise_paths_need_migration() {
5961
fn test3_only_by_value_need_migration() {
6062
let t = (String::new(), String::new());
6163
let t1 = (String::new(), String::new());
62-
let c = || { let _ = &t;
64+
let c = || {
65+
let _ = &t;
6366
//~^ ERROR: drop order
6467
//~| NOTE: for more information, see
6568
//~| HELP: add a dummy let to cause `t` to be fully captured
@@ -80,7 +83,8 @@ fn test4_only_non_copy_types_need_migration() {
8083
// `t1` is Copy because all of its elements are Copy
8184
let t1 = (0i32, 0i32);
8285

83-
let c = || { let _ = &t;
86+
let c = || {
87+
let _ = &t;
8488
//~^ ERROR: drop order
8589
//~| NOTE: for more information, see
8690
//~| HELP: add a dummy let to cause `t` to be fully captured
@@ -101,7 +105,8 @@ fn test5_only_drop_types_need_migration() {
101105
// `s` doesn't implement Drop or any elements within it, and doesn't need migration
102106
let s = S(0i32, 0i32);
103107

104-
let c = || { let _ = &t;
108+
let c = || {
109+
let _ = &t;
105110
//~^ ERROR: drop order
106111
//~| NOTE: for more information, see
107112
//~| HELP: add a dummy let to cause `t` to be fully captured
@@ -119,7 +124,8 @@ fn test5_only_drop_types_need_migration() {
119124
fn test6_move_closures_non_copy_types_might_need_migration() {
120125
let t = (String::new(), String::new());
121126
let t1 = (String::new(), String::new());
122-
let c = move || { let _ = (&t1, &t);
127+
let c = move || {
128+
let _ = (&t1, &t);
123129
//~^ ERROR: drop order
124130
//~| NOTE: for more information, see
125131
//~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
@@ -139,7 +145,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() {
139145
fn test7_drop_non_drop_aggregate_need_migration() {
140146
let t = (String::new(), String::new(), 0i32);
141147

142-
let c = || { let _ = &t;
148+
let c = || {
149+
let _ = &t;
143150
//~^ ERROR: drop order
144151
//~| NOTE: for more information, see
145152
//~| HELP: add a dummy let to cause `t` to be fully captured

0 commit comments

Comments
 (0)