Rollup merge of #98022 - compiler-errors:erroneous-borrowck-span, r=oli-obk
Fix erroneous span for borrowck error I am not confident that this is the correct fix, but it does the job. Open to suggestions for a real fix instead. Fixes #97997 The issue is that we pass a [dummy location](https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/mir/visit.rs.html#302) when type-checking the ["required consts"](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Body.html#structfield.required_consts) that are needed by the MIR body during borrowck. This means that when we fail to evaluate the constant, we use the span of `bb0[0]`, instead of the actual span of the constant. There are quite a few other places that use `START_BLOCK.start_location()`, `Location::START`, etc. when calling for a random/unspecified `Location` value. This is because, unlike (for example) `Span`, we don't have a dummy/miscellaneous value to use instead. I would appreciate guidance (either in this PR, or a follow-up) on what needs to be done to clean this up in general.
This commit is contained in:
commit
a7f789b502
@ -357,12 +357,20 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
.add_element(live_region_vid, location);
|
||||
});
|
||||
|
||||
// HACK(compiler-errors): Constants that are gathered into Body.required_consts
|
||||
// have their locations erased...
|
||||
let locations = if location != Location::START {
|
||||
location.to_locations()
|
||||
} else {
|
||||
Locations::All(constant.span)
|
||||
};
|
||||
|
||||
if let Some(annotation_index) = constant.user_ty {
|
||||
if let Err(terr) = self.cx.relate_type_and_user_type(
|
||||
constant.literal.ty(),
|
||||
ty::Variance::Invariant,
|
||||
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
||||
location.to_locations(),
|
||||
locations,
|
||||
ConstraintCategory::Boring,
|
||||
) {
|
||||
let annotation = &self.cx.user_type_annotations[annotation_index];
|
||||
@ -390,12 +398,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
promoted: &Body<'tcx>,
|
||||
ty,
|
||||
san_ty| {
|
||||
if let Err(terr) = verifier.cx.eq_types(
|
||||
ty,
|
||||
san_ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Boring,
|
||||
) {
|
||||
if let Err(terr) =
|
||||
verifier.cx.eq_types(ty, san_ty, locations, ConstraintCategory::Boring)
|
||||
{
|
||||
span_mirbug!(
|
||||
verifier,
|
||||
promoted,
|
||||
@ -416,7 +421,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
if let Err(terr) = self.cx.fully_perform_op(
|
||||
location.to_locations(),
|
||||
locations,
|
||||
ConstraintCategory::Boring,
|
||||
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
|
||||
constant.literal.ty(),
|
||||
@ -435,7 +440,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
}
|
||||
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
|
||||
let unnormalized_ty = tcx.type_of(static_def_id);
|
||||
let locations = location.to_locations();
|
||||
let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
|
||||
let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
|
||||
|
||||
@ -454,7 +458,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
self.cx.normalize_and_prove_instantiated_predicates(
|
||||
def_id,
|
||||
instantiated_predicates,
|
||||
location.to_locations(),
|
||||
locations,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ error: implementation of `Foo` is not general enough
|
||||
--> $DIR/hrtb-just-for-static.rs:24:5
|
||||
|
|
||||
LL | want_hrtb::<StaticInt>()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
||||
|
|
||||
= note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Foo<&'static isize>`
|
||||
|
16
src/test/ui/nll/issue-97997.rs
Normal file
16
src/test/ui/nll/issue-97997.rs
Normal file
@ -0,0 +1,16 @@
|
||||
trait Foo {
|
||||
const ASSOC: bool = true;
|
||||
}
|
||||
impl<T> Foo for fn(T) {}
|
||||
|
||||
fn foo(_x: i32) {}
|
||||
|
||||
fn impls_foo<T: Foo>(_x: T) {}
|
||||
|
||||
fn main() {
|
||||
impls_foo(foo as fn(i32));
|
||||
|
||||
<fn(&u8) as Foo>::ASSOC;
|
||||
//~^ ERROR implementation of `Foo` is not general enough
|
||||
//~| ERROR implementation of `Foo` is not general enough
|
||||
}
|
20
src/test/ui/nll/issue-97997.stderr
Normal file
20
src/test/ui/nll/issue-97997.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error: implementation of `Foo` is not general enough
|
||||
--> $DIR/issue-97997.rs:13:5
|
||||
|
|
||||
LL | <fn(&u8) as Foo>::ASSOC;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
||||
|
|
||||
= note: `Foo` would have to be implemented for the type `for<'r> fn(&'r u8)`
|
||||
= note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`
|
||||
|
||||
error: implementation of `Foo` is not general enough
|
||||
--> $DIR/issue-97997.rs:13:5
|
||||
|
|
||||
LL | <fn(&u8) as Foo>::ASSOC;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
|
||||
|
|
||||
= note: `Foo` would have to be implemented for the type `for<'r> fn(&'r u8)`
|
||||
= note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user