Skip to content

Commit

Permalink
Auto merge of #2946 - RalfJung:rustup, r=RalfJung
Browse files Browse the repository at this point in the history
Rustup
  • Loading branch information
bors committed Jun 29, 2023
2 parents cec5ec4 + cca0c81 commit feed376
Show file tree
Hide file tree
Showing 54 changed files with 434 additions and 420 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2580,9 +2580,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"

[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
94 changes: 43 additions & 51 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,9 @@ pub struct Borrows<'a, 'tcx> {
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
}

struct StackEntry {
bb: mir::BasicBlock,
lo: usize,
hi: usize,
}

struct OutOfScopePrecomputer<'a, 'tcx> {
visited: BitSet<mir::BasicBlock>,
visit_stack: Vec<StackEntry>,
visit_stack: Vec<mir::BasicBlock>,
body: &'a Body<'tcx>,
regioncx: &'a RegionInferenceContext<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
Expand All @@ -158,68 +152,66 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
borrow_region: RegionVid,
first_location: Location,
) {
// We visit one BB at a time. The complication is that we may start in the
// middle of the first BB visited (the one containing `first_location`), in which
// case we may have to later on process the first part of that BB if there
// is a path back to its start.

// For visited BBs, we record the index of the first statement processed.
// (In fully processed BBs this index is 0.) Note also that we add BBs to
// `visited` once they are added to `stack`, before they are actually
// processed, because this avoids the need to look them up again on
// completion.
self.visited.insert(first_location.block);

let first_block = first_location.block;
let mut first_lo = first_location.statement_index;
let first_hi = self.body[first_block].statements.len();
let first_bb_data = &self.body.basic_blocks[first_block];

// This is the first block, we only want to visit it from the creation of the borrow at
// `first_location`.
let first_lo = first_location.statement_index;
let first_hi = first_bb_data.statements.len();

if let Some(kill_stmt) = self.regioncx.first_non_contained_inclusive(
borrow_region,
first_block,
first_lo,
first_hi,
) {
let kill_location = Location { block: first_block, statement_index: kill_stmt };
// If region does not contain a point at the location, then add to list and skip
// successor locations.
debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location);
self.borrows_out_of_scope_at_location
.entry(kill_location)
.or_default()
.push(borrow_index);

// The borrow is already dead, there is no need to visit other blocks.
return;
}

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

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

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

// Add successor BBs to the work list, if necessary.
let bb_data = &self.body[bb];
debug_assert!(hi == bb_data.statements.len());
for succ_bb in bb_data.terminator().successors() {
if !self.visited.insert(succ_bb) {
if succ_bb == first_block && first_lo > 0 {
// `succ_bb` has been seen before. If it wasn't
// fully processed, add its first part to `stack`
// for processing.
self.visit_stack.push(StackEntry { bb: succ_bb, lo: 0, hi: first_lo - 1 });

// And update this entry with 0, to represent the
// whole BB being processed.
first_lo = 0;
}
} else {
// succ_bb hasn't been seen before. Add it to
// `stack` for processing.
self.visit_stack.push(StackEntry {
bb: succ_bb,
lo: 0,
hi: self.body[succ_bb].statements.len(),
});
if self.visited.insert(succ_bb) {
self.visit_stack.push(succ_bb);
}
}
}
Expand Down
23 changes: 11 additions & 12 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::base::ExtCtxt;
use pm::bridge::{
server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
};
use pm::{Delimiter, Level, LineColumn};
use pm::{Delimiter, Level};
use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
Expand Down Expand Up @@ -648,23 +648,22 @@ impl server::Span for Rustc<'_, '_> {

Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
}

fn start(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
LineColumn { line: loc.line, column: loc.col.to_usize() }
fn start(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo()
}

fn end(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.hi());
LineColumn { line: loc.line, column: loc.col.to_usize() }
fn end(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_hi()
}

fn before(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo()
fn line(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.line
}

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

fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
Expand Down
62 changes: 27 additions & 35 deletions compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ use rustc_span::symbol::Ident;
use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits;

use crate::astconv::{AstConv, ConvertedBinding, ConvertedBindingKind};
use crate::astconv::{
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
};
use crate::bounds::Bounds;
use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified};

use super::OnlySelfBounds;

impl<'tcx> dyn AstConv<'tcx> + '_ {
/// Sets `implicitly_sized` to true on `Bounds` if necessary
pub(crate) fn add_implicitly_sized(
Expand Down Expand Up @@ -176,47 +176,39 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
&self,
param_ty: Ty<'tcx>,
ast_bounds: &[hir::GenericBound<'_>],
only_self_bounds: OnlySelfBounds,
filter: PredicateFilter,
) -> Bounds<'tcx> {
let mut bounds = Bounds::default();
self.add_bounds(
param_ty,
ast_bounds.iter(),
&mut bounds,
ty::List::empty(),
only_self_bounds,
);
debug!(?bounds);

bounds
}

/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
/// named `assoc_name` into ty::Bounds. Ignore the rest.
pub(crate) fn compute_bounds_that_match_assoc_item(
&self,
param_ty: Ty<'tcx>,
ast_bounds: &[hir::GenericBound<'_>],
assoc_name: Ident,
) -> Bounds<'tcx> {
let mut result = Vec::new();

for ast_bound in ast_bounds {
if let Some(trait_ref) = ast_bound.trait_ref()
&& let Some(trait_did) = trait_ref.trait_def_id()
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
{
result.push(ast_bound.clone());
let only_self_bounds = match filter {
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
OnlySelfBounds(false)
}
}
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
};

let mut bounds = Bounds::default();
self.add_bounds(
param_ty,
result.iter(),
ast_bounds.iter().filter(|bound| {
match filter {
PredicateFilter::All
| PredicateFilter::SelfOnly
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
PredicateFilter::SelfThatDefines(assoc_name) => {
if let Some(trait_ref) = bound.trait_ref()
&& let Some(trait_did) = trait_ref.trait_def_id()
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
{
true
} else {
false
}
}
}
}),
&mut bounds,
ty::List::empty(),
OnlySelfBounds(true),
only_self_bounds,
);
debug!(?bounds);

Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ pub struct PathSeg(pub DefId, pub usize);
#[derive(Copy, Clone, Debug)]
pub struct OnlySelfBounds(pub bool);

#[derive(Copy, Clone, Debug)]
pub enum PredicateFilter {
/// All predicates may be implied by the trait.
All,

/// Only traits that reference `Self: ..` are implied by the trait.
SelfOnly,

/// Only traits that reference `Self: ..` and define an associated type
/// with the given ident are implied by the trait.
SelfThatDefines(Ident),

/// Only traits that reference `Self: ..` and their associated type bounds.
/// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
/// and `<Self as Tr>::A: B`.
SelfAndAssociatedTypeBounds,
}

pub trait AstConv<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx>;

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::ItemCtxt;
use crate::astconv::{AstConv, OnlySelfBounds};
use crate::astconv::{AstConv, PredicateFilter};
use rustc_hir as hir;
use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts;
Expand All @@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>(
);

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

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

0 comments on commit feed376

Please sign in to comment.