Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ea70a41

Browse files
committedJan 8, 2025·
Auto merge of rust-lang#135227 - matthiaskrgr:rollup-5itqccr, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#134389 (Condvar: implement wait_timeout for targets without threads) - rust-lang#134920 (Convert typeck constraints in location-sensitive polonius) - rust-lang#135032 (triagebot: register `relnotes-interest-group` ping group) - rust-lang#135176 (More compelling env_clear() examples) - rust-lang#135184 (Reserve x18 register for aarch64 wrs vxworks target) - rust-lang#135203 (arm: add unstable soft-float target feature) - rust-lang#135219 (warn about broken simd not only on structs but also enums and unions when we didn't opt in to it) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1f81f90 + 846a9c4 commit ea70a41

File tree

22 files changed

+411
-136
lines changed

22 files changed

+411
-136
lines changed
 

‎compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
242242
}
243243
}
244244

245-
ast::ItemKind::Struct(..) => {
245+
ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => {
246246
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
247247
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
248248
if item.has_name(sym::simd) {

‎compiler/rustc_borrowck/src/borrow_set.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_mir_dataflow::move_paths::MoveData;
1111
use tracing::debug;
1212

1313
use crate::BorrowIndex;
14-
use crate::path_utils::allow_two_phase_borrow;
1514
use crate::place_ext::PlaceExt;
1615

1716
pub struct BorrowSet<'tcx> {
@@ -350,7 +349,7 @@ impl<'a, 'tcx> GatherBorrows<'a, 'tcx> {
350349
start_location, assigned_place, borrow_index,
351350
);
352351

353-
if !allow_two_phase_borrow(kind) {
352+
if !kind.allows_two_phase_borrow() {
354353
debug!(" -> {:?}", start_location);
355354
return;
356355
}

‎compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir::intravisit::Visitor;
1010
use rustc_hir::{self as hir, BindingMode, ByRef, Node};
1111
use rustc_middle::bug;
1212
use rustc_middle::hir::place::PlaceBase;
13+
use rustc_middle::mir::visit::PlaceContext;
1314
use rustc_middle::mir::{
1415
self, BindingForm, Local, LocalDecl, LocalInfo, LocalKind, Location, Mutability, Place,
1516
PlaceRef, ProjectionElem,
@@ -22,7 +23,6 @@ use rustc_trait_selection::traits;
2223
use tracing::debug;
2324

2425
use crate::diagnostics::BorrowedContentSource;
25-
use crate::util::FindAssignments;
2626
use crate::{MirBorrowckCtxt, session_diagnostics};
2727

2828
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -1088,6 +1088,38 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
10881088
}
10891089
}
10901090

1091+
/// Finds all statements that assign directly to local (i.e., X = ...) and returns their
1092+
/// locations.
1093+
fn find_assignments(&self, local: Local) -> Vec<Location> {
1094+
use rustc_middle::mir::visit::Visitor;
1095+
1096+
struct FindLocalAssignmentVisitor {
1097+
needle: Local,
1098+
locations: Vec<Location>,
1099+
}
1100+
1101+
impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor {
1102+
fn visit_local(
1103+
&mut self,
1104+
local: Local,
1105+
place_context: PlaceContext,
1106+
location: Location,
1107+
) {
1108+
if self.needle != local {
1109+
return;
1110+
}
1111+
1112+
if place_context.is_place_assignment() {
1113+
self.locations.push(location);
1114+
}
1115+
}
1116+
}
1117+
1118+
let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] };
1119+
visitor.visit_body(self.body);
1120+
visitor.locations
1121+
}
1122+
10911123
fn suggest_make_local_mut(&self, err: &mut Diag<'_>, local: Local, name: Symbol) {
10921124
let local_decl = &self.body.local_decls[local];
10931125

@@ -1121,7 +1153,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11211153
})) => {
11221154
// check if the RHS is from desugaring
11231155
let opt_assignment_rhs_span =
1124-
self.body.find_assignments(local).first().map(|&location| {
1156+
self.find_assignments(local).first().map(|&location| {
11251157
if let Some(mir::Statement {
11261158
source_info: _,
11271159
kind:

‎compiler/rustc_borrowck/src/lib.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
use std::cell::RefCell;
1919
use std::marker::PhantomData;
20-
use std::ops::Deref;
20+
use std::ops::{ControlFlow, Deref};
2121

2222
use rustc_abi::FieldIdx;
2323
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -81,7 +81,6 @@ mod session_diagnostics;
8181
mod type_check;
8282
mod universal_regions;
8383
mod used_muts;
84-
mod util;
8584

8685
/// A public API provided for the Rust compiler consumers.
8786
pub mod consumers;
@@ -1054,31 +1053,31 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
10541053
rw,
10551054
(borrow_index, borrow),
10561055
);
1057-
Control::Continue
1056+
ControlFlow::Continue(())
10581057
}
10591058

10601059
(Read(_), BorrowKind::Shared | BorrowKind::Fake(_))
10611060
| (
10621061
Read(ReadKind::Borrow(BorrowKind::Fake(FakeBorrowKind::Shallow))),
10631062
BorrowKind::Mut { .. },
1064-
) => Control::Continue,
1063+
) => ControlFlow::Continue(()),
10651064

10661065
(Reservation(_), BorrowKind::Fake(_) | BorrowKind::Shared) => {
10671066
// This used to be a future compatibility warning (to be
10681067
// disallowed on NLL). See rust-lang/rust#56254
1069-
Control::Continue
1068+
ControlFlow::Continue(())
10701069
}
10711070

10721071
(Write(WriteKind::Move), BorrowKind::Fake(FakeBorrowKind::Shallow)) => {
10731072
// Handled by initialization checks.
1074-
Control::Continue
1073+
ControlFlow::Continue(())
10751074
}
10761075

10771076
(Read(kind), BorrowKind::Mut { .. }) => {
10781077
// Reading from mere reservations of mutable-borrows is OK.
10791078
if !is_active(this.dominators(), borrow, location) {
1080-
assert!(allow_two_phase_borrow(borrow.kind));
1081-
return Control::Continue;
1079+
assert!(borrow.kind.allows_two_phase_borrow());
1080+
return ControlFlow::Continue(());
10821081
}
10831082

10841083
error_reported = true;
@@ -1094,7 +1093,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
10941093
this.buffer_error(err);
10951094
}
10961095
}
1097-
Control::Break
1096+
ControlFlow::Break(())
10981097
}
10991098

11001099
(Reservation(kind) | Activation(kind, _) | Write(kind), _) => {
@@ -1141,7 +1140,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
11411140
this.report_illegal_mutation_of_borrowed(location, place_span, borrow)
11421141
}
11431142
}
1144-
Control::Break
1143+
ControlFlow::Break(())
11451144
}
11461145
},
11471146
);
@@ -1185,7 +1184,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
11851184
}
11861185
BorrowKind::Mut { .. } => {
11871186
let wk = WriteKind::MutableBorrow(bk);
1188-
if allow_two_phase_borrow(bk) {
1187+
if bk.allows_two_phase_borrow() {
11891188
(Deep, Reservation(wk))
11901189
} else {
11911190
(Deep, Write(wk))

‎compiler/rustc_borrowck/src/nll.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ pub(crate) fn compute_regions<'a, 'tcx>(
142142

143143
// If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives
144144
// constraints.
145-
let localized_outlives_constraints = polonius_context
146-
.as_mut()
147-
.map(|polonius_context| polonius_context.create_localized_constraints(&mut regioncx, body));
145+
let localized_outlives_constraints = polonius_context.as_mut().map(|polonius_context| {
146+
polonius_context.create_localized_constraints(infcx.tcx, &regioncx, body)
147+
});
148148

149149
// If requested: dump NLL facts, and run legacy polonius analysis.
150150
let polonius_output = all_facts.as_ref().and_then(|all_facts| {

‎compiler/rustc_borrowck/src/path_utils.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,14 @@
1+
use std::ops::ControlFlow;
2+
13
use rustc_abi::FieldIdx;
24
use rustc_data_structures::graph::dominators::Dominators;
3-
use rustc_middle::mir::{BasicBlock, Body, BorrowKind, Location, Place, PlaceRef, ProjectionElem};
5+
use rustc_middle::mir::{BasicBlock, Body, Location, Place, PlaceRef, ProjectionElem};
46
use rustc_middle::ty::TyCtxt;
57
use tracing::debug;
68

79
use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
810
use crate::{AccessDepth, BorrowIndex, places_conflict};
911

10-
/// Returns `true` if the borrow represented by `kind` is
11-
/// allowed to be split into separate Reservation and
12-
/// Activation phases.
13-
pub(super) fn allow_two_phase_borrow(kind: BorrowKind) -> bool {
14-
kind.allows_two_phase_borrow()
15-
}
16-
17-
/// Control for the path borrow checking code
18-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
19-
pub(super) enum Control {
20-
Continue,
21-
Break,
22-
}
23-
2412
/// Encapsulates the idea of iterating over every borrow that involves a particular path
2513
pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
2614
s: &mut S,
@@ -31,7 +19,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
3119
is_candidate: I,
3220
mut op: F,
3321
) where
34-
F: FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> Control,
22+
F: FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> ControlFlow<()>,
3523
I: Fn(BorrowIndex) -> bool,
3624
{
3725
let (access, place) = access_place;
@@ -62,7 +50,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
6250
i, borrowed, place, access
6351
);
6452
let ctrl = op(s, i, borrowed);
65-
if ctrl == Control::Break {
53+
if matches!(ctrl, ControlFlow::Break(_)) {
6654
return;
6755
}
6856
}

‎compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::ops::ControlFlow;
2+
13
use rustc_data_structures::graph::dominators::Dominators;
24
use rustc_middle::bug;
35
use rustc_middle::mir::visit::Visitor;
@@ -260,7 +262,7 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
260262
}
261263
BorrowKind::Mut { .. } => {
262264
let wk = WriteKind::MutableBorrow(bk);
263-
if allow_two_phase_borrow(bk) {
265+
if bk.allows_two_phase_borrow() {
264266
(Deep, Reservation(wk))
265267
} else {
266268
(Deep, Write(wk))
@@ -378,8 +380,8 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
378380
// Reading from mere reservations of mutable-borrows is OK.
379381
if !is_active(this.dominators, borrow, location) {
380382
// If the borrow isn't active yet, reads don't invalidate it
381-
assert!(allow_two_phase_borrow(borrow.kind));
382-
return Control::Continue;
383+
assert!(borrow.kind.allows_two_phase_borrow());
384+
return ControlFlow::Continue(());
383385
}
384386

385387
// Unique and mutable borrows are invalidated by reads from any
@@ -395,7 +397,7 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
395397
this.emit_loan_invalidated_at(borrow_index, location);
396398
}
397399
}
398-
Control::Continue
400+
ControlFlow::Continue(())
399401
},
400402
);
401403
}

‎compiler/rustc_borrowck/src/polonius/mod.rs

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,20 @@ mod constraints;
3737
mod dump;
3838
pub(crate) mod legacy;
3939
mod liveness_constraints;
40+
mod typeck_constraints;
4041

4142
use std::collections::BTreeMap;
4243

4344
use rustc_index::bit_set::SparseBitMatrix;
44-
use rustc_middle::mir::{Body, Location};
45-
use rustc_middle::ty::RegionVid;
45+
use rustc_middle::mir::Body;
46+
use rustc_middle::ty::{RegionVid, TyCtxt};
4647
use rustc_mir_dataflow::points::PointIndex;
4748

4849
pub(crate) use self::constraints::*;
4950
pub(crate) use self::dump::dump_polonius_mir;
5051
use self::liveness_constraints::create_liveness_constraints;
52+
use self::typeck_constraints::convert_typeck_constraints;
5153
use crate::RegionInferenceContext;
52-
use crate::constraints::OutlivesConstraint;
53-
use crate::region_infer::values::LivenessValues;
54-
use crate::type_check::Locations;
5554

5655
/// This struct holds the data needed to create the Polonius localized constraints.
5756
pub(crate) struct PoloniusContext {
@@ -88,14 +87,17 @@ impl PoloniusContext {
8887
/// - encoding liveness constraints
8988
pub(crate) fn create_localized_constraints<'tcx>(
9089
&self,
90+
tcx: TyCtxt<'tcx>,
9191
regioncx: &RegionInferenceContext<'tcx>,
9292
body: &Body<'tcx>,
9393
) -> LocalizedOutlivesConstraintSet {
9494
let mut localized_outlives_constraints = LocalizedOutlivesConstraintSet::default();
9595
convert_typeck_constraints(
96+
tcx,
9697
body,
9798
regioncx.liveness_constraints(),
9899
regioncx.outlives_constraints(),
100+
regioncx.universal_regions(),
99101
&mut localized_outlives_constraints,
100102
);
101103

@@ -117,38 +119,3 @@ impl PoloniusContext {
117119
localized_outlives_constraints
118120
}
119121
}
120-
121-
/// Propagate loans throughout the subset graph at a given point (with some subtleties around the
122-
/// location where effects start to be visible).
123-
fn convert_typeck_constraints<'tcx>(
124-
body: &Body<'tcx>,
125-
liveness: &LivenessValues,
126-
outlives_constraints: impl Iterator<Item = OutlivesConstraint<'tcx>>,
127-
localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet,
128-
) {
129-
for outlives_constraint in outlives_constraints {
130-
match outlives_constraint.locations {
131-
Locations::All(_) => {
132-
// For now, turn logical constraints holding at all points into physical edges at
133-
// every point in the graph.
134-
// FIXME: encode this into *traversal* instead.
135-
for (block, bb) in body.basic_blocks.iter_enumerated() {
136-
let statement_count = bb.statements.len();
137-
for statement_index in 0..=statement_count {
138-
let current_location = Location { block, statement_index };
139-
let current_point = liveness.point_from_location(current_location);
140-
141-
localized_outlives_constraints.push(LocalizedOutlivesConstraint {
142-
source: outlives_constraint.sup,
143-
from: current_point,
144-
target: outlives_constraint.sub,
145-
to: current_point,
146-
});
147-
}
148-
}
149-
}
150-
151-
_ => {}
152-
}
153-
}
154-
}
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
use rustc_data_structures::fx::FxHashSet;
2+
use rustc_middle::mir::{Body, Location, Statement, StatementKind, Terminator, TerminatorKind};
3+
use rustc_middle::ty::{TyCtxt, TypeVisitable};
4+
use rustc_mir_dataflow::points::PointIndex;
5+
6+
use super::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet};
7+
use crate::constraints::OutlivesConstraint;
8+
use crate::region_infer::values::LivenessValues;
9+
use crate::type_check::Locations;
10+
use crate::universal_regions::UniversalRegions;
11+
12+
/// Propagate loans throughout the subset graph at a given point (with some subtleties around the
13+
/// location where effects start to be visible).
14+
pub(super) fn convert_typeck_constraints<'tcx>(
15+
tcx: TyCtxt<'tcx>,
16+
body: &Body<'tcx>,
17+
liveness: &LivenessValues,
18+
outlives_constraints: impl Iterator<Item = OutlivesConstraint<'tcx>>,
19+
universal_regions: &UniversalRegions<'tcx>,
20+
localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet,
21+
) {
22+
for outlives_constraint in outlives_constraints {
23+
match outlives_constraint.locations {
24+
Locations::All(_) => {
25+
// For now, turn logical constraints holding at all points into physical edges at
26+
// every point in the graph.
27+
// FIXME: encode this into *traversal* instead.
28+
for (block, bb) in body.basic_blocks.iter_enumerated() {
29+
let statement_count = bb.statements.len();
30+
for statement_index in 0..=statement_count {
31+
let current_location = Location { block, statement_index };
32+
let current_point = liveness.point_from_location(current_location);
33+
34+
localized_outlives_constraints.push(LocalizedOutlivesConstraint {
35+
source: outlives_constraint.sup,
36+
from: current_point,
37+
target: outlives_constraint.sub,
38+
to: current_point,
39+
});
40+
}
41+
}
42+
}
43+
44+
Locations::Single(location) => {
45+
// This constraint is marked as holding at one location, we localize it to that
46+
// location or its successor, depending on the corresponding MIR
47+
// statement/terminator. Unfortunately, they all show up from typeck as coming "on
48+
// entry", so for now we modify them to take effects that should apply "on exit"
49+
// into account.
50+
//
51+
// FIXME: this approach is subtle, complicated, and hard to test, so we should track
52+
// this information better in MIR typeck instead, for example with a new `Locations`
53+
// variant that contains which node is crossing over between entry and exit.
54+
let point = liveness.point_from_location(location);
55+
let localized_constraint = if let Some(stmt) =
56+
body[location.block].statements.get(location.statement_index)
57+
{
58+
localize_statement_constraint(
59+
tcx,
60+
body,
61+
stmt,
62+
liveness,
63+
&outlives_constraint,
64+
location,
65+
point,
66+
universal_regions,
67+
)
68+
} else {
69+
assert_eq!(location.statement_index, body[location.block].statements.len());
70+
let terminator = body[location.block].terminator();
71+
localize_terminator_constraint(
72+
tcx,
73+
body,
74+
terminator,
75+
liveness,
76+
&outlives_constraint,
77+
point,
78+
universal_regions,
79+
)
80+
};
81+
localized_outlives_constraints.push(localized_constraint);
82+
}
83+
}
84+
}
85+
}
86+
87+
/// For a given outlives constraint arising from a MIR statement, localize the constraint with the
88+
/// needed CFG `from`-`to` intra-block nodes.
89+
fn localize_statement_constraint<'tcx>(
90+
tcx: TyCtxt<'tcx>,
91+
body: &Body<'tcx>,
92+
stmt: &Statement<'tcx>,
93+
liveness: &LivenessValues,
94+
outlives_constraint: &OutlivesConstraint<'tcx>,
95+
current_location: Location,
96+
current_point: PointIndex,
97+
universal_regions: &UniversalRegions<'tcx>,
98+
) -> LocalizedOutlivesConstraint {
99+
match &stmt.kind {
100+
StatementKind::Assign(box (lhs, rhs)) => {
101+
// To create localized outlives constraints without midpoints, we rely on the property
102+
// that no input regions from the RHS of the assignment will flow into themselves: they
103+
// should not appear in the output regions in the LHS. We believe this to be true by
104+
// construction of the MIR, via temporaries, and assert it here.
105+
//
106+
// We think we don't need midpoints because:
107+
// - every LHS Place has a unique set of regions that don't appear elsewhere
108+
// - this implies that for them to be part of the RHS, the same Place must be read and
109+
// written
110+
// - and that should be impossible in MIR
111+
//
112+
// When we have a more complete implementation in the future, tested with crater, etc,
113+
// we can relax this to a debug assert instead, or remove it.
114+
assert!(
115+
{
116+
let mut lhs_regions = FxHashSet::default();
117+
tcx.for_each_free_region(lhs, |region| {
118+
let region = universal_regions.to_region_vid(region);
119+
lhs_regions.insert(region);
120+
});
121+
122+
let mut rhs_regions = FxHashSet::default();
123+
tcx.for_each_free_region(rhs, |region| {
124+
let region = universal_regions.to_region_vid(region);
125+
rhs_regions.insert(region);
126+
});
127+
128+
// The intersection between LHS and RHS regions should be empty.
129+
lhs_regions.is_disjoint(&rhs_regions)
130+
},
131+
"there should be no common regions between the LHS and RHS of an assignment"
132+
);
133+
134+
// As mentioned earlier, we should be tracking these better upstream but: we want to
135+
// relate the types on entry to the type of the place on exit. That is, outlives
136+
// constraints on the RHS are on entry, and outlives constraints to/from the LHS are on
137+
// exit (i.e. on entry to the successor location).
138+
let lhs_ty = body.local_decls[lhs.local].ty;
139+
let successor_location = Location {
140+
block: current_location.block,
141+
statement_index: current_location.statement_index + 1,
142+
};
143+
let successor_point = liveness.point_from_location(successor_location);
144+
compute_constraint_direction(
145+
tcx,
146+
outlives_constraint,
147+
&lhs_ty,
148+
current_point,
149+
successor_point,
150+
universal_regions,
151+
)
152+
}
153+
_ => {
154+
// For the other cases, we localize an outlives constraint to where it arises.
155+
LocalizedOutlivesConstraint {
156+
source: outlives_constraint.sup,
157+
from: current_point,
158+
target: outlives_constraint.sub,
159+
to: current_point,
160+
}
161+
}
162+
}
163+
}
164+
165+
/// For a given outlives constraint arising from a MIR terminator, localize the constraint with the
166+
/// needed CFG `from`-`to` inter-block nodes.
167+
fn localize_terminator_constraint<'tcx>(
168+
tcx: TyCtxt<'tcx>,
169+
body: &Body<'tcx>,
170+
terminator: &Terminator<'tcx>,
171+
liveness: &LivenessValues,
172+
outlives_constraint: &OutlivesConstraint<'tcx>,
173+
current_point: PointIndex,
174+
universal_regions: &UniversalRegions<'tcx>,
175+
) -> LocalizedOutlivesConstraint {
176+
// FIXME: check if other terminators need the same handling as `Call`s, in particular
177+
// Assert/Yield/Drop. A handful of tests are failing with Drop related issues, as well as some
178+
// coroutine tests, and that may be why.
179+
match &terminator.kind {
180+
// FIXME: also handle diverging calls.
181+
TerminatorKind::Call { destination, target: Some(target), .. } => {
182+
// Calls are similar to assignments, and thus follow the same pattern. If there is a
183+
// target for the call we also relate what flows into the destination here to entry to
184+
// that successor.
185+
let destination_ty = destination.ty(&body.local_decls, tcx);
186+
let successor_location = Location { block: *target, statement_index: 0 };
187+
let successor_point = liveness.point_from_location(successor_location);
188+
compute_constraint_direction(
189+
tcx,
190+
outlives_constraint,
191+
&destination_ty,
192+
current_point,
193+
successor_point,
194+
universal_regions,
195+
)
196+
}
197+
_ => {
198+
// Typeck constraints guide loans between regions at the current point, so we do that in
199+
// the general case, and liveness will take care of making them flow to the terminator's
200+
// successors.
201+
LocalizedOutlivesConstraint {
202+
source: outlives_constraint.sup,
203+
from: current_point,
204+
target: outlives_constraint.sub,
205+
to: current_point,
206+
}
207+
}
208+
}
209+
}
210+
/// For a given outlives constraint and CFG edge, returns the localized constraint with the
211+
/// appropriate `from`-`to` direction. This is computed according to whether the constraint flows to
212+
/// or from a free region in the given `value`, some kind of result for an effectful operation, like
213+
/// the LHS of an assignment.
214+
fn compute_constraint_direction<'tcx>(
215+
tcx: TyCtxt<'tcx>,
216+
outlives_constraint: &OutlivesConstraint<'tcx>,
217+
value: &impl TypeVisitable<TyCtxt<'tcx>>,
218+
current_point: PointIndex,
219+
successor_point: PointIndex,
220+
universal_regions: &UniversalRegions<'tcx>,
221+
) -> LocalizedOutlivesConstraint {
222+
let mut to = current_point;
223+
let mut from = current_point;
224+
tcx.for_each_free_region(value, |region| {
225+
let region = universal_regions.to_region_vid(region);
226+
if region == outlives_constraint.sub {
227+
// This constraint flows into the result, its effects start becoming visible on exit.
228+
to = successor_point;
229+
} else if region == outlives_constraint.sup {
230+
// This constraint flows from the result, its effects start becoming visible on exit.
231+
from = successor_point;
232+
}
233+
});
234+
235+
LocalizedOutlivesConstraint {
236+
source: outlives_constraint.sup,
237+
from,
238+
target: outlives_constraint.sub,
239+
to,
240+
}
241+
}

‎compiler/rustc_borrowck/src/util/collect_writes.rs

Lines changed: 0 additions & 35 deletions
This file was deleted.

‎compiler/rustc_borrowck/src/util/mod.rs

Lines changed: 0 additions & 3 deletions
This file was deleted.

‎compiler/rustc_middle/src/mir/statement.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ impl BorrowKind {
455455
}
456456
}
457457

458+
/// Returns whether borrows represented by this kind are allowed to be split into separate
459+
/// Reservation and Activation phases.
458460
pub fn allows_two_phase_borrow(&self) -> bool {
459461
match *self {
460462
BorrowKind::Shared

‎compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
1313
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
1414
arch: "aarch64".into(),
1515
options: TargetOptions {
16-
features: "+v8a".into(),
16+
features: "+v8a,+reserve-x18".into(),
1717
max_atomic_width: Some(128),
1818
stack_probes: StackProbeType::Inline,
1919
..base::vxworks::opts()

‎compiler/rustc_target/src/target_features.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ const ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
148148
("neon", Unstable(sym::arm_target_feature), &["vfp3"]),
149149
("rclass", Unstable(sym::arm_target_feature), &[]),
150150
("sha2", Unstable(sym::arm_target_feature), &["neon"]),
151+
// This can be *disabled* on non-`hf` targets to enable the use
152+
// of hardfloats while keeping the softfloat ABI.
153+
// FIXME before stabilization: Should we expose this as a `hard-float` target feature instead of
154+
// matching the odd negative feature LLVM uses?
155+
("soft-float", Unstable(sym::arm_target_feature), &[]),
151156
// This is needed for inline assembly, but shouldn't be stabilized as-is
152157
// since it should be enabled per-function using #[instruction_set], not
153158
// #[target_feature].
@@ -790,6 +795,9 @@ impl Target {
790795
match self.llvm_floatabi.unwrap() {
791796
FloatAbi::Soft => {
792797
// Nothing special required, will use soft-float ABI throughout.
798+
// We can even allow `-soft-float` here; in fact that is useful as it lets
799+
// people use FPU instructions with a softfloat ABI (corresponds to
800+
// `-mfloat-abi=softfp` in GCC/clang).
793801
NOTHING
794802
}
795803
FloatAbi::Hard => {

‎library/std/src/process.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -868,13 +868,17 @@ impl Command {
868868
///
869869
/// # Examples
870870
///
871+
/// Prevent any inherited `GIT_DIR` variable from changing the target of the `git` command,
872+
/// while allowing all other variables, like `GIT_AUTHOR_NAME`.
873+
///
871874
/// ```no_run
872875
/// use std::process::Command;
873876
///
874-
/// Command::new("ls")
875-
/// .env_remove("PATH")
876-
/// .spawn()
877-
/// .expect("ls command failed to start");
877+
/// Command::new("git")
878+
/// .arg("commit")
879+
/// .env_remove("GIT_DIR")
880+
/// .spawn()?;
881+
/// # std::io::Result::Ok(())
878882
/// ```
879883
#[stable(feature = "process", since = "1.0.0")]
880884
pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
@@ -896,13 +900,17 @@ impl Command {
896900
///
897901
/// # Examples
898902
///
903+
/// The behavior of `sort` is affected by `LANG` and `LC_*` environment variables.
904+
/// Clearing the environment makes `sort`'s behavior independent of the parent processes' language.
905+
///
899906
/// ```no_run
900907
/// use std::process::Command;
901908
///
902-
/// Command::new("ls")
909+
/// Command::new("sort")
910+
/// .arg("file.txt")
903911
/// .env_clear()
904-
/// .spawn()
905-
/// .expect("ls command failed to start");
912+
/// .spawn()?;
913+
/// # std::io::Result::Ok(())
906914
/// ```
907915
#[stable(feature = "process", since = "1.0.0")]
908916
pub fn env_clear(&mut self) -> &mut Command {

‎library/std/src/sys/sync/condvar/no_threads.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::sys::sync::Mutex;
2+
use crate::thread::sleep;
23
use crate::time::Duration;
34

45
pub struct Condvar {}
@@ -19,7 +20,8 @@ impl Condvar {
1920
panic!("condvar wait not supported")
2021
}
2122

22-
pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
23-
panic!("condvar wait not supported");
23+
pub unsafe fn wait_timeout(&self, _mutex: &Mutex, dur: Duration) -> bool {
24+
sleep(dur);
25+
false
2426
}
2527
}

‎tests/ui/check-cfg/target_feature.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE");
202202
`sme-lutv2`
203203
`sme2`
204204
`sme2p1`
205+
`soft-float`
205206
`spe`
206207
`ssbs`
207208
`sse`
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
#[repr(simd)] //~ error: SIMD types are experimental
1+
#[repr(simd)] //~ ERROR: SIMD types are experimental
22
struct Foo([u64; 2]);
33

44
#[repr(C)] //~ ERROR conflicting representation hints
55
//~^ WARN this was previously accepted
6-
#[repr(simd)] //~ error: SIMD types are experimental
6+
#[repr(simd)] //~ ERROR: SIMD types are experimental
77
struct Bar([u64; 2]);
88

9+
#[repr(simd)] //~ ERROR: SIMD types are experimental
10+
//~^ ERROR: attribute should be applied to a struct
11+
union U {f: u32}
12+
13+
#[repr(simd)] //~ ERROR: SIMD types are experimental
14+
//~^ error: attribute should be applied to a struct
15+
enum E { X }
16+
917
fn main() {}

‎tests/ui/feature-gates/feature-gate-repr-simd.stderr

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,26 @@ LL | #[repr(simd)]
1818
= help: add `#![feature(repr_simd)]` to the crate attributes to enable
1919
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2020

21+
error[E0658]: SIMD types are experimental and possibly buggy
22+
--> $DIR/feature-gate-repr-simd.rs:9:1
23+
|
24+
LL | #[repr(simd)]
25+
| ^^^^^^^^^^^^^
26+
|
27+
= note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
28+
= help: add `#![feature(repr_simd)]` to the crate attributes to enable
29+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
30+
31+
error[E0658]: SIMD types are experimental and possibly buggy
32+
--> $DIR/feature-gate-repr-simd.rs:13:1
33+
|
34+
LL | #[repr(simd)]
35+
| ^^^^^^^^^^^^^
36+
|
37+
= note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
38+
= help: add `#![feature(repr_simd)]` to the crate attributes to enable
39+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
40+
2141
error[E0566]: conflicting representation hints
2242
--> $DIR/feature-gate-repr-simd.rs:4:8
2343
|
@@ -31,10 +51,28 @@ LL | #[repr(simd)]
3151
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
3252
= note: `#[deny(conflicting_repr_hints)]` on by default
3353

34-
error: aborting due to 3 previous errors
54+
error[E0517]: attribute should be applied to a struct
55+
--> $DIR/feature-gate-repr-simd.rs:9:8
56+
|
57+
LL | #[repr(simd)]
58+
| ^^^^
59+
LL |
60+
LL | union U {f: u32}
61+
| ---------------- not a struct
62+
63+
error[E0517]: attribute should be applied to a struct
64+
--> $DIR/feature-gate-repr-simd.rs:13:8
65+
|
66+
LL | #[repr(simd)]
67+
| ^^^^
68+
LL |
69+
LL | enum E { X }
70+
| ------------ not a struct
71+
72+
error: aborting due to 7 previous errors
3573

36-
Some errors have detailed explanations: E0566, E0658.
37-
For more information about an error, try `rustc --explain E0566`.
74+
Some errors have detailed explanations: E0517, E0566, E0658.
75+
For more information about an error, try `rustc --explain E0517`.
3876
Future incompatibility report: Future breakage diagnostic:
3977
error[E0566]: conflicting representation hints
4078
--> $DIR/feature-gate-repr-simd.rs:4:8

‎tests/ui/repr/issue-83505-repr-simd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#[repr(simd)]
66
//~^ ERROR: attribute should be applied to a struct [E0517]
77
//~| ERROR: unsupported representation for zero-variant enum [E0084]
8+
//~| ERROR: SIMD types are experimental and possibly buggy [E0658]
9+
810
enum Es {}
911
static CLs: Es;
1012
//~^ ERROR: free static item without body

‎tests/ui/repr/issue-83505-repr-simd.stderr

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
error: free static item without body
2-
--> $DIR/issue-83505-repr-simd.rs:9:1
2+
--> $DIR/issue-83505-repr-simd.rs:11:1
33
|
44
LL | static CLs: Es;
55
| ^^^^^^^^^^^^^^-
66
| |
77
| help: provide a definition for the static: `= <expr>;`
88

9+
error[E0658]: SIMD types are experimental and possibly buggy
10+
--> $DIR/issue-83505-repr-simd.rs:5:1
11+
|
12+
LL | #[repr(simd)]
13+
| ^^^^^^^^^^^^^
14+
|
15+
= note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
16+
= help: add `#![feature(repr_simd)]` to the crate attributes to enable
17+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
18+
919
error[E0517]: attribute should be applied to a struct
1020
--> $DIR/issue-83505-repr-simd.rs:5:8
1121
|
@@ -24,7 +34,7 @@ LL | #[repr(simd)]
2434
LL | enum Es {}
2535
| ------- zero-variant enum
2636

27-
error: aborting due to 3 previous errors
37+
error: aborting due to 4 previous errors
2838

29-
Some errors have detailed explanations: E0084, E0517.
39+
Some errors have detailed explanations: E0084, E0517, E0658.
3040
For more information about an error, try `rustc --explain E0084`.

‎triagebot.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,12 @@ issues).
172172
"""
173173
label = "O-emscripten"
174174

175+
[ping.relnotes-interest-group]
176+
message = """\
177+
Hi relnotes-interest-group, this PR adds release notes. Could you review this PR
178+
if you have time? Thanks <3
179+
"""
180+
175181
[prioritize]
176182
label = "I-prioritize"
177183

0 commit comments

Comments
 (0)
This repository has been archived.