Skip to content

Commit ff8aec4

Browse files
Fix trait method resolution on an adjusted never type
1 parent 6769f69 commit ff8aec4

4 files changed

Lines changed: 45 additions & 26 deletions

File tree

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
459459
// If we encountered an `_` type or an error type during autoderef, this is
460460
// ambiguous.
461461
if let Some(bad_ty) = &steps.opt_bad_ty {
462+
// Ended up encountering a type variable when doing autoderef,
463+
// but it may not be a type variable after processing obligations
464+
// in our local `FnCtxt`, so don't call `structurally_resolve_type`.
465+
let ty = &bad_ty.ty;
466+
let ty = self
467+
.probe_instantiate_query_response(span, &orig_values, ty)
468+
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
469+
let ty = self.resolve_vars_if_possible(ty.value);
470+
462471
if is_suggestion.0 {
463472
// Ambiguity was encountered during a suggestion. There's really
464473
// not much use in suggesting methods in this case.
@@ -482,15 +491,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
482491
span,
483492
MissingTypeAnnot,
484493
);
494+
// If `ty` is an inference variable that was created by being adjusted from the never type,
495+
// We demand the type to be equal to the never type, so we can probe the never type for methods
496+
// (see https://github.com/rust-lang/rust/issues/143349)
497+
} else if let ty::Infer(ty::TyVar(ty_id)) = *ty.kind()
498+
&& let ty_id = self.root_var(ty_id)
499+
&& let root_ty = Ty::new_var(self.tcx, ty_id)
500+
&& self
501+
.diverging_type_vars
502+
.borrow()
503+
.iter()
504+
.any(|&candidate_id| self.root_var(candidate_id) == ty_id)
505+
{
506+
self.demand_eqtype(span, root_ty, self.tcx.types.never);
485507
} else {
486-
// Ended up encountering a type variable when doing autoderef,
487-
// but it may not be a type variable after processing obligations
488-
// in our local `FnCtxt`, so don't call `structurally_resolve_type`.
489-
let ty = &bad_ty.ty;
490-
let ty = self
491-
.probe_instantiate_query_response(span, &orig_values, ty)
492-
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
493-
let ty = self.resolve_vars_if_possible(ty.value);
494508
let guar = match *ty.kind() {
495509
_ if let Some(guar) = self.tainted_by_errors() => guar,
496510
ty::Infer(ty::TyVar(_)) => {
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
//! regression test for issue #2151
1+
//@ check-pass
2+
// Regression test for https://github.com/rust-lang/rust/issues/143349
23

34
fn main() {
4-
let x = panic!(); //~ ERROR type annotations needed
5+
let x = panic!();
56
x.clone();
67
}
Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +0,0 @@
1-
error[E0282]: type annotations needed
2-
--> $DIR/clone-never.rs:4:9
3-
|
4-
LL | let x = panic!();
5-
| ^
6-
LL | x.clone();
7-
| - type must be known at this point
8-
|
9-
help: consider giving `x` an explicit type
10-
|
11-
LL | let x: /* Type */ = panic!();
12-
| ++++++++++++
13-
14-
error: aborting due to 1 previous error
15-
16-
For more information about this error, try `rustc --explain E0282`.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ check-pass
2+
// Regression test for https://github.com/rust-lang/rust/issues/143349
3+
4+
#![feature(never_type)]
5+
6+
trait Trait {
7+
fn method(&self);
8+
}
9+
impl Trait for ! {
10+
fn method(&self) {
11+
todo!()
12+
}
13+
}
14+
15+
fn main() {
16+
let x = loop {};
17+
x.method();
18+
19+
{ loop {} }.method();
20+
}

0 commit comments

Comments
 (0)