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:
parent
49c67bd632
commit
7e0f7a50ab
@ -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>"));
|
||||
}
|
||||
_ => { }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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, "");
|
||||
}
|
||||
|
@ -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),
|
||||
|
21
src/test/compile-fail/issue-40000.rs
Normal file
21
src/test/compile-fail/issue-40000.rs
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user