Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3f5fd8d

Browse files
committedAug 6, 2024
Auto merge of #128635 - pietroalbini:pa-1.80.1, r=pietroalbini
Prepare Rust 1.80.1 point release The point release is scheduled to include: * #128271 * #128618
2 parents 0514789 + 1cc8da5 commit 3f5fd8d

40 files changed

+236
-308
lines changed
 

‎RELEASES.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
Version 1.80 (2024-07-25)
1+
Version 1.80.1 (2024-08-08)
2+
===========================
3+
4+
<a id="1.80.1"></a>
5+
6+
- [Fix miscompilation in the jump threading MIR optimization when comparing floats](https://github.com/rust-lang/rust/pull/128271)
7+
- [Revert changes to the `dead_code` lint from 1.80.0](https://github.com/rust-lang/rust/pull/128618)
8+
9+
Version 1.80.0 (2024-07-25)
210
==========================
311

412
<a id="1.80-Language"></a>

‎compiler/rustc_mir_transform/src/jump_threading.rs

+7
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,13 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
494494
BinOp::Ne => ScalarInt::FALSE,
495495
_ => return None,
496496
};
497+
if value.const_.ty().is_floating_point() {
498+
// Floating point equality does not follow bit-patterns.
499+
// -0.0 and NaN both have special rules for equality,
500+
// and therefore we cannot use integer comparisons for them.
501+
// Avoid handling them, though this could be extended in the future.
502+
return None;
503+
}
497504
let value = value.const_.normalize(self.tcx, self.param_env).try_to_scalar_int()?;
498505
let conds = conditions.map(self.arena, |c| Condition {
499506
value,

‎compiler/rustc_passes/src/dead.rs

+28-93
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hir::{Node, PatKind, TyKind};
1515
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1616
use rustc_middle::middle::privacy::Level;
1717
use rustc_middle::query::Providers;
18-
use rustc_middle::ty::{self, AssocItemContainer, TyCtxt};
18+
use rustc_middle::ty::{self, TyCtxt};
1919
use rustc_middle::{bug, span_bug};
2020
use rustc_session::lint;
2121
use rustc_session::lint::builtin::DEAD_CODE;
@@ -44,63 +44,16 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
4444
)
4545
}
4646

47-
struct Publicness {
48-
ty_is_public: bool,
49-
ty_and_all_fields_are_public: bool,
50-
}
51-
52-
impl Publicness {
53-
fn new(ty_is_public: bool, ty_and_all_fields_are_public: bool) -> Self {
54-
Self { ty_is_public, ty_and_all_fields_are_public }
55-
}
56-
}
57-
58-
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
59-
// treat PhantomData and positional ZST as public,
60-
// we don't want to lint types which only have them,
61-
// cause it's a common way to use such types to check things like well-formedness
62-
tcx.adt_def(id).all_fields().all(|field| {
63-
let field_type = tcx.type_of(field.did).instantiate_identity();
64-
if field_type.is_phantom_data() {
65-
return true;
66-
}
67-
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
68-
if is_positional
69-
&& tcx
70-
.layout_of(tcx.param_env(field.did).and(field_type))
71-
.map_or(true, |layout| layout.is_zst())
72-
{
73-
return true;
74-
}
75-
field.vis.is_public()
76-
})
77-
}
78-
79-
/// check struct and its fields are public or not,
80-
/// for enum and union, just check they are public,
81-
/// and doesn't solve types like &T for now, just skip them
82-
fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> Publicness {
47+
fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> bool {
8348
if let TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
8449
&& let Res::Def(def_kind, def_id) = path.res
8550
&& def_id.is_local()
51+
&& matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
8652
{
87-
return match def_kind {
88-
DefKind::Enum | DefKind::Union => {
89-
let ty_is_public = tcx.visibility(def_id).is_public();
90-
Publicness::new(ty_is_public, ty_is_public)
91-
}
92-
DefKind::Struct => {
93-
let ty_is_public = tcx.visibility(def_id).is_public();
94-
Publicness::new(
95-
ty_is_public,
96-
ty_is_public && struct_all_fields_are_public(tcx, def_id),
97-
)
98-
}
99-
_ => Publicness::new(true, true),
100-
};
53+
tcx.visibility(def_id).is_public()
54+
} else {
55+
true
10156
}
102-
103-
Publicness::new(true, true)
10457
}
10558

10659
/// Determine if a work from the worklist is coming from the a `#[allow]`
@@ -474,11 +427,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
474427
{
475428
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..))
476429
&& !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty)
477-
.ty_and_all_fields_are_public
478430
{
479-
// skip impl-items of non pure pub ty,
480-
// cause we don't know the ty is constructed or not,
481-
// check these later in `solve_rest_impl_items`
431+
// skip methods of private ty,
432+
// they would be solved in `solve_rest_impl_items`
482433
continue;
483434
}
484435

@@ -559,21 +510,22 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
559510
&& let Some(local_def_id) = def_id.as_local()
560511
&& matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
561512
{
513+
if self.tcx.visibility(impl_item_id).is_public() {
514+
// for the public method, we don't know the trait item is used or not,
515+
// so we mark the method live if the self is used
516+
return self.live_symbols.contains(&local_def_id);
517+
}
518+
562519
if let Some(trait_item_id) = self.tcx.associated_item(impl_item_id).trait_item_def_id
563520
&& let Some(local_id) = trait_item_id.as_local()
564521
{
565-
// for the local impl item, we can know the trait item is used or not,
522+
// for the private method, we can know the trait item is used or not,
566523
// so we mark the method live if the self is used and the trait item is used
567-
self.live_symbols.contains(&local_id) && self.live_symbols.contains(&local_def_id)
568-
} else {
569-
// for the foreign method and inherent pub method,
570-
// we don't know the trait item or the method is used or not,
571-
// so we mark the method live if the self is used
572-
self.live_symbols.contains(&local_def_id)
524+
return self.live_symbols.contains(&local_id)
525+
&& self.live_symbols.contains(&local_def_id);
573526
}
574-
} else {
575-
false
576527
}
528+
false
577529
}
578530
}
579531

@@ -795,9 +747,7 @@ fn check_item<'tcx>(
795747
.iter()
796748
.filter_map(|def_id| def_id.as_local());
797749

798-
let self_ty = tcx.hir().item(id).expect_impl().self_ty;
799-
let Publicness { ty_is_public, ty_and_all_fields_are_public } =
800-
ty_ref_to_pub_struct(tcx, self_ty);
750+
let ty_is_pub = ty_ref_to_pub_struct(tcx, tcx.hir().item(id).expect_impl().self_ty);
801751

802752
// And we access the Map here to get HirId from LocalDefId
803753
for local_def_id in local_def_ids {
@@ -813,20 +763,18 @@ fn check_item<'tcx>(
813763
// for trait impl blocks,
814764
// mark the method live if the self_ty is public,
815765
// or the method is public and may construct self
816-
if of_trait && matches!(tcx.def_kind(local_def_id), DefKind::AssocTy)
817-
|| tcx.visibility(local_def_id).is_public()
818-
&& (ty_and_all_fields_are_public || may_construct_self)
766+
if of_trait
767+
&& (!matches!(tcx.def_kind(local_def_id), DefKind::AssocFn)
768+
|| tcx.visibility(local_def_id).is_public()
769+
&& (ty_is_pub || may_construct_self))
819770
{
820-
// if the impl item is public,
821-
// and the ty may be constructed or can be constructed in foreign crates,
822-
// mark the impl item live
823771
worklist.push((local_def_id, ComesFromAllowExpect::No));
824772
} else if let Some(comes_from_allow) =
825773
has_allow_dead_code_or_lang_attr(tcx, local_def_id)
826774
{
827775
worklist.push((local_def_id, comes_from_allow));
828-
} else if of_trait || tcx.visibility(local_def_id).is_public() && ty_is_public {
829-
// private impl items of traits || public impl items not constructs self
776+
} else if of_trait {
777+
// private method || public method not constructs self
830778
unsolved_impl_items.push((id, local_def_id));
831779
}
832780
}
@@ -893,14 +841,6 @@ fn create_and_seed_worklist(
893841
effective_vis
894842
.is_public_at_level(Level::Reachable)
895843
.then_some(id)
896-
.filter(|&id|
897-
// checks impls, impl-items and pub structs with all public fields later
898-
match tcx.def_kind(id) {
899-
DefKind::Impl { .. } => false,
900-
DefKind::AssocConst | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
901-
DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
902-
_ => true
903-
})
904844
.map(|id| (id, ComesFromAllowExpect::No))
905845
})
906846
// Seed entry point
@@ -1173,15 +1113,10 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
11731113
|| (def_kind == DefKind::Trait && live_symbols.contains(&item.owner_id.def_id))
11741114
{
11751115
for &def_id in tcx.associated_item_def_ids(item.owner_id.def_id) {
1176-
// We have diagnosed unused assoc consts and fns in traits
1116+
// We have diagnosed unused methods in traits
11771117
if matches!(def_kind, DefKind::Impl { of_trait: true })
1178-
&& matches!(tcx.def_kind(def_id), DefKind::AssocConst | DefKind::AssocFn)
1179-
// skip unused public inherent methods,
1180-
// cause we have diagnosed unconstructed struct
1181-
|| matches!(def_kind, DefKind::Impl { of_trait: false })
1182-
&& tcx.visibility(def_id).is_public()
1183-
&& ty_ref_to_pub_struct(tcx, tcx.hir().item(item).expect_impl().self_ty).ty_is_public
1184-
|| def_kind == DefKind::Trait && tcx.def_kind(def_id) == DefKind::AssocTy
1118+
&& tcx.def_kind(def_id) == DefKind::AssocFn
1119+
|| def_kind == DefKind::Trait && tcx.def_kind(def_id) != DefKind::AssocFn
11851120
{
11861121
continue;
11871122
}

‎src/ci/github-actions/jobs.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ runners:
3333
<<: *base-job
3434

3535
- &job-aarch64-linux
36-
os: [ self-hosted, ARM64, linux ]
36+
os: ubuntu-22.04-arm64-8core-32gb
3737

3838
envs:
3939
env-x86_64-apple-tests: &env-x86_64-apple-tests

‎src/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.80.0
1+
1.80.1

‎tests/codegen-units/item-collection/generic-impl.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ impl<T> Struct<T> {
2222
}
2323
}
2424

25-
pub struct _LifeTimeOnly<'a> {
25+
pub struct LifeTimeOnly<'a> {
2626
_a: &'a u32,
2727
}
2828

29-
impl<'a> _LifeTimeOnly<'a> {
30-
//~ MONO_ITEM fn _LifeTimeOnly::<'_>::foo
29+
impl<'a> LifeTimeOnly<'a> {
30+
//~ MONO_ITEM fn LifeTimeOnly::<'_>::foo
3131
pub fn foo(&self) {}
32-
//~ MONO_ITEM fn _LifeTimeOnly::<'_>::bar
32+
//~ MONO_ITEM fn LifeTimeOnly::<'_>::bar
3333
pub fn bar(&'a self) {}
34-
//~ MONO_ITEM fn _LifeTimeOnly::<'_>::baz
34+
//~ MONO_ITEM fn LifeTimeOnly::<'_>::baz
3535
pub fn baz<'b>(&'b self) {}
3636

3737
pub fn non_instantiated<T>(&self) {}

‎tests/codegen-units/item-collection/overloaded-operators.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,44 @@
55

66
use std::ops::{Add, Deref, Index, IndexMut};
77

8-
pub struct _Indexable {
8+
pub struct Indexable {
99
data: [u8; 3],
1010
}
1111

12-
impl Index<usize> for _Indexable {
12+
impl Index<usize> for Indexable {
1313
type Output = u8;
1414

15-
//~ MONO_ITEM fn <_Indexable as std::ops::Index<usize>>::index
15+
//~ MONO_ITEM fn <Indexable as std::ops::Index<usize>>::index
1616
fn index(&self, index: usize) -> &Self::Output {
1717
if index >= 3 { &self.data[0] } else { &self.data[index] }
1818
}
1919
}
2020

21-
impl IndexMut<usize> for _Indexable {
22-
//~ MONO_ITEM fn <_Indexable as std::ops::IndexMut<usize>>::index_mut
21+
impl IndexMut<usize> for Indexable {
22+
//~ MONO_ITEM fn <Indexable as std::ops::IndexMut<usize>>::index_mut
2323
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2424
if index >= 3 { &mut self.data[0] } else { &mut self.data[index] }
2525
}
2626
}
2727

28-
//~ MONO_ITEM fn <_Equatable as std::cmp::PartialEq>::eq
29-
//~ MONO_ITEM fn <_Equatable as std::cmp::PartialEq>::ne
28+
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::eq
29+
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::ne
3030
#[derive(PartialEq)]
31-
pub struct _Equatable(u32);
31+
pub struct Equatable(u32);
3232

33-
impl Add<u32> for _Equatable {
33+
impl Add<u32> for Equatable {
3434
type Output = u32;
3535

36-
//~ MONO_ITEM fn <_Equatable as std::ops::Add<u32>>::add
36+
//~ MONO_ITEM fn <Equatable as std::ops::Add<u32>>::add
3737
fn add(self, rhs: u32) -> u32 {
3838
self.0 + rhs
3939
}
4040
}
4141

42-
impl Deref for _Equatable {
42+
impl Deref for Equatable {
4343
type Target = u32;
4444

45-
//~ MONO_ITEM fn <_Equatable as std::ops::Deref>::deref
45+
//~ MONO_ITEM fn <Equatable as std::ops::Deref>::deref
4646
fn deref(&self) -> &Self::Target {
4747
&self.0
4848
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
- // MIR for `floats` before JumpThreading
2+
+ // MIR for `floats` after JumpThreading
3+
4+
fn floats() -> u32 {
5+
let mut _0: u32;
6+
let _1: f64;
7+
let mut _2: bool;
8+
let mut _3: bool;
9+
let mut _4: f64;
10+
scope 1 {
11+
debug x => _1;
12+
}
13+
14+
bb0: {
15+
StorageLive(_1);
16+
StorageLive(_2);
17+
_2 = const true;
18+
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
19+
+ goto -> bb1;
20+
}
21+
22+
bb1: {
23+
_1 = const -0f64;
24+
goto -> bb3;
25+
}
26+
27+
bb2: {
28+
_1 = const 1f64;
29+
goto -> bb3;
30+
}
31+
32+
bb3: {
33+
StorageDead(_2);
34+
StorageLive(_3);
35+
StorageLive(_4);
36+
_4 = _1;
37+
_3 = Eq(move _4, const 0f64);
38+
switchInt(move _3) -> [0: bb5, otherwise: bb4];
39+
}
40+
41+
bb4: {
42+
StorageDead(_4);
43+
_0 = const 0_u32;
44+
goto -> bb6;
45+
}
46+
47+
bb5: {
48+
StorageDead(_4);
49+
_0 = const 1_u32;
50+
goto -> bb6;
51+
}
52+
53+
bb6: {
54+
StorageDead(_3);
55+
StorageDead(_1);
56+
return;
57+
}
58+
}
59+
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.