Skip to content

Commit d004edf

Browse files
Don't ICE if HIR and middle types disagree in borrowck error reporting
1 parent 2ccafed commit d004edf

File tree

4 files changed

+81
-20
lines changed

4 files changed

+81
-20
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+26-8
Original file line numberDiff line numberDiff line change
@@ -4304,17 +4304,35 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
43044304
// search for relevant arguments.
43054305
let mut arguments = Vec::new();
43064306
for (index, argument) in sig.inputs().skip_binder().iter().enumerate() {
4307-
if let ty::Ref(argument_region, _, _) = argument.kind() {
4308-
if argument_region == return_region {
4309-
// Need to use the `rustc_middle::ty` types to compare against the
4310-
// `return_region`. Then use the `rustc_hir` type to get only
4311-
// the lifetime span.
4312-
if let hir::TyKind::Ref(lifetime, _) = &fn_decl.inputs[index].kind {
4307+
if let ty::Ref(argument_region, _, _) = argument.kind()
4308+
&& argument_region == return_region
4309+
{
4310+
// Need to use the `rustc_middle::ty` types to compare against the
4311+
// `return_region`. Then use the `rustc_hir` type to get only
4312+
// the lifetime span.
4313+
match &fn_decl.inputs[index].kind {
4314+
hir::TyKind::Ref(lifetime, _) => {
43134315
// With access to the lifetime, we can get
43144316
// the span of it.
43154317
arguments.push((*argument, lifetime.ident.span));
4316-
} else {
4317-
bug!("ty type is a ref but hir type is not");
4318+
}
4319+
// Resolve `self` whose self type is `&T`.
4320+
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
4321+
if let Res::SelfTyAlias { alias_to, .. } = path.res
4322+
&& let Some(alias_to) = alias_to.as_local()
4323+
&& let hir::Impl { self_ty, .. } = self
4324+
.infcx
4325+
.tcx
4326+
.hir_node_by_def_id(alias_to)
4327+
.expect_item()
4328+
.expect_impl()
4329+
&& let hir::TyKind::Ref(lifetime, _) = self_ty.kind
4330+
{
4331+
arguments.push((*argument, lifetime.ident.span));
4332+
}
4333+
}
4334+
_ => {
4335+
// Don't ICE though. It might be a type alias.
43184336
}
43194337
}
43204338
}

tests/crashes/121816.rs

-12
This file was deleted.
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Don't ICE when trying to annotate signature and we see `&()`
2+
3+
fn f<'a, T>(_: &'static &'a (), x: &'a T) -> &'static T {
4+
x
5+
}
6+
trait W<'a> {
7+
fn g<T>(self, x: &'a T) -> &'static T;
8+
}
9+
10+
// Frankly this error message is impossible to parse, but :shrug:.
11+
impl<'a> W<'a> for &'static () {
12+
fn g<T>(self, x: &'a T) -> &'static T {
13+
f(&self, x)
14+
//~^ ERROR borrowed data escapes outside of method
15+
//~| ERROR `self` does not live long enough
16+
}
17+
}
18+
19+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0521]: borrowed data escapes outside of method
2+
--> $DIR/ice-on-non-ref-sig-ty.rs:13:9
3+
|
4+
LL | impl<'a> W<'a> for &'static () {
5+
| -- lifetime `'a` defined here
6+
LL | fn g<T>(self, x: &'a T) -> &'static T {
7+
| ---- - `x` is a reference that is only valid in the method body
8+
| |
9+
| `self` declared here, outside of the method body
10+
LL | f(&self, x)
11+
| ^^^^^^^^^^^
12+
| |
13+
| `x` escapes the method body here
14+
| argument requires that `'a` must outlive `'static`
15+
16+
error[E0597]: `self` does not live long enough
17+
--> $DIR/ice-on-non-ref-sig-ty.rs:13:11
18+
|
19+
LL | impl<'a> W<'a> for &'static () {
20+
| ------- has lifetime `'static`
21+
LL | fn g<T>(self, x: &'a T) -> &'static T {
22+
| ------- also has lifetime `'static`
23+
LL | f(&self, x)
24+
| ^^^^^ `self` would have to be valid for `'static`...
25+
...
26+
LL | }
27+
| - ...but `self` will be dropped here, when the function `g` returns
28+
|
29+
= help: use data from the highlighted arguments which match the `'static` lifetime of the return type
30+
= note: functions cannot return a borrow to data owned within the function's scope, functions can only return borrows to data passed as arguments
31+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#dangling-references>
32+
33+
error: aborting due to 2 previous errors
34+
35+
Some errors have detailed explanations: E0521, E0597.
36+
For more information about an error, try `rustc --explain E0521`.

0 commit comments

Comments
 (0)