Skip to content

Commit feed376

Browse files
committed
Auto merge of rust-lang#2946 - RalfJung:rustup, r=RalfJung
Rustup
2 parents cec5ec4 + cca0c81 commit feed376

File tree

54 files changed

+434
-420
lines changed

Some content is hidden

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

54 files changed

+434
-420
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -2580,9 +2580,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
25802580

25812581
[[package]]
25822582
name = "proc-macro2"
2583-
version = "1.0.56"
2583+
version = "1.0.60"
25842584
source = "registry+https://github.com/rust-lang/crates.io-index"
2585-
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
2585+
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
25862586
dependencies = [
25872587
"unicode-ident",
25882588
]

compiler/rustc_borrowck/src/dataflow.rs

+43-51
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,9 @@ pub struct Borrows<'a, 'tcx> {
125125
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
126126
}
127127

128-
struct StackEntry {
129-
bb: mir::BasicBlock,
130-
lo: usize,
131-
hi: usize,
132-
}
133-
134128
struct OutOfScopePrecomputer<'a, 'tcx> {
135129
visited: BitSet<mir::BasicBlock>,
136-
visit_stack: Vec<StackEntry>,
130+
visit_stack: Vec<mir::BasicBlock>,
137131
body: &'a Body<'tcx>,
138132
regioncx: &'a RegionInferenceContext<'tcx>,
139133
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
@@ -158,68 +152,66 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
158152
borrow_region: RegionVid,
159153
first_location: Location,
160154
) {
161-
// We visit one BB at a time. The complication is that we may start in the
162-
// middle of the first BB visited (the one containing `first_location`), in which
163-
// case we may have to later on process the first part of that BB if there
164-
// is a path back to its start.
165-
166-
// For visited BBs, we record the index of the first statement processed.
167-
// (In fully processed BBs this index is 0.) Note also that we add BBs to
168-
// `visited` once they are added to `stack`, before they are actually
169-
// processed, because this avoids the need to look them up again on
170-
// completion.
171-
self.visited.insert(first_location.block);
172-
173155
let first_block = first_location.block;
174-
let mut first_lo = first_location.statement_index;
175-
let first_hi = self.body[first_block].statements.len();
156+
let first_bb_data = &self.body.basic_blocks[first_block];
157+
158+
// This is the first block, we only want to visit it from the creation of the borrow at
159+
// `first_location`.
160+
let first_lo = first_location.statement_index;
161+
let first_hi = first_bb_data.statements.len();
162+
163+
if let Some(kill_stmt) = self.regioncx.first_non_contained_inclusive(
164+
borrow_region,
165+
first_block,
166+
first_lo,
167+
first_hi,
168+
) {
169+
let kill_location = Location { block: first_block, statement_index: kill_stmt };
170+
// If region does not contain a point at the location, then add to list and skip
171+
// successor locations.
172+
debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location);
173+
self.borrows_out_of_scope_at_location
174+
.entry(kill_location)
175+
.or_default()
176+
.push(borrow_index);
177+
178+
// The borrow is already dead, there is no need to visit other blocks.
179+
return;
180+
}
176181

177-
self.visit_stack.push(StackEntry { bb: first_block, lo: first_lo, hi: first_hi });
182+
// The borrow is not dead. Add successor BBs to the work list, if necessary.
183+
for succ_bb in first_bb_data.terminator().successors() {
184+
if self.visited.insert(succ_bb) {
185+
self.visit_stack.push(succ_bb);
186+
}
187+
}
178188

179-
'preorder: while let Some(StackEntry { bb, lo, hi }) = self.visit_stack.pop() {
189+
// We may end up visiting `first_block` again. This is not an issue: we know at this point
190+
// that it does not kill the borrow in the `first_lo..=first_hi` range, so checking the
191+
// `0..first_lo` range and the `0..first_hi` range give the same result.
192+
while let Some(block) = self.visit_stack.pop() {
193+
let bb_data = &self.body[block];
194+
let num_stmts = bb_data.statements.len();
180195
if let Some(kill_stmt) =
181-
self.regioncx.first_non_contained_inclusive(borrow_region, bb, lo, hi)
196+
self.regioncx.first_non_contained_inclusive(borrow_region, block, 0, num_stmts)
182197
{
183-
let kill_location = Location { block: bb, statement_index: kill_stmt };
198+
let kill_location = Location { block, statement_index: kill_stmt };
184199
// If region does not contain a point at the location, then add to list and skip
185200
// successor locations.
186201
debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location);
187202
self.borrows_out_of_scope_at_location
188203
.entry(kill_location)
189204
.or_default()
190205
.push(borrow_index);
191-
continue 'preorder;
192-
}
193206

194-
// If we process the first part of the first basic block (i.e. we encounter that block
195-
// for the second time), we no longer have to visit its successors again.
196-
if bb == first_block && hi != first_hi {
207+
// We killed the borrow, so we do not visit this block's successors.
197208
continue;
198209
}
199210

200211
// Add successor BBs to the work list, if necessary.
201-
let bb_data = &self.body[bb];
202-
debug_assert!(hi == bb_data.statements.len());
203212
for succ_bb in bb_data.terminator().successors() {
204-
if !self.visited.insert(succ_bb) {
205-
if succ_bb == first_block && first_lo > 0 {
206-
// `succ_bb` has been seen before. If it wasn't
207-
// fully processed, add its first part to `stack`
208-
// for processing.
209-
self.visit_stack.push(StackEntry { bb: succ_bb, lo: 0, hi: first_lo - 1 });
210-
211-
// And update this entry with 0, to represent the
212-
// whole BB being processed.
213-
first_lo = 0;
214-
}
215-
} else {
216-
// succ_bb hasn't been seen before. Add it to
217-
// `stack` for processing.
218-
self.visit_stack.push(StackEntry {
219-
bb: succ_bb,
220-
lo: 0,
221-
hi: self.body[succ_bb].statements.len(),
222-
});
213+
if self.visited.insert(succ_bb) {
214+
self.visit_stack.push(succ_bb);
223215
}
224216
}
225217
}

compiler/rustc_expand/src/proc_macro_server.rs

+11-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::base::ExtCtxt;
22
use pm::bridge::{
33
server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
44
};
5-
use pm::{Delimiter, Level, LineColumn};
5+
use pm::{Delimiter, Level};
66
use rustc_ast as ast;
77
use rustc_ast::token;
88
use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
@@ -648,23 +648,22 @@ impl server::Span for Rustc<'_, '_> {
648648

649649
Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
650650
}
651-
652-
fn start(&mut self, span: Self::Span) -> LineColumn {
653-
let loc = self.sess().source_map().lookup_char_pos(span.lo());
654-
LineColumn { line: loc.line, column: loc.col.to_usize() }
651+
fn start(&mut self, span: Self::Span) -> Self::Span {
652+
span.shrink_to_lo()
655653
}
656654

657-
fn end(&mut self, span: Self::Span) -> LineColumn {
658-
let loc = self.sess().source_map().lookup_char_pos(span.hi());
659-
LineColumn { line: loc.line, column: loc.col.to_usize() }
655+
fn end(&mut self, span: Self::Span) -> Self::Span {
656+
span.shrink_to_hi()
660657
}
661658

662-
fn before(&mut self, span: Self::Span) -> Self::Span {
663-
span.shrink_to_lo()
659+
fn line(&mut self, span: Self::Span) -> usize {
660+
let loc = self.sess().source_map().lookup_char_pos(span.lo());
661+
loc.line
664662
}
665663

666-
fn after(&mut self, span: Self::Span) -> Self::Span {
667-
span.shrink_to_hi()
664+
fn column(&mut self, span: Self::Span) -> usize {
665+
let loc = self.sess().source_map().lookup_char_pos(span.lo());
666+
loc.col.to_usize() + 1
668667
}
669668

670669
fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {

compiler/rustc_hir_analysis/src/astconv/bounds.rs

+27-35
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ use rustc_span::symbol::Ident;
99
use rustc_span::{ErrorGuaranteed, Span};
1010
use rustc_trait_selection::traits;
1111

12-
use crate::astconv::{AstConv, ConvertedBinding, ConvertedBindingKind};
12+
use crate::astconv::{
13+
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
14+
};
1315
use crate::bounds::Bounds;
1416
use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified};
1517

16-
use super::OnlySelfBounds;
17-
1818
impl<'tcx> dyn AstConv<'tcx> + '_ {
1919
/// Sets `implicitly_sized` to true on `Bounds` if necessary
2020
pub(crate) fn add_implicitly_sized(
@@ -176,47 +176,39 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
176176
&self,
177177
param_ty: Ty<'tcx>,
178178
ast_bounds: &[hir::GenericBound<'_>],
179-
only_self_bounds: OnlySelfBounds,
179+
filter: PredicateFilter,
180180
) -> Bounds<'tcx> {
181181
let mut bounds = Bounds::default();
182-
self.add_bounds(
183-
param_ty,
184-
ast_bounds.iter(),
185-
&mut bounds,
186-
ty::List::empty(),
187-
only_self_bounds,
188-
);
189-
debug!(?bounds);
190182

191-
bounds
192-
}
193-
194-
/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
195-
/// named `assoc_name` into ty::Bounds. Ignore the rest.
196-
pub(crate) fn compute_bounds_that_match_assoc_item(
197-
&self,
198-
param_ty: Ty<'tcx>,
199-
ast_bounds: &[hir::GenericBound<'_>],
200-
assoc_name: Ident,
201-
) -> Bounds<'tcx> {
202-
let mut result = Vec::new();
203-
204-
for ast_bound in ast_bounds {
205-
if let Some(trait_ref) = ast_bound.trait_ref()
206-
&& let Some(trait_did) = trait_ref.trait_def_id()
207-
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
208-
{
209-
result.push(ast_bound.clone());
183+
let only_self_bounds = match filter {
184+
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
185+
OnlySelfBounds(false)
210186
}
211-
}
187+
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
188+
};
212189

213-
let mut bounds = Bounds::default();
214190
self.add_bounds(
215191
param_ty,
216-
result.iter(),
192+
ast_bounds.iter().filter(|bound| {
193+
match filter {
194+
PredicateFilter::All
195+
| PredicateFilter::SelfOnly
196+
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
197+
PredicateFilter::SelfThatDefines(assoc_name) => {
198+
if let Some(trait_ref) = bound.trait_ref()
199+
&& let Some(trait_did) = trait_ref.trait_def_id()
200+
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
201+
{
202+
true
203+
} else {
204+
false
205+
}
206+
}
207+
}
208+
}),
217209
&mut bounds,
218210
ty::List::empty(),
219-
OnlySelfBounds(true),
211+
only_self_bounds,
220212
);
221213
debug!(?bounds);
222214

compiler/rustc_hir_analysis/src/astconv/mod.rs

+18
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ pub struct PathSeg(pub DefId, pub usize);
5858
#[derive(Copy, Clone, Debug)]
5959
pub struct OnlySelfBounds(pub bool);
6060

61+
#[derive(Copy, Clone, Debug)]
62+
pub enum PredicateFilter {
63+
/// All predicates may be implied by the trait.
64+
All,
65+
66+
/// Only traits that reference `Self: ..` are implied by the trait.
67+
SelfOnly,
68+
69+
/// Only traits that reference `Self: ..` and define an associated type
70+
/// with the given ident are implied by the trait.
71+
SelfThatDefines(Ident),
72+
73+
/// Only traits that reference `Self: ..` and their associated type bounds.
74+
/// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
75+
/// and `<Self as Tr>::A: B`.
76+
SelfAndAssociatedTypeBounds,
77+
}
78+
6179
pub trait AstConv<'tcx> {
6280
fn tcx(&self) -> TyCtxt<'tcx>;
6381

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::ItemCtxt;
2-
use crate::astconv::{AstConv, OnlySelfBounds};
2+
use crate::astconv::{AstConv, PredicateFilter};
33
use rustc_hir as hir;
44
use rustc_infer::traits::util;
55
use rustc_middle::ty::subst::InternalSubsts;
@@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>(
2626
);
2727

2828
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
29-
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
29+
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
3030
// Associated types are implicitly sized unless a `?Sized` bound is found
3131
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
3232

@@ -68,7 +68,7 @@ fn opaque_type_bounds<'tcx>(
6868
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
6969
ty::print::with_no_queries!({
7070
let icx = ItemCtxt::new(tcx, opaque_def_id);
71-
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
71+
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
7272
// Opaque types are implicitly sized unless a `?Sized` bound is found
7373
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
7474
debug!(?bounds);

0 commit comments

Comments
 (0)