Skip to content

Commit 05c5caa

Browse files
Don't ICE if method receiver fails to unify with arbitrary_self_types
1 parent 1b67f8b commit 05c5caa

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

compiler/rustc_hir_typeck/src/method/confirm.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
471471
self_ty, method_self_ty, self.span, pick
472472
);
473473
let cause = self.cause(
474-
self.span,
474+
self.self_expr.span,
475475
ObligationCauseCode::UnifyReceiver(Box::new(UnifyReceiverContext {
476476
assoc_item: pick.item,
477477
param_env: self.param_env,
@@ -482,13 +482,22 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
482482
Ok(InferOk { obligations, value: () }) => {
483483
self.register_predicates(obligations);
484484
}
485-
Err(_) => {
486-
span_bug!(
487-
self.span,
488-
"{} was a subtype of {} but now is not?",
489-
self_ty,
490-
method_self_ty
491-
);
485+
Err(terr) => {
486+
// FIXME(arbitrary_self_types): We probably should limit the
487+
// situations where this can occur by adding additional restrictions
488+
// to the feature, like the self type can't reference method substs.
489+
if self.tcx.features().arbitrary_self_types {
490+
self.err_ctxt()
491+
.report_mismatched_types(&cause, method_self_ty, self_ty, terr)
492+
.emit();
493+
} else {
494+
span_bug!(
495+
self.span,
496+
"{} was a subtype of {} but now is not?",
497+
self_ty,
498+
method_self_ty
499+
);
500+
}
492501
}
493502
}
494503
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(arbitrary_self_types)]
2+
3+
use std::ops::Deref;
4+
5+
struct Foo(u32);
6+
impl Foo {
7+
fn get<R: Deref<Target=Self>>(self: R) -> u32 {
8+
self.0
9+
}
10+
}
11+
12+
fn main() {
13+
let mut foo = Foo(1);
14+
foo.get::<&Foo>();
15+
//~^ ERROR mismatched types
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/arbitrary-self-from-method-substs.rs:14:5
3+
|
4+
LL | foo.get::<&Foo>();
5+
| ^^^ expected `&Foo`, found `Foo`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)