when using feature(nll), don't warn about AST-based region errors
Also, keep reporting AST-based region errors that are not occuring in a fn body.
This commit is contained in:
parent
cfa4ffa374
commit
80c510e353
7 changed files with 120 additions and 13 deletions
|
|
@ -258,10 +258,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn report_region_errors(&self,
|
||||
region_scope_tree: ®ion::ScopeTree,
|
||||
errors: &Vec<RegionResolutionError<'tcx>>) {
|
||||
errors: &Vec<RegionResolutionError<'tcx>>,
|
||||
will_later_be_reported_by_nll: bool) {
|
||||
debug!("report_region_errors(): {} errors to start", errors.len());
|
||||
|
||||
if self.tcx.sess.nll() {
|
||||
if will_later_be_reported_by_nll && self.tcx.sess.nll() {
|
||||
// With `#![feature(nll)]`, we want to present a nice user
|
||||
// experience, so don't even mention the errors from the
|
||||
// AST checker.
|
||||
if self.tcx.sess.features.borrow().nll {
|
||||
return;
|
||||
}
|
||||
|
||||
// But with -Znll, it's nice to have some note for later.
|
||||
for error in errors {
|
||||
match *error {
|
||||
RegionResolutionError::ConcreteFailure(ref origin, ..) |
|
||||
|
|
|
|||
|
|
@ -1159,10 +1159,45 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
/// result. After this, no more unification operations should be
|
||||
/// done -- or the compiler will panic -- but it is legal to use
|
||||
/// `resolve_type_vars_if_possible` as well as `fully_resolve`.
|
||||
pub fn resolve_regions_and_report_errors(&self,
|
||||
region_context: DefId,
|
||||
region_map: ®ion::ScopeTree,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>) {
|
||||
pub fn resolve_regions_and_report_errors(
|
||||
&self,
|
||||
region_context: DefId,
|
||||
region_map: ®ion::ScopeTree,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||
) {
|
||||
self.resolve_regions_and_report_errors_inner(
|
||||
region_context,
|
||||
region_map,
|
||||
outlives_env,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
/// Like `resolve_regions_and_report_errors`, but skips error
|
||||
/// reporting if NLL is enabled. This is used for fn bodies where
|
||||
/// the same error may later be reported by the NLL-based
|
||||
/// inference.
|
||||
pub fn resolve_regions_and_report_errors_unless_nll(
|
||||
&self,
|
||||
region_context: DefId,
|
||||
region_map: ®ion::ScopeTree,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||
) {
|
||||
self.resolve_regions_and_report_errors_inner(
|
||||
region_context,
|
||||
region_map,
|
||||
outlives_env,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
fn resolve_regions_and_report_errors_inner(
|
||||
&self,
|
||||
region_context: DefId,
|
||||
region_map: ®ion::ScopeTree,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||
will_later_be_reported_by_nll: bool,
|
||||
) {
|
||||
assert!(self.is_tainted_by_errors() || self.region_obligations.borrow().is_empty(),
|
||||
"region_obligations not empty: {:#?}",
|
||||
self.region_obligations.borrow());
|
||||
|
|
@ -1187,7 +1222,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
// this infcx was in use. This is totally hokey but
|
||||
// otherwise we have a hard time separating legit region
|
||||
// errors from silly ones.
|
||||
self.report_region_errors(region_map, &errors); // see error_reporting module
|
||||
self.report_region_errors(region_map, &errors, will_later_be_reported_by_nll);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
rcx.visit_body(body);
|
||||
rcx.visit_region_obligations(id);
|
||||
}
|
||||
rcx.resolve_regions_and_report_errors();
|
||||
rcx.resolve_regions_and_report_errors_unless_nll();
|
||||
|
||||
assert!(self.tables.borrow().free_region_map.is_empty());
|
||||
self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
|
||||
|
|
@ -173,7 +173,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
rcx.visit_fn_body(fn_id, body, self.tcx.hir.span(fn_id));
|
||||
}
|
||||
|
||||
rcx.resolve_regions_and_report_errors();
|
||||
rcx.resolve_regions_and_report_errors_unless_nll();
|
||||
|
||||
// In this mode, we also copy the free-region-map into the
|
||||
// tables of the enclosing fcx. In the other regionck modes
|
||||
|
|
@ -371,6 +371,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
&self.outlives_environment);
|
||||
}
|
||||
|
||||
fn resolve_regions_and_report_errors_unless_nll(&self) {
|
||||
self.fcx.resolve_regions_and_report_errors_unless_nll(self.subject_def_id,
|
||||
&self.region_scope_tree,
|
||||
&self.outlives_environment);
|
||||
}
|
||||
|
||||
fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) {
|
||||
debug!("regionck::visit_pat(pat={:?})", pat);
|
||||
pat.each_binding(|_, id, span, _| {
|
||||
|
|
|
|||
|
|
@ -10,11 +10,15 @@
|
|||
|
||||
// Various examples of structs whose fields are not well-formed.
|
||||
|
||||
// revisions:lexical nll
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![cfg_attr(nll, feature(nll))]
|
||||
|
||||
struct Ref<'a, T> {
|
||||
field: &'a T
|
||||
//~^ ERROR the parameter type `T` may not live long enough
|
||||
//[lexical]~^ ERROR the parameter type `T` may not live long enough
|
||||
//[nll]~^^ ERROR the parameter type `T` may not live long enough
|
||||
}
|
||||
|
||||
struct RefOk<'a, T:'a> {
|
||||
|
|
@ -23,12 +27,14 @@ struct RefOk<'a, T:'a> {
|
|||
|
||||
struct RefIndirect<'a, T> {
|
||||
field: RefOk<'a, T>
|
||||
//~^ ERROR the parameter type `T` may not live long enough
|
||||
//[lexical]~^ ERROR the parameter type `T` may not live long enough
|
||||
//[nll]~^^ ERROR the parameter type `T` may not live long enough
|
||||
}
|
||||
|
||||
struct DoubleRef<'a, 'b, T> {
|
||||
field: &'a &'b T
|
||||
//~^ ERROR reference has a longer lifetime than the data it references
|
||||
//[lexical]~^ ERROR reference has a longer lifetime than the data it references
|
||||
//[nll]~^^ ERROR reference has a longer lifetime than the data it references
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:-Zborrowck=mir -Znll-dump-cause
|
||||
// compile-flags:-Znll-dump-cause
|
||||
|
||||
// Test that a structure which tries to store a pointer to `y` into
|
||||
// `p` (indirectly) fails to compile.
|
||||
|
|
|
|||
41
src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs
Normal file
41
src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that we assume that universal types like `T` outlive the
|
||||
// function body. Same as ty-param-fn-body, but uses `feature(nll)`,
|
||||
// which affects error reporting.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(dyn_trait)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// No errors here, because `'a` is local to the body.
|
||||
fn region_within_body<T>(t: T) {
|
||||
let some_int = 22;
|
||||
let cell = Cell::new(&some_int);
|
||||
outlives(cell, t)
|
||||
}
|
||||
|
||||
// Error here, because T: 'a is not satisfied.
|
||||
fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) {
|
||||
outlives(cell, t)
|
||||
//~^ ERROR the parameter type `T` may not live long enough
|
||||
}
|
||||
|
||||
fn outlives<'a, T>(x: Cell<&'a usize>, y: T)
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
error[E0309]: the parameter type `T` may not live long enough
|
||||
--> $DIR/ty-param-fn-body-nll-feature.rs:31:5
|
||||
|
|
||||
31 | outlives(cell, t)
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `T: 'a`...
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue