Skip to content

add some run-pass tests for NLL showing that things work as expected #24

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

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3b2f6a5
simplify `AnonTypeDecl` in the impl trait code
nikomatsakis Dec 6, 2017
057f297
region_infer/values.rs: rustfmt
nikomatsakis Dec 6, 2017
4017315
Add tracking of causes for nll
Nashenas88 Nov 21, 2017
f80c7a5
rustfmt: borrow_check/mod.rs
nikomatsakis Dec 14, 2017
5d5aae6
dump out causal information for "free region" errors
nikomatsakis Dec 7, 2017
eebf46e
use Rc to store nonlexical_regioncx in Borrows
nikomatsakis Dec 7, 2017
337b840
integrate -Znll-dump-cause into borrowck
nikomatsakis Dec 7, 2017
87fb030
get the `DefiningTy` from the `body_owner_kind` not type
nikomatsakis Dec 8, 2017
9857582
propagate `region_bound_pairs` into MIR type-check
nikomatsakis Dec 8, 2017
b46c410
extract `instantiate_anon_types` to the `InferCtxt`
nikomatsakis Dec 9, 2017
fb24cd0
extract `constrain_anon_types` to the `InferCtxt`
nikomatsakis Dec 9, 2017
6937c9a
extract the writeback code for anon types into InferCtxt
nikomatsakis Dec 9, 2017
ac0bb0e
pass `UniversalRegions` to MIR type-checker instead of fields
nikomatsakis Dec 10, 2017
3d72efa
extract `input_output` code into its own module
nikomatsakis Dec 10, 2017
a51a1b7
connect NLL type checker to the impl trait code
nikomatsakis Dec 10, 2017
43c0d4c
Move MirVisitable to visit.rs
spastorino Dec 12, 2017
fd2e2b7
Move categorize logic out of visit_local function
spastorino Dec 12, 2017
51628d7
Add three point error handling to borrowck
spastorino Dec 12, 2017
f8f1905
only dump causes if we have nothing better
nikomatsakis Dec 14, 2017
fc89f4c
add some run-pass tests for NLL showing that things work as expected
nikomatsakis Dec 7, 2017
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
598 changes: 598 additions & 0 deletions src/librustc/infer/anon_types/mod.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use self::outlives::env::OutlivesEnvironment;
use self::type_variable::TypeVariableOrigin;
use self::unify_key::ToType;

pub mod anon_types;
pub mod at;
mod combine;
mod equate;
Expand Down
37 changes: 23 additions & 14 deletions src/librustc/infer/outlives/free_region_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,6 @@ impl<'tcx> FreeRegionMap<'tcx> {
}
}

/// Tests whether `r_a <= r_b`. Both must be free regions or
/// `'static`.
pub fn sub_free_regions<'a, 'gcx>(&self,
r_a: Region<'tcx>,
r_b: Region<'tcx>)
-> bool {
assert!(is_free_or_static(r_a) && is_free_or_static(r_b));
if let ty::ReStatic = r_b {
true // `'a <= 'static` is just always true, and not stored in the relation explicitly
} else {
r_a == r_b || self.relation.contains(&r_a, &r_b)
}
}

/// Compute the least-upper-bound of two free regions. In some
/// cases, this is more conservative than necessary, in order to
/// avoid making arbitrary choices. See
Expand All @@ -75,6 +61,29 @@ impl<'tcx> FreeRegionMap<'tcx> {
}
}

/// The NLL region handling code represents free region relations in a
/// slightly different way; this trait allows functions to be abstract
/// over which version is in use.
pub trait FreeRegionRelations<'tcx> {
/// Tests whether `r_a <= r_b`. Both must be free regions or
/// `'static`.
fn sub_free_regions(&self, shorter: ty::Region<'tcx>, longer: ty::Region<'tcx>) -> bool;
}

impl<'tcx> FreeRegionRelations<'tcx> for FreeRegionMap<'tcx> {
fn sub_free_regions(&self,
r_a: Region<'tcx>,
r_b: Region<'tcx>)
-> bool {
assert!(is_free_or_static(r_a) && is_free_or_static(r_b));
if let ty::ReStatic = r_b {
true // `'a <= 'static` is just always true, and not stored in the relation explicitly
} else {
r_a == r_b || self.relation.contains(&r_a, &r_b)
}
}
}

fn is_free(r: Region) -> bool {
match *r {
ty::ReEarlyBound(_) | ty::ReFree(_) => true,
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![feature(dyn_trait)]
#![feature(from_ref)]
#![feature(i128)]
#![feature(i128_type)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/free_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//! `TransitiveRelation` type and use that to decide when one free
//! region outlives another and so forth.

use infer::outlives::free_region_map::FreeRegionMap;
use infer::outlives::free_region_map::{FreeRegionMap, FreeRegionRelations};
use hir::def_id::DefId;
use middle::region;
use ty::{self, TyCtxt, Region};
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rustc_data_structures::control_flow_graph::ControlFlowGraph;
use rustc_serialize as serialize;
use hir::def::CtorKind;
use hir::def_id::DefId;
use mir::visit::MirVisitable;
use ty::subst::{Subst, Substs};
use ty::{self, AdtDef, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
Expand Down Expand Up @@ -867,6 +868,14 @@ impl<'tcx> BasicBlockData<'tcx> {
}
}
}

pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> {
if index < self.statements.len() {
&self.statements[index]
} else {
&self.terminator
}
}
}

impl<'tcx> Debug for TerminatorKind<'tcx> {
Expand Down
25 changes: 25 additions & 0 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,31 @@ macro_rules! make_mir_visitor {
make_mir_visitor!(Visitor,);
make_mir_visitor!(MutVisitor,mut);

pub trait MirVisitable<'tcx> {
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>);
}

impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> {
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
{
visitor.visit_statement(location.block, self, location)
}
}

impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> {
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
{
visitor.visit_terminator(location.block, self, location)
}
}

impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> {
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>)
{
visitor.visit_terminator(location.block, self.as_ref().unwrap(), location)
}
}

/// Extra information passed to `visit_ty` and friends to give context
/// about where the type etc appears.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"choose which RELRO level to use"),
nll: bool = (false, parse_bool, [UNTRACKED],
"run the non-lexical lifetimes MIR pass"),
nll_dump_cause: bool = (false, parse_bool, [UNTRACKED],
"dump cause information when reporting errors from NLL"),
trans_time_graph: bool = (false, parse_bool, [UNTRACKED],
"generate a graphical HTML report of time spent in trans and LLVM"),
thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
Expand Down
18 changes: 11 additions & 7 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,13 +865,17 @@ impl fmt::Debug for ty::RegionVid {
define_print! {
() ty::InferTy, (self, f, cx) {
display {
match *self {
ty::TyVar(_) => write!(f, "_"),
ty::IntVar(_) => write!(f, "{}", "{integer}"),
ty::FloatVar(_) => write!(f, "{}", "{float}"),
ty::FreshTy(v) => write!(f, "FreshTy({})", v),
ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
if cx.is_verbose {
print!(f, cx, print_debug(self))
} else {
match *self {
ty::TyVar(_) => write!(f, "_"),
ty::IntVar(_) => write!(f, "{}", "{integer}"),
ty::FloatVar(_) => write!(f, "{}", "{float}"),
ty::FreshTy(v) => write!(f, "FreshTy({})", v),
ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
}
}
}
debug {
Expand Down
Loading