Auto merge of #89250 - Aaron1011:keep-bound-region-names, r=estebank
Don't anonymize bound region names during typeck
Once this anonymization has performed, we have no
way of recovering the original names during NLL
borrow checking. Keeping the original names allows
error messages in full NLL mode to contain the original
bound region names.
As a result, the typeck results may contain types that
differ only in the names used for their bound regions. However,
anonimization of bound regions does not guarantee that
all distinct types are unqual (e.g. not subtypes of each other).
For example, `for<'a> fn(&'a u32, &'a u32)` and
`for<'b, 'c> fn(&'b u32, &'c u32)` are subtypes of each other,
as explained here:
63cc2bb3d0/compiler/rustc_infer/src/infer/nll_relate/mod.rs (L682-L690)
Therefore, any code handling types with higher-ranked regions already
needs to handle the case where two distinct `Ty`s are 'actually'
equal.
This commit is contained in:
commit
69c1c6a173
@ -736,6 +736,26 @@ fn report_const_error(&self, c: &'tcx ty::Const<'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
struct EraseEarlyRegions<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if ty.has_type_flags(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) {
|
||||
ty.super_fold_with(self)
|
||||
} else {
|
||||
ty
|
||||
}
|
||||
}
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
if let ty::ReLateBound(..) = r { r } else { self.tcx.lifetimes.re_erased }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
@ -743,7 +763,13 @@ fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match self.infcx.fully_resolve(t) {
|
||||
Ok(t) => self.infcx.tcx.erase_regions(t),
|
||||
Ok(t) => {
|
||||
// Do not anonymize late-bound regions
|
||||
// (e.g. keep `for<'a>` named `for<'a>`).
|
||||
// This allows NLL to generate error messages that
|
||||
// refer to the higher-ranked lifetime names written by the user.
|
||||
EraseEarlyRegions { tcx: self.infcx.tcx }.fold_ty(t)
|
||||
}
|
||||
Err(_) => {
|
||||
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
||||
self.report_type_error(t);
|
||||
|
@ -8,8 +8,8 @@ LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u3
|
||||
LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
|
||||
| |_____________________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `Option<for<'r, 's> fn(&'r u32, &'s u32) -> &'r u32>`
|
||||
found enum `Option<for<'r> fn(&'r u32, &'r u32) -> &'r u32>`
|
||||
= note: expected enum `Option<for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32>`
|
||||
found enum `Option<for<'a> fn(&'a u32, &'a u32) -> &'a u32>`
|
||||
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -8,7 +8,7 @@ LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
|
||||
LL | | fn(&'x u32)) }
|
||||
| |______________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `Option<for<'r> fn(&'r u32)>`
|
||||
= note: expected enum `Option<for<'a> fn(&'a u32)>`
|
||||
found enum `Option<fn(&u32)>`
|
||||
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
@ -8,8 +8,8 @@ LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
|
||||
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
|
||||
| |__________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `Option<for<'r, 's> fn(Inv<'r>, Inv<'s>)>`
|
||||
found enum `Option<for<'r> fn(Inv<'r>, Inv<'r>)>`
|
||||
= note: expected enum `Option<for<'a, 'b> fn(Inv<'a>, Inv<'b>)>`
|
||||
found enum `Option<for<'a> fn(Inv<'a>, Inv<'a>)>`
|
||||
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -22,8 +22,8 @@ LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>),
|
||||
LL | | for<'a> fn(Inv<'a>, Inv<'a>)) }
|
||||
| |__________________________________- in this macro invocation
|
||||
|
|
||||
= note: expected enum `Option<for<'r, 's> fn(Inv<'r>, Inv<'s>)>`
|
||||
found enum `Option<for<'r> fn(Inv<'r>, Inv<'r>)>`
|
||||
= note: expected enum `Option<for<'a, 'b> fn(Inv<'a>, Inv<'b>)>`
|
||||
found enum `Option<for<'a> fn(Inv<'a>, Inv<'a>)>`
|
||||
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -4,8 +4,8 @@ error[E0308]: mismatched types
|
||||
LL | _ => y,
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected fn pointer `for<'r, 's> fn(&'r u8, &'s u8) -> &'r u8`
|
||||
found fn pointer `for<'r> fn(&'r u8, &'r u8) -> &'r u8`
|
||||
= note: expected fn pointer `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
|
||||
found fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,8 +4,8 @@ error[E0308]: mismatched types
|
||||
LL | _ => y,
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected trait object `dyn for<'r, 's> Foo<&'r u8, &'s u8>`
|
||||
found trait object `dyn for<'r> Foo<&'r u8, &'r u8>`
|
||||
= note: expected trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
|
||||
found trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/old-lub-glb-object.rs:10:14
|
||||
@ -13,8 +13,8 @@ error[E0308]: mismatched types
|
||||
LL | _ => y,
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected trait object `dyn for<'r, 's> Foo<&'r u8, &'s u8>`
|
||||
found trait object `dyn for<'r> Foo<&'r u8, &'r u8>`
|
||||
= note: expected trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
|
||||
found trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0308]: mismatched types
|
||||
LL | let y: for<'a> fn(&'a ()) = x;
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected fn pointer `for<'r> fn(&'r ())`
|
||||
= note: expected fn pointer `for<'a> fn(&'a ())`
|
||||
found fn pointer `fn(&())`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -4,7 +4,7 @@ error[E0308]: mismatched types
|
||||
LL | let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
|
||||
| ^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected fn pointer `for<'r, 's> fn(&'r u32, &'s u32) -> &'r u32`
|
||||
= note: expected fn pointer `for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32`
|
||||
found fn pointer `for<'a> fn(&'a u32, &'a u32) -> &'a u32`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -14,7 +14,7 @@ LL | let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected fn pointer `for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32`
|
||||
found fn pointer `for<'r> fn(&'r u32, &'r u32) -> &'r u32`
|
||||
found fn pointer `for<'a> fn(&'a u32, &'a u32) -> &'a u32`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0308]: mismatched types
|
||||
LL | let y: Box<dyn for<'a> Foo<'a>> = x;
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected trait object `dyn for<'r> Foo<'r>`
|
||||
= note: expected trait object `dyn for<'a> Foo<'a>`
|
||||
found trait object `dyn Foo<'_>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -31,7 +31,7 @@ LL | |
|
||||
LL | | };
|
||||
| |_^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r, 's> Fn<(&'r Foo<'s>,)>`
|
||||
= note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>`
|
||||
found type `Fn<(&Foo<'_>,)>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -46,7 +46,7 @@ LL | |
|
||||
LL | | };
|
||||
| |_^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r, 's> Fn<(&'r Foo<'s>,)>`
|
||||
= note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>`
|
||||
found type `Fn<(&Foo<'_>,)>`
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
@ -61,7 +61,7 @@ LL | |
|
||||
LL | | };
|
||||
| |_^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'_>,)>`, for any lifetime `'1`...
|
||||
= note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2`
|
||||
|
||||
error: implementation of `FnOnce` is not general enough
|
||||
@ -76,7 +76,7 @@ LL | |
|
||||
LL | | };
|
||||
| |_^ implementation of `FnOnce` is not general enough
|
||||
|
|
||||
= note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&Foo<'1>,)>`, for any lifetime `'1`...
|
||||
= note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&'a Foo<'1>,)>`, for any lifetime `'1`...
|
||||
= note: ...but it actually implements `FnOnce<(&Foo<'2>,)>`, for some specific lifetime `'2`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user