Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #65027

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7b480cd
Implement Clone::clone_from for LinkedList
crgl Oct 1, 2019
73b50d2
Add support for 'extern const fn'
Aaron1011 Sep 29, 2019
84b680f
Add missing 'bump'
Aaron1011 Oct 2, 2019
2537a8a
syntax: improve parameter without type suggestions
davidtwco Oct 1, 2019
fb80e6c
BacktraceStatus: add Eq impl
mathstuf Oct 2, 2019
03455e4
Filter out RLS output directories on tidy runs
spastorino Oct 2, 2019
5055d4b
Use zipped iterators in clone_from for LinkedList
crgl Oct 2, 2019
df203a2
Compare primary with value instead of dropping it
AnthonyMikh Oct 2, 2019
864e6fe
Add test for LinkedList clone_from
crgl Oct 2, 2019
08a60ac
Calculate liveness for the same locals with and without -Zpolonius
matthewjasper Sep 21, 2019
2180c24
Make lifetimes in constants live at the point of use
matthewjasper Sep 24, 2019
a4744d6
Rollup merge of #64749 - matthewjasper:liveness-opt, r=nikomatsakis
Manishearth Oct 2, 2019
5d0db38
Rollup merge of #64906 - Aaron1011:feature/extern-const-fn, r=Centril
Manishearth Oct 2, 2019
0ec37c4
Rollup merge of #64959 - davidtwco:issue-64252-self-type-help, r=Cent…
Manishearth Oct 2, 2019
cd104d3
Rollup merge of #64975 - crgl:clone-from-linked-list, r=bluss
Manishearth Oct 2, 2019
d2c92d0
Rollup merge of #64993 - mathstuf:backtrace-status-eq, r=withoutboats
Manishearth Oct 2, 2019
2cb64f2
Rollup merge of #64998 - spastorino:filter-rls-on-tidy, r=petrochenkov
Manishearth Oct 2, 2019
bd2b3e7
Rollup merge of #65010 - AnthonyMikh:fix_65001, r=estebank
Manishearth Oct 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/liballoc/collections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,19 @@ impl<T: Clone> Clone for LinkedList<T> {
fn clone(&self) -> Self {
self.iter().cloned().collect()
}

fn clone_from(&mut self, other: &Self) {
let mut iter_other = other.iter();
if self.len() > other.len() {
self.split_off(other.len());
}
for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) {
elem.clone_from(elem_other);
}
if !iter_other.is_empty() {
self.extend(iter_other.cloned());
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
43 changes: 43 additions & 0 deletions src/liballoc/collections/linked_list/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,49 @@ fn test_append() {
check_links(&n);
}

#[test]
fn test_clone_from() {
// Short cloned from long
{
let v = vec![1, 2, 3, 4, 5];
let u = vec![8, 7, 6, 2, 3, 4, 5];
let mut m = list_from(&v);
let n = list_from(&u);
m.clone_from(&n);
check_links(&m);
assert_eq!(m, n);
for elt in u {
assert_eq!(m.pop_front(), Some(elt))
}
}
// Long cloned from short
{
let v = vec![1, 2, 3, 4, 5];
let u = vec![6, 7, 8];
let mut m = list_from(&v);
let n = list_from(&u);
m.clone_from(&n);
check_links(&m);
assert_eq!(m, n);
for elt in u {
assert_eq!(m.pop_front(), Some(elt))
}
}
// Two equal length lists
{
let v = vec![1, 2, 3, 4, 5];
let u = vec![9, 8, 1, 2, 3];
let mut m = list_from(&v);
let n = list_from(&u);
m.clone_from(&n);
check_links(&m);
assert_eq!(m, n);
for elt in u {
assert_eq!(m.pop_front(), Some(elt))
}
}
}

#[test]
fn test_insert_prev() {
let mut m = list_from(&[0, 2, 4, 6, 8]);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,8 @@ impl EmitterWriter {
children.iter()
.map(|sub| self.get_multispan_max_line_num(&sub.span))
.max()
.unwrap_or(primary)
.unwrap_or(0)
.max(primary)
}

/// Adds a left margin to every line but the first, given a padding length and the label being
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ impl LocalUseMap {
appearances: IndexVec::new(),
};

if live_locals.is_empty() {
return local_use_map;
}

let mut locals_with_use_data: IndexVec<Local, bool> =
IndexVec::from_elem_n(false, body.local_decls.len());
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
Expand Down
52 changes: 30 additions & 22 deletions src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,39 @@ pub(super) fn generate<'tcx>(
) {
debug!("liveness::generate");

let live_locals: Vec<Local> = if AllFacts::enabled(typeck.tcx()) {
// If "dump facts from NLL analysis" was requested perform
// the liveness analysis for all `Local`s. This case opens
// the possibility of the variables being analyzed in `trace`
// to be *any* `Local`, not just the "live" ones, so we can't
// make any assumptions past this point as to the characteristics
// of the `live_locals`.
// FIXME: Review "live" terminology past this point, we should
// not be naming the `Local`s as live.
body.local_decls.indices().collect()
let free_regions = regions_that_outlive_free_regions(
typeck.infcx.num_region_vars(),
&typeck.borrowck_context.universal_regions,
&typeck.borrowck_context.constraints.outlives_constraints,
);
let live_locals = compute_live_locals(typeck.tcx(), &free_regions, body);
let facts_enabled = AllFacts::enabled(typeck.tcx());


let polonius_drop_used = if facts_enabled {
let mut drop_used = Vec::new();
polonius::populate_access_facts(
typeck,
body,
location_table,
move_data,
&mut drop_used,
);
Some(drop_used)
} else {
let free_regions = {
regions_that_outlive_free_regions(
typeck.infcx.num_region_vars(),
&typeck.borrowck_context.universal_regions,
&typeck.borrowck_context.constraints.outlives_constraints,
)
};
compute_live_locals(typeck.tcx(), &free_regions, body)
None
};

if !live_locals.is_empty() {
trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);

polonius::populate_access_facts(typeck, body, location_table, move_data);
if !live_locals.is_empty() || facts_enabled {
trace::trace(
typeck,
body,
elements,
flow_inits,
move_data,
live_locals,
polonius_drop_used,
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct UseFactsExtractor<'me> {
var_defined: &'me mut VarPointRelations,
var_used: &'me mut VarPointRelations,
location_table: &'me LocationTable,
var_drop_used: &'me mut VarPointRelations,
var_drop_used: &'me mut Vec<(Local, Location)>,
move_data: &'me MoveData<'me>,
path_accessed_at: &'me mut MovePathPointRelations,
}
Expand All @@ -39,7 +39,7 @@ impl UseFactsExtractor<'_> {

fn insert_drop_use(&mut self, local: Local, location: Location) {
debug!("LivenessFactsExtractor::insert_drop_use()");
self.var_drop_used.push((local, self.location_to_index(location)));
self.var_drop_used.push((local, location));
}

fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
Expand Down Expand Up @@ -100,19 +100,24 @@ pub(super) fn populate_access_facts(
body: &Body<'tcx>,
location_table: &LocationTable,
move_data: &MoveData<'_>,
drop_used: &mut Vec<(Local, Location)>,
) {
debug!("populate_var_liveness_facts()");

if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
UseFactsExtractor {
var_defined: &mut facts.var_defined,
var_used: &mut facts.var_used,
var_drop_used: &mut facts.var_drop_used,
var_drop_used: drop_used,
path_accessed_at: &mut facts.path_accessed_at,
location_table,
move_data,
}
.visit_body(body);

facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| {
(local, location_table.mid_index(location))
}));
}

for (local, local_decl) in body.local_decls.iter_enumerated() {
Expand Down
37 changes: 35 additions & 2 deletions src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc::traits::query::type_op::outlives::DropckOutlives;
use rustc::traits::query::type_op::TypeOp;
use rustc::ty::{Ty, TypeFoldable};
use rustc_index::bit_set::HybridBitSet;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::rc::Rc;

/// This is the heart of the liveness computation. For each variable X
Expand All @@ -37,6 +37,7 @@ pub(super) fn trace(
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
move_data: &MoveData<'tcx>,
live_locals: Vec<Local>,
polonius_drop_used: Option<Vec<(Local, Location)>>,
) {
debug!("trace()");

Expand All @@ -52,7 +53,13 @@ pub(super) fn trace(
drop_data: FxHashMap::default(),
};

LivenessResults::new(cx).compute_for_all_locals(live_locals);
let mut results = LivenessResults::new(cx);

if let Some(drop_used) = polonius_drop_used {
results.add_extra_drop_facts(drop_used, live_locals.iter().copied().collect())
}

results.compute_for_all_locals(live_locals);
}

/// Contextual state for the type-liveness generator.
Expand Down Expand Up @@ -145,6 +152,32 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
}
}

/// Add extra drop facts needed for Polonius.
///
/// Add facts for all locals with free regions, since regions may outlive
/// the function body only at certain nodes in the CFG.
fn add_extra_drop_facts(
&mut self,
drop_used: Vec<(Local, Location)>,
live_locals: FxHashSet<Local>,
) {
let locations = HybridBitSet::new_empty(self.cx.elements.num_points());

for (local, location) in drop_used {
if !live_locals.contains(&local) {
let local_ty = self.cx.body.local_decls[local].ty;
if local_ty.has_free_regions() {
self.cx.add_drop_live_facts_for(
local,
local_ty,
&[location],
&locations,
);
}
}
}
}

/// Clear the value of fields that are "per local variable".
fn reset_local_state(&mut self) {
self.defs.clear();
Expand Down
64 changes: 41 additions & 23 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,17 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {

fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
self.sanitize_type(constant, constant.literal.ty);
let ty = self.sanitize_type(constant, constant.literal.ty);

self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
let live_region_vid =
self.cx.borrowck_context.universal_regions.to_region_vid(live_region);
self.cx
.borrowck_context
.constraints
.liveness_constraints
.add_element(live_region_vid, location);
});

if let Some(annotation_index) = constant.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
Expand Down Expand Up @@ -528,56 +538,64 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {

let parent_body = mem::replace(&mut self.body, promoted_body);

// Use new sets of constraints and closure bounds so that we can
// modify their locations.
let all_facts = &mut None;
let mut constraints = Default::default();
let mut closure_bounds = Default::default();
let mut liveness_constraints = LivenessValues::new(
Rc::new(RegionValueElements::new(promoted_body)),
);
// Don't try to add borrow_region facts for the promoted MIR
mem::swap(self.cx.borrowck_context.all_facts, all_facts);

// Use a new sets of constraints and closure bounds so that we can
// modify their locations.
mem::swap(
&mut self.cx.borrowck_context.constraints.outlives_constraints,
&mut constraints
);
mem::swap(
&mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
&mut closure_bounds
);
let mut swap_constraints = |this: &mut Self| {
mem::swap(this.cx.borrowck_context.all_facts, all_facts);
mem::swap(
&mut this.cx.borrowck_context.constraints.outlives_constraints,
&mut constraints
);
mem::swap(
&mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
&mut closure_bounds
);
mem::swap(
&mut this.cx.borrowck_context.constraints.liveness_constraints,
&mut liveness_constraints
);
};

swap_constraints(self);

self.visit_body(promoted_body);


if !self.errors_reported {
// if verifier failed, don't do further checks to avoid ICEs
self.cx.typeck_mir(promoted_body);
}

self.body = parent_body;
// Merge the outlives constraints back in, at the given location.
mem::swap(self.cx.borrowck_context.all_facts, all_facts);
mem::swap(
&mut self.cx.borrowck_context.constraints.outlives_constraints,
&mut constraints
);
mem::swap(
&mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
&mut closure_bounds
);
swap_constraints(self);

let locations = location.to_locations();
for constraint in constraints.outlives().iter() {
let mut constraint = *constraint;
constraint.locations = locations;
if let ConstraintCategory::Return
| ConstraintCategory::UseAsConst
| ConstraintCategory::UseAsStatic = constraint.category
| ConstraintCategory::UseAsConst
| ConstraintCategory::UseAsStatic = constraint.category
{
// "Returning" from a promoted is an assigment to a
// temporary from the user's point of view.
constraint.category = ConstraintCategory::Boring;
}
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
}
for live_region in liveness_constraints.rows() {
self.cx.borrowck_context.constraints.liveness_constraints
.add_element(live_region, location);
}

if !closure_bounds.is_empty() {
let combined_bounds_mapping = closure_bounds
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub struct Backtrace {
/// The current status of a backtrace, indicating whether it was captured or
/// whether it is empty for some other reason.
#[non_exhaustive]
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
pub enum BacktraceStatus {
/// Capturing a backtrace is not supported, likely because it's not
/// implemented for the current platform.
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/feature_gate/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@ declare_features! (
/// Allows the use of or-patterns (e.g., `0 | 1`).
(active, or_patterns, "1.38.0", Some(54883), None),

/// Allows the definition of `const extern fn` and `const unsafe extern fn`.
(active, const_extern_fn, "1.40.0", Some(64926), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/feature_gate/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ pub fn check_crate(krate: &ast::Crate,
gate_all!(async_closure, "async closures are unstable");
gate_all!(yields, generators, "yield syntax is experimental");
gate_all!(or_patterns, "or-patterns syntax is experimental");
gate_all!(const_extern_fn, "`const extern fn` definitions are unstable");

visit::walk_crate(&mut visitor, krate);
}
Expand Down
Loading