store a copy of the Issue32230 info within TypeError

The data can't be looked up from the region variable directly, because
the region variable might have been destroyed at the end of a snapshot.

Fixes #40000.
Fixes #40743.
This commit is contained in:
Ariel Ben-Yehuda 2017-03-26 14:15:47 +03:00
parent 49c67bd632
commit 7e0f7a50ab
5 changed files with 69 additions and 36 deletions

View File

@ -426,30 +426,26 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
{
debug!("note_issue_32330: terr={:?}", terr);
match *terr {
TypeError::RegionsInsufficientlyPolymorphic(_, &Region::ReVar(vid)) |
TypeError::RegionsOverlyPolymorphic(_, &Region::ReVar(vid)) => {
match self.region_vars.var_origin(vid) {
RegionVariableOrigin::EarlyBoundRegion(_, _, Some(Issue32330 {
fn_def_id,
region_name
})) => {
diag.note(
&format!("lifetime parameter `{0}` declared on fn `{1}` \
appears only in the return type, \
but here is required to be higher-ranked, \
which means that `{0}` must appear in both \
argument and return types",
region_name,
self.tcx.item_path_str(fn_def_id)));
diag.note(
&format!("this error is the result of a recent bug fix; \
for more information, see issue #33685 \
<https://github.com/rust-lang/rust/issues/33685>"));
}
_ => { }
}
TypeError::RegionsInsufficientlyPolymorphic(_, _, Some(box Issue32330 {
fn_def_id, region_name
})) |
TypeError::RegionsOverlyPolymorphic(_, _, Some(box Issue32330 {
fn_def_id, region_name
})) => {
diag.note(
&format!("lifetime parameter `{0}` declared on fn `{1}` \
appears only in the return type, \
but here is required to be higher-ranked, \
which means that `{0}` must appear in both \
argument and return types",
region_name,
self.tcx.item_path_str(fn_def_id)));
diag.note(
&format!("this error is the result of a recent bug fix; \
for more information, see issue #33685 \
<https://github.com/rust-lang/rust/issues/33685>"));
}
_ => { }
_ => {}
}
}

View File

@ -15,6 +15,7 @@ use super::{CombinedSnapshot,
InferCtxt,
LateBoundRegion,
HigherRankedType,
RegionVariableOrigin,
SubregionOrigin,
SkolemizationMap};
use super::combine::CombineFields;
@ -656,14 +657,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
skol_br,
tainted_region);
let issue_32330 = if let &ty::ReVar(vid) = tainted_region {
match self.region_vars.var_origin(vid) {
RegionVariableOrigin::EarlyBoundRegion(_, _, issue_32330) => {
issue_32330.map(Box::new)
}
_ => None
}
} else {
None
};
if overly_polymorphic {
debug!("Overly polymorphic!");
return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
tainted_region));
tainted_region,
issue_32330));
} else {
debug!("Not as polymorphic!");
return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
tainted_region));
tainted_region,
issue_32330));
}
}
}

View File

@ -39,8 +39,8 @@ pub enum TypeError<'tcx> {
RegionsDoesNotOutlive(&'tcx Region, &'tcx Region),
RegionsNotSame(&'tcx Region, &'tcx Region),
RegionsNoOverlap(&'tcx Region, &'tcx Region),
RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region),
RegionsOverlyPolymorphic(BoundRegion, &'tcx Region),
RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
RegionsOverlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
Sorts(ExpectedFound<Ty<'tcx>>),
IntMismatch(ExpectedFound<ty::IntVarValue>),
FloatMismatch(ExpectedFound<ast::FloatTy>),
@ -116,11 +116,11 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
RegionsNoOverlap(..) => {
write!(f, "lifetimes do not intersect")
}
RegionsInsufficientlyPolymorphic(br, _) => {
RegionsInsufficientlyPolymorphic(br, _, _) => {
write!(f, "expected bound lifetime parameter {}, \
found concrete lifetime", br)
}
RegionsOverlyPolymorphic(br, _) => {
RegionsOverlyPolymorphic(br, _, _) => {
write!(f, "expected concrete lifetime, \
found bound lifetime parameter {}", br)
}
@ -253,15 +253,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.note_and_explain_region(db, "...does not overlap ",
region2, "");
}
RegionsInsufficientlyPolymorphic(_, conc_region) => {
RegionsInsufficientlyPolymorphic(_, conc_region, _) => {
self.note_and_explain_region(db, "concrete lifetime that was found is ",
conc_region, "");
}
RegionsOverlyPolymorphic(_, &ty::ReVar(_)) => {
RegionsOverlyPolymorphic(_, &ty::ReVar(_), _) => {
// don't bother to print out the message below for
// inference variables, it's not very illuminating.
}
RegionsOverlyPolymorphic(_, conc_region) => {
RegionsOverlyPolymorphic(_, conc_region, _) => {
self.note_and_explain_region(db, "expected concrete lifetime is ",
conc_region, "");
}

View File

@ -293,11 +293,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
RegionsNoOverlap(a, b) => {
return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b))
}
RegionsInsufficientlyPolymorphic(a, b) => {
return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
RegionsInsufficientlyPolymorphic(a, b, ref c) => {
let c = c.clone();
return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b, c))
}
RegionsOverlyPolymorphic(a, b) => {
return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
RegionsOverlyPolymorphic(a, b, ref c) => {
let c = c.clone();
return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b, c))
}
IntMismatch(x) => IntMismatch(x),
FloatMismatch(x) => FloatMismatch(x),

View File

@ -0,0 +1,21 @@
// Copyright 2017 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.
#![feature(closure_to_fn_coercion)]
fn main() {
let bar: fn(&mut u32) = |_| {}; //~ ERROR mismatched types
//~| expected concrete lifetime, found bound lifetime parameter
fn foo(x: Box<Fn(&i32)>) {}
let bar = Box::new(|x: &i32| {}) as Box<Fn(_)>;
foo(bar); //~ ERROR mismatched types
//~| expected concrete lifetime, found bound lifetime parameter
}