Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f3335c6
simplify `AnonTypeDecl` in the impl trait code
nikomatsakis Dec 6, 2017
f6741d0
region_infer/values.rs: rustfmt
nikomatsakis Dec 6, 2017
e447b54
Add tracking of causes for nll
Nashenas88 Nov 21, 2017
39b0e49
rustfmt: borrow_check/mod.rs
nikomatsakis Dec 14, 2017
594c386
dump out causal information for "free region" errors
nikomatsakis Dec 7, 2017
741ef41
use Rc to store nonlexical_regioncx in Borrows
nikomatsakis Dec 7, 2017
0e64a75
integrate -Znll-dump-cause into borrowck
nikomatsakis Dec 7, 2017
fe89f4b
get the `DefiningTy` from the `body_owner_kind` not type
nikomatsakis Dec 8, 2017
4a967c9
propagate `region_bound_pairs` into MIR type-check
nikomatsakis Dec 8, 2017
e96f4be
extract `instantiate_anon_types` to the `InferCtxt`
nikomatsakis Dec 9, 2017
8e64ba8
extract `constrain_anon_types` to the `InferCtxt`
nikomatsakis Dec 9, 2017
7f50e7c
extract the writeback code for anon types into InferCtxt
nikomatsakis Dec 9, 2017
a66c651
pass `UniversalRegions` to MIR type-checker instead of fields
nikomatsakis Dec 10, 2017
da63aaa
extract `input_output` code into its own module
nikomatsakis Dec 10, 2017
93afb1a
connect NLL type checker to the impl trait code
nikomatsakis Dec 10, 2017
58b0506
Move MirVisitable to visit.rs
spastorino Dec 12, 2017
6d2987c
Move categorize logic out of visit_local function
nikomatsakis Dec 20, 2017
3a185a5
Add three point error handling to borrowck
spastorino Dec 12, 2017
e28d03f
only dump causes if we have nothing better
nikomatsakis Dec 14, 2017
4089d14
move nice-region-error reporting into its own module
nikomatsakis Dec 12, 2017
93498e0
make `util` fns private to nice_region_error
nikomatsakis Dec 12, 2017
3720242
extract `find_anon_type` into its own module
nikomatsakis Dec 12, 2017
a28ab84
nice_region_error: rustfmt
nikomatsakis Dec 12, 2017
cba4732
introduce a `NiceRegionError` type and define methods on that
nikomatsakis Dec 12, 2017
de56308
use `Option<ErrorReported>` instead of `bool`
nikomatsakis Dec 12, 2017
94e7072
give precedence to `try_report_named_anon_conflict` method
nikomatsakis Dec 12, 2017
6b39781
connect NLL machinery to the `NiceRegionError` code
nikomatsakis Dec 12, 2017
3788f42
refactor `report_generic_bound_failure` to be usable by NLL code
nikomatsakis Dec 19, 2017
508a831
use `report_generic_bound_failure` when we can in the compiler
nikomatsakis Dec 19, 2017
95b6148
Add nll_dump_cause helper to Session
spastorino Dec 19, 2017
0b2db1e
Add nll feature and make nll imply nll_dump_cause
spastorino Dec 19, 2017
2019d69
feature nll implies two-phase-borrows
spastorino Dec 19, 2017
e980fb8
feature nll implies borrowck=mir
spastorino Dec 19, 2017
cfa4ffa
document and tweak the nll, use_mir, etc helpers
nikomatsakis Dec 20, 2017
80c510e
when using feature(nll), don't warn about AST-based region errors
nikomatsakis Dec 20, 2017
cba8256
add some run-pass tests for NLL showing that things work as expected
nikomatsakis Dec 7, 2017
3f490ca
convert region-liveness-drop{-,-no-}may-dangle.rs into ui tests
nikomatsakis Dec 20, 2017
4f549fe
improve comment about instantiating anon types
nikomatsakis Dec 20, 2017
d925f4d
fix truncated comment
nikomatsakis Dec 20, 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
Prev Previous commit
Next Next commit
use report_generic_bound_failure when we can in the compiler
  • Loading branch information
nikomatsakis committed Dec 20, 2017
commit 508a831dcabcd12998185c6ac1fc53138368c618
114 changes: 87 additions & 27 deletions src/librustc_mir/borrow_check/nll/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
None
};

self.check_type_tests(infcx, mir, outlives_requirements.as_mut());
self.check_type_tests(infcx, mir, mir_def_id, outlives_requirements.as_mut());

self.check_universal_regions(infcx, mir, mir_def_id, outlives_requirements.as_mut());

Expand Down Expand Up @@ -504,6 +504,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
&self,
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
mir_def_id: DefId,
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'gcx>>>,
) {
let tcx = infcx.tcx;
Expand All @@ -522,14 +523,56 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}

// Oh the humanity. Obviously we will do better than this error eventually.
tcx.sess.span_err(
type_test.span,
&format!(
"`{}` does not outlive `{:?}`",
let lower_bound_region = self.to_error_region(type_test.lower_bound);
if let Some(lower_bound_region) = lower_bound_region {
let region_scope_tree = &tcx.region_scope_tree(mir_def_id);
infcx.report_generic_bound_failure(
region_scope_tree,
type_test.span,
None,
type_test.generic_kind,
type_test.lower_bound,
),
);
lower_bound_region,
);
} else {
// FIXME. We should handle this case better. It
// indicates that we have e.g. some region variable
// whose value is like `'a+'b` where `'a` and `'b` are
// distinct unrelated univesal regions that are not
// known to outlive one another. It'd be nice to have
// some examples where this arises to decide how best
// to report it; we could probably handle it by
// iterating over the universal regions and reporting
// an error that multiple bounds are required.
tcx.sess.span_err(
type_test.span,
&format!(
"`{}` does not live long enough",
type_test.generic_kind,
),
);
}
}
}

/// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound,
/// then we use the name that we have on record for it. If `r` is
/// existentially bound, then we check its inferred value and try
/// to find a good name from that. Returns `None` if we can't find
/// one (e.g., this is just some random part of the CFG).
fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
if self.universal_regions.is_universal_region(r) {
return self.definitions[r].external_name;
} else {
let inferred_values = self.inferred_values
.as_ref()
.expect("region values not yet inferred");
let upper_bound = self.universal_upper_bound(r);
if inferred_values.contains(r, upper_bound) {
self.to_error_region(upper_bound)
} else {
None
}
}
}

Expand Down Expand Up @@ -663,6 +706,36 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// encoding `T` as part of `try_promote_type_test_subject` (see
/// that fn for details).
///
/// This is based on the result `'y` of `universal_upper_bound`,
/// except that it converts further takes the non-local upper
/// bound of `'y`, so that the final result is non-local.
fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
let inferred_values = self.inferred_values.as_ref().unwrap();

debug!(
"non_local_universal_upper_bound(r={:?}={})",
r,
inferred_values.region_value_str(r)
);

let lub = self.universal_upper_bound(r);

// Grow further to get smallest universal region known to
// creator.
let non_local_lub = self.universal_regions.non_local_upper_bound(lub);

debug!(
"non_local_universal_upper_bound: non_local_lub={:?}",
non_local_lub
);

non_local_lub
}

/// Returns a universally quantified region that outlives the
/// value of `r` (`r` may be existentially or universally
/// quantified).
///
/// Since `r` is (potentially) an existential region, it has some
/// value which may include (a) any number of points in the CFG
/// and (b) any number of `end('x)` elements of universally
Expand All @@ -673,15 +746,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// include the CFG anyhow.
/// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
/// a result `'y`.
/// - Finally, we take the non-local upper bound of `'y`.
/// - This uses `UniversalRegions::non_local_upper_bound`, which
/// is similar to this method but only works on universal
/// regions).
fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
let inferred_values = self.inferred_values.as_ref().unwrap();

debug!(
"non_local_universal_upper_bound(r={:?}={})",
"universal_upper_bound(r={:?}={})",
r,
inferred_values.region_value_str(r)
);
Expand All @@ -693,18 +762,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
lub = self.universal_regions.postdom_upper_bound(lub, ur);
}

debug!("non_local_universal_upper_bound: lub={:?}", lub);

// Grow further to get smallest universal region known to
// creator.
let non_local_lub = self.universal_regions.non_local_upper_bound(lub);
debug!("universal_upper_bound: r={:?} lub={:?}", r, lub);

debug!(
"non_local_universal_upper_bound: non_local_lub={:?}",
non_local_lub
);

non_local_lub
lub
}

/// Test if `test` is true when applied to `lower_bound` at
Expand Down Expand Up @@ -924,8 +984,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
) {
// Obviously uncool error reporting.

let fr_name = self.definitions[fr].external_name;
let outlived_fr_name = self.definitions[outlived_fr].external_name;
let fr_name = self.to_error_region(fr);
let outlived_fr_name = self.to_error_region(outlived_fr);

if let (Some(f), Some(o)) = (fr_name, outlived_fr_name) {
let tables = infcx.tcx.typeck_tables_of(mir_def_id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ where
T: Trait<'a>,
{
establish_relationships(value, |value| {
//~^ ERROR `T` does not outlive
//~^ ERROR the parameter type `T` may not live long enough

// This function call requires that
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ note: External requirements
|
42 | establish_relationships(value, |value| {
| ____________________________________^
43 | | //~^ ERROR `T` does not outlive
43 | | //~^ ERROR the parameter type `T` may not live long enough
44 | |
45 | | // This function call requires that
... |
Expand All @@ -26,18 +26,20 @@ note: External requirements
= note: number of external vids: 2
= note: where T: '_#1r

error: `T` does not outlive `'_#3r`
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/propagate-from-trait-match.rs:42:36
|
42 | establish_relationships(value, |value| {
| ____________________________________^
43 | | //~^ ERROR `T` does not outlive
43 | | //~^ ERROR the parameter type `T` may not live long enough
44 | |
45 | | // This function call requires that
... |
56 | | //~^ WARNING not reporting region error due to -Znll
57 | | });
| |_____^
|
= help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...

note: No external requirements
--> $DIR/propagate-from-trait-match.rs:38:1
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/nll/ty-outlives/impl-trait-outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ where
T: Debug,
{
x
//~^ ERROR `T` does not outlive
//~^ ERROR the parameter type `T` may not live long enough [E0309]
}

fn correct_region<'a, T>(x: Box<T>) -> impl Debug + 'a
Expand All @@ -37,7 +37,7 @@ where
T: 'b + Debug,
{
x
//~^ ERROR `T` does not outlive
//~^ ERROR the parameter type `T` may not live long enough [E0309]
}

fn outlives_region<'a, 'b, T>(x: Box<T>) -> impl Debug + 'a
Expand Down
8 changes: 6 additions & 2 deletions src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ warning: not reporting region error due to -Znll
34 | fn wrong_region<'a, 'b, T>(x: Box<T>) -> impl Debug + 'a
| ^^^^^^^^^^^^^^^

error: `T` does not outlive `'_#1r`
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/impl-trait-outlives.rs:23:5
|
23 | x
| ^
|
= help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...

error: `T` does not outlive `'_#1r`
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/impl-trait-outlives.rs:39:5
|
39 | x
| ^
|
= help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...

error: aborting due to 2 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/nll/ty-outlives/projection-implied-bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ where
fn generic2<T: Iterator>(value: T) {
twice(value, |value_ref, item| invoke2(value_ref, item));
//~^ WARNING not reporting region error due to -Znll
//~| ERROR `T` does not outlive
//~| ERROR the parameter type `T` may not live long enough
}

fn invoke2<'a, T, U>(a: &T, b: Cell<&'a Option<U>>)
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ warning: not reporting region error due to -Znll
45 | twice(value, |value_ref, item| invoke2(value_ref, item));
| ^^^^^^^

error: `T` does not outlive `'_#0r`
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/projection-implied-bounds.rs:45:18
|
45 | twice(value, |value_ref, item| invoke2(value_ref, item));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'static`...

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ where
{
with_signature(x, |mut y| Box::new(y.next()))
//~^ WARNING not reporting region error due to -Znll
//~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
//~| ERROR the associated type `<T as std::iter::Iterator>::Item` may not live long enough
}

#[rustc_regions]
Expand All @@ -53,7 +53,7 @@ where
{
with_signature(x, |mut y| Box::new(y.next()))
//~^ WARNING not reporting region error due to -Znll
//~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
//~| ERROR the associated type `<T as std::iter::Iterator>::Item` may not live long enough
}

#[rustc_regions]
Expand Down
12 changes: 8 additions & 4 deletions src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,13 @@ note: External requirements
= note: number of external vids: 4
= note: where <T as std::iter::Iterator>::Item: '_#3r

error: `<T as std::iter::Iterator>::Item` does not outlive `'_#4r`
error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
--> $DIR/projection-no-regions-closure.rs:36:23
|
36 | with_signature(x, |mut y| Box::new(y.next()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...

note: No external requirements
--> $DIR/projection-no-regions-closure.rs:32:1
Expand All @@ -86,7 +88,7 @@ note: No external requirements
34 | | T: Iterator,
35 | | {
... |
38 | | //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
38 | | //~| ERROR the associated type `<T as std::iter::Iterator>::Item` may not live long enough
39 | | }
| |_^
|
Expand All @@ -111,11 +113,13 @@ note: No external requirements
T
]

error: `<T as std::iter::Iterator>::Item` does not outlive `'_#6r`
error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
--> $DIR/projection-no-regions-closure.rs:54:23
|
54 | with_signature(x, |mut y| Box::new(y.next()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...

note: No external requirements
--> $DIR/projection-no-regions-closure.rs:50:1
Expand All @@ -125,7 +129,7 @@ note: No external requirements
52 | | T: 'b + Iterator,
53 | | {
... |
56 | | //~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
56 | | //~| ERROR the associated type `<T as std::iter::Iterator>::Item` may not live long enough
57 | | }
| |_^
|
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ where
{
Box::new(x.next())
//~^ WARNING not reporting region error due to -Znll
//~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
//~| the associated type `<T as std::iter::Iterator>::Item` may not live long enough
}

fn correct_region<'a, T>(mut x: T) -> Box<dyn Anything + 'a>
Expand All @@ -39,7 +39,7 @@ where
{
Box::new(x.next())
//~^ WARNING not reporting region error due to -Znll
//~| ERROR `<T as std::iter::Iterator>::Item` does not outlive
//~| the associated type `<T as std::iter::Iterator>::Item` may not live long enough
}

fn outlives_region<'a, 'b, T>(mut x: T) -> Box<dyn Anything + 'a>
Expand Down
8 changes: 6 additions & 2 deletions src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ warning: not reporting region error due to -Znll
40 | Box::new(x.next())
| ^^^^^^^^^^^^^^^^^^

error: `<T as std::iter::Iterator>::Item` does not outlive `'_#4r`
error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
--> $DIR/projection-no-regions-fn.rs:24:5
|
24 | Box::new(x.next())
| ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...

error: `<T as std::iter::Iterator>::Item` does not outlive `'_#5r`
error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
--> $DIR/projection-no-regions-fn.rs:40:5
|
40 | Box::new(x.next())
| ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...

error: aborting due to 2 previous errors

Loading