Skip to content

Commit 75d6b9a

Browse files
Fix trait method resolution on an adjusted never type
1 parent 7a9ab3f commit 75d6b9a

4 files changed

Lines changed: 40 additions & 26 deletions

File tree

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 17 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,15 @@ 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 root_ty = Ty::new_var(self.tcx, self.root_var(ty_id))
499+
&& self.diverging_type_vars.borrow().contains(&root_ty)
500+
{
501+
self.demand_eqtype(DUMMY_SP, root_ty, self.tcx.types.never);
485502
} 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);
494503
let guar = match *ty.kind() {
495504
_ if let Some(guar) = self.tainted_by_errors() => guar,
496505
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
}

tests/ui/never_type/basic/clone-never.stderr

Lines changed: 0 additions & 16 deletions
This file was deleted.
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)