Skip to content

Commit 9f37cd4

Browse files
committed
Auto merge of #115442 - cuviper:beta-next, r=cuviper
[beta] backports - Contents of reachable statics is reachable #115114 - Revert "Suggest using `Arc` on `!Send`/`!Sync` types" #115311 - Stop emitting non-power-of-two vectors in (non-portable-SIMD) codegen #115236 - Do not forget to pass DWARF fragment information to LLVM. #115139 - rustdoc: use unicode-aware checks for redundant explicit link fastpath #115070 r? cuviper
2 parents bc28abf + 20ddd45 commit 9f37cd4

File tree

125 files changed

+193
-268
lines changed

Some content is hidden

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

125 files changed

+193
-268
lines changed

compiler/rustc_codegen_llvm/src/type_of.rs

+4
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,11 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
405405

406406
// Vectors, even for non-power-of-two sizes, have the same layout as
407407
// arrays but don't count as aggregate types
408+
// While LLVM theoretically supports non-power-of-two sizes, and they
409+
// often work fine, sometimes x86-isel deals with them horribly
410+
// (see #115212) so for now only use power-of-two ones.
408411
if let FieldsShape::Array { count, .. } = self.layout.fields()
412+
&& count.is_power_of_two()
409413
&& let element = self.field(cx, 0)
410414
&& element.ty.is_integral()
411415
{

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+28-9
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
435435
bx.store(place.llval, alloca.llval, alloca.align);
436436

437437
// Point the debug info to `*alloca` for the current variable
438-
bx.dbg_var_addr(dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], None);
438+
bx.dbg_var_addr(
439+
dbg_var,
440+
dbg_loc,
441+
alloca.llval,
442+
Size::ZERO,
443+
&[Size::ZERO],
444+
var.fragment,
445+
);
439446
} else {
440-
bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, direct_offset, &indirect_offsets, None);
447+
bx.dbg_var_addr(
448+
dbg_var,
449+
dbg_loc,
450+
base.llval,
451+
direct_offset,
452+
&indirect_offsets,
453+
var.fragment,
454+
);
441455
}
442456
}
443457

@@ -560,17 +574,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
560574
}
561575

562576
let place = fragment.contents;
577+
let fragment = if fragment_layout.size == Size::ZERO {
578+
// Fragment is a ZST, so does not represent anything.
579+
continue;
580+
} else if fragment_layout.size == var_layout.size {
581+
// Fragment covers entire variable, so as far as
582+
// DWARF is concerned, it's not really a fragment.
583+
None
584+
} else {
585+
Some(fragment_start..fragment_start + fragment_layout.size)
586+
};
587+
563588
per_local[place.local].push(PerLocalVarDebugInfo {
564589
name: var.name,
565590
source_info: var.source_info,
566591
dbg_var,
567-
fragment: if fragment_layout.size == var_layout.size {
568-
// Fragment covers entire variable, so as far as
569-
// DWARF is concerned, it's not really a fragment.
570-
None
571-
} else {
572-
Some(fragment_start..fragment_start + fragment_layout.size)
573-
},
592+
fragment,
574593
projection: place.projection,
575594
});
576595
}

compiler/rustc_passes/src/reachable.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,11 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
9898
self.worklist.push(def_id);
9999
} else {
100100
match res {
101-
// If this path leads to a constant, then we need to
102-
// recurse into the constant to continue finding
103-
// items that are reachable.
104-
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
101+
// Reachable constants and reachable statics can have their contents inlined
102+
// into other crates. Mark them as reachable and recurse into their body.
103+
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static(_), _) => {
105104
self.worklist.push(def_id);
106105
}
107-
108-
// If this wasn't a static, then the destination is
109-
// surely reachable.
110106
_ => {
111107
self.reachable_symbols.insert(def_id);
112108
}

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

-6
Original file line numberDiff line numberDiff line change
@@ -2743,12 +2743,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
27432743
}
27442744
ObligationCauseCode::BindingObligation(item_def_id, span)
27452745
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => {
2746-
if self.tcx.is_diagnostic_item(sym::Send, item_def_id)
2747-
|| self.tcx.lang_items().sync_trait() == Some(item_def_id)
2748-
{
2749-
return;
2750-
}
2751-
27522746
let item_name = tcx.def_path_str(item_def_id);
27532747
let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id));
27542748
let mut multispan = MultiSpan::from(span);

library/core/src/marker.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,8 @@ macro marker_impls {
7676
#[stable(feature = "rust1", since = "1.0.0")]
7777
#[cfg_attr(not(test), rustc_diagnostic_item = "Send")]
7878
#[rustc_on_unimplemented(
79-
on(_Self = "std::rc::Rc<T, A>", note = "use `std::sync::Arc` instead of `std::rc::Rc`"),
8079
message = "`{Self}` cannot be sent between threads safely",
81-
label = "`{Self}` cannot be sent between threads safely",
82-
note = "consider using `std::sync::Arc<{Self}>`; for more information visit \
83-
<https://doc.rust-lang.org/book/ch16-03-shared-state.html>"
80+
label = "`{Self}` cannot be sent between threads safely"
8481
)]
8582
pub unsafe auto trait Send {
8683
// empty.
@@ -631,11 +628,8 @@ impl<T: ?Sized> Copy for &T {}
631628
any(_Self = "core::cell::RefCell<T>", _Self = "std::cell::RefCell<T>"),
632629
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead",
633630
),
634-
on(_Self = "std::rc::Rc<T, A>", note = "use `std::sync::Arc` instead of `std::rc::Rc`"),
635631
message = "`{Self}` cannot be shared between threads safely",
636-
label = "`{Self}` cannot be shared between threads safely",
637-
note = "consider using `std::sync::Arc<{Self}>`; for more information visit \
638-
<https://doc.rust-lang.org/book/ch16-03-shared-state.html>"
632+
label = "`{Self}` cannot be shared between threads safely"
639633
)]
640634
pub unsafe auto trait Sync {
641635
// FIXME(estebank): once support to add notes in `rustc_on_unimplemented`

src/librustdoc/passes/collect_intra_doc_links.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1430,20 +1430,15 @@ impl LinkCollector<'_, '_> {
14301430
// Otherwise, check if 2 links are same, if so, skip the resolve process.
14311431
//
14321432
// Notice that this algorithm is passive, might possibly miss actual redudant cases.
1433-
let explicit_link = &explicit_link.to_string();
1433+
let explicit_link = explicit_link.to_string();
14341434
let display_text = ori_link.display_text.as_ref().unwrap();
1435-
let display_len = display_text.len();
1436-
let explicit_len = explicit_link.len();
14371435

1438-
if display_len == explicit_len {
1436+
if display_text.len() == explicit_link.len() {
14391437
// Whether they are same or not, skip the resolve process.
14401438
return;
14411439
}
14421440

1443-
if (explicit_len >= display_len
1444-
&& &explicit_link[(explicit_len - display_len)..] == display_text)
1445-
|| (display_len >= explicit_len
1446-
&& &display_text[(display_len - explicit_len)..] == explicit_link)
1441+
if explicit_link.ends_with(&display_text[..]) || display_text.ends_with(&explicit_link[..])
14471442
{
14481443
self.resolve_with_disambiguator_cached(
14491444
display_res_info,

src/librustdoc/passes/lint/redundant_explicit_links.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,8 @@ fn check_redundant_explicit_link<'md>(
9898

9999
let explicit_link = dest.to_string();
100100
let display_link = link_data.resolvable_link.clone()?;
101-
let explicit_len = explicit_link.len();
102-
let display_len = display_link.len();
103101

104-
if (explicit_len >= display_len
105-
&& &explicit_link[(explicit_len - display_len)..] == display_link)
106-
|| (display_len >= explicit_len
107-
&& &display_link[(display_len - explicit_len)..] == explicit_link)
102+
if explicit_link.ends_with(&display_link) || display_link.ends_with(&explicit_link)
108103
{
109104
match link_type {
110105
LinkType::Inline | LinkType::ReferenceUnknown => {

tests/codegen/mem-replace-simple-type.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,21 @@ pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str {
3333
}
3434

3535
#[no_mangle]
36-
// CHECK-LABEL: @replace_short_array(
37-
pub fn replace_short_array(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] {
36+
// CHECK-LABEL: @replace_short_array_3(
37+
pub fn replace_short_array_3(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] {
3838
// CHECK-NOT: alloca
39-
// CHECK: %[[R:.+]] = load <3 x i32>, ptr %r, align 4
40-
// CHECK: store <3 x i32> %[[R]], ptr %result
41-
// CHECK: %[[V:.+]] = load <3 x i32>, ptr %v, align 4
42-
// CHECK: store <3 x i32> %[[V]], ptr %r
39+
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %result, ptr align 4 %r, i64 12, i1 false)
40+
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %r, ptr align 4 %v, i64 12, i1 false)
41+
std::mem::replace(r, v)
42+
}
43+
44+
#[no_mangle]
45+
// CHECK-LABEL: @replace_short_array_4(
46+
pub fn replace_short_array_4(r: &mut [u32; 4], v: [u32; 4]) -> [u32; 4] {
47+
// CHECK-NOT: alloca
48+
// CHECK: %[[R:.+]] = load <4 x i32>, ptr %r, align 4
49+
// CHECK: store <4 x i32> %[[R]], ptr %result
50+
// CHECK: %[[V:.+]] = load <4 x i32>, ptr %v, align 4
51+
// CHECK: store <4 x i32> %[[V]], ptr %r
4352
std::mem::replace(r, v)
4453
}
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// compile-flags: -g -Zmir-opt-level=0 -Zmir-enable-passes=+ScalarReplacementOfAggregates
2+
// compile-flags: -Cno-prepopulate-passes
3+
//
4+
// Tested offsets are only correct for x86_64.
5+
// only-x86_64
6+
7+
#![crate_type = "lib"]
8+
9+
pub struct ExtraSlice<'input> {
10+
slice: &'input [u8],
11+
extra: u32,
12+
}
13+
14+
#[no_mangle]
15+
pub fn extra(s: &[u8]) {
16+
// CHECK: void @extra(
17+
// CHECK: %slice.dbg.spill1 = alloca i32,
18+
// CHECK: %slice.dbg.spill = alloca { ptr, i64 },
19+
// CHECK: %s.dbg.spill = alloca { ptr, i64 },
20+
// CHECK: call void @llvm.dbg.declare(metadata ptr %s.dbg.spill, metadata ![[S_EXTRA:.*]], metadata !DIExpression()),
21+
// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata ![[SLICE_EXTRA:.*]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 128)),
22+
// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill1, metadata ![[SLICE_EXTRA]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 32)),
23+
let slice = ExtraSlice { slice: s, extra: s.len() as u32 };
24+
}
25+
26+
struct Zst;
27+
28+
pub struct ZstSlice<'input> {
29+
slice: &'input [u8],
30+
extra: Zst,
31+
}
32+
33+
#[no_mangle]
34+
pub fn zst(s: &[u8]) {
35+
// The field `extra` is a ZST. The fragment for the field `slice` encompasses the whole
36+
// variable, so is not a fragment. In that case, the variable must have no fragment.
37+
38+
// CHECK: void @zst(
39+
// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata !{}, metadata !DIExpression(DW_OP_LLVM_fragment,
40+
// CHECK: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST:.*]], metadata !DIExpression()),
41+
// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST]],
42+
let slice = ZstSlice { slice: s, extra: Zst };
43+
}
44+
45+
// CHECK: ![[S_EXTRA]] = !DILocalVariable(name: "s",
46+
// CHECK: ![[SLICE_EXTRA]] = !DILocalVariable(name: "slice",

tests/codegen/swap-small-types.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ type RGB48 = [u16; 3];
1111
// CHECK-LABEL: @swap_rgb48_manually(
1212
#[no_mangle]
1313
pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) {
14-
// CHECK-NOT: alloca
15-
// CHECK: %[[TEMP0:.+]] = load <3 x i16>, ptr %x, align 2
16-
// CHECK: %[[TEMP1:.+]] = load <3 x i16>, ptr %y, align 2
17-
// CHECK: store <3 x i16> %[[TEMP1]], ptr %x, align 2
18-
// CHECK: store <3 x i16> %[[TEMP0]], ptr %y, align 2
14+
// FIXME: See #115212 for why this has an alloca again
15+
16+
// CHECK: alloca [3 x i16], align 2
17+
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
18+
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
19+
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
1920

2021
let temp = *x;
2122
*x = *y;
@@ -25,11 +26,25 @@ pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) {
2526
// CHECK-LABEL: @swap_rgb48
2627
#[no_mangle]
2728
pub fn swap_rgb48(x: &mut RGB48, y: &mut RGB48) {
29+
// FIXME: See #115212 for why this has an alloca again
30+
31+
// CHECK: alloca [3 x i16], align 2
32+
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
33+
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
34+
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
35+
swap(x, y)
36+
}
37+
38+
type RGBA64 = [u16; 4];
39+
40+
// CHECK-LABEL: @swap_rgba64
41+
#[no_mangle]
42+
pub fn swap_rgba64(x: &mut RGBA64, y: &mut RGBA64) {
2843
// CHECK-NOT: alloca
29-
// CHECK: load <3 x i16>
30-
// CHECK: load <3 x i16>
31-
// CHECK: store <3 x i16>
32-
// CHECK: store <3 x i16>
44+
// CHECK-DAG: %[[XVAL:.+]] = load <4 x i16>, ptr %x, align 2
45+
// CHECK-DAG: %[[YVAL:.+]] = load <4 x i16>, ptr %y, align 2
46+
// CHECK-DAG: store <4 x i16> %[[YVAL]], ptr %x, align 2
47+
// CHECK-DAG: store <4 x i16> %[[XVAL]], ptr %y, align 2
3348
swap(x, y)
3449
}
3550

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
3+
/// [`…foo`] [`…bar`] [`Err`]
4+
pub struct Broken {}
5+
6+
/// [`…`] [`…`] [`Err`]
7+
pub struct Broken2 {}
8+
9+
/// [`…`][…] [`…`][…] [`Err`]
10+
pub struct Broken3 {}
11+
12+
/// […………………………][Broken3]
13+
pub struct Broken4 {}
14+
15+
/// [Broken3][…………………………]
16+
pub struct Broken5 {}
17+
18+
pub struct Err;

tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8
55
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
66
|
77
= help: the trait `Send` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
8-
= note: consider using `std::sync::Arc<<<Self as Case1>::C as Iterator>::Item>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
98
help: consider further restricting the associated type
109
|
1110
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
@@ -30,7 +29,6 @@ LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8
3029
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
3130
|
3231
= help: the trait `Sync` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
33-
= note: consider using `std::sync::Arc<<<Self as Case1>::C as Iterator>::Item>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
3432
help: consider further restricting the associated type
3533
|
3634
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Sync {

tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ LL | is_send(foo::<T>());
1414
| ^^^^^^^^^^ future returned by `foo` is not `Send`
1515
|
1616
= help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>>`
17-
= note: consider using `std::sync::Arc<impl Future<Output = Result<(), ()>>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
1817
note: future is not `Send` as it awaits another future which is not `Send`
1918
--> $DIR/basic.rs:13:5
2019
|

tests/ui/async-await/async-await-let-else.drop_tracking.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | is_send(foo(Some(true)));
55
| ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
66
|
77
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
8-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
98
note: future is not `Send` as this value is used across an await
109
--> $DIR/async-await-let-else.rs:11:15
1110
|
@@ -33,7 +32,6 @@ LL | is_send(foo2(Some(true)));
3332
| required by a bound introduced by this call
3433
|
3534
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
36-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
3735
note: required because it's used within this `async fn` body
3836
--> $DIR/async-await-let-else.rs:27:29
3937
|
@@ -66,7 +64,6 @@ LL | is_send(foo3(Some(true)));
6664
| ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
6765
|
6866
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
69-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
7067
note: future is not `Send` as this value is used across an await
7168
--> $DIR/async-await-let-else.rs:33:29
7269
|
@@ -88,7 +85,6 @@ LL | is_send(foo4(Some(true)));
8885
| ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
8986
|
9087
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
91-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
9288
note: future is not `Send` as this value is used across an await
9389
--> $DIR/async-await-let-else.rs:41:15
9490
|

tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | is_send(foo(Some(true)));
55
| ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
66
|
77
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
8-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
98
note: future is not `Send` as this value is used across an await
109
--> $DIR/async-await-let-else.rs:11:15
1110
|
@@ -31,7 +30,6 @@ LL | is_send(foo2(Some(true)));
3130
| required by a bound introduced by this call
3231
|
3332
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
34-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
3533
note: required because it's used within this `async fn` body
3634
--> $DIR/async-await-let-else.rs:27:29
3735
|
@@ -64,7 +62,6 @@ LL | is_send(foo3(Some(true)));
6462
| ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
6563
|
6664
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
67-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
6865
note: future is not `Send` as this value is used across an await
6966
--> $DIR/async-await-let-else.rs:33:29
7067
|
@@ -85,7 +82,6 @@ LL | is_send(foo4(Some(true)));
8582
| ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
8683
|
8784
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
88-
= note: use `std::sync::Arc` instead of `std::rc::Rc`
8985
note: future is not `Send` as this value is used across an await
9086
--> $DIR/async-await-let-else.rs:41:15
9187
|

0 commit comments

Comments
 (0)