Skip to content

Commit 7db5f81

Browse files
Relax recursive opaque type check
1 parent 8d361cb commit 7db5f81

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed

Diff for: compiler/rustc_hir_typeck/src/writeback.rs

+4-20
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,19 @@
33
// substitutions.
44

55
use crate::FnCtxt;
6-
use hir::def_id::LocalDefId;
76
use rustc_data_structures::unord::ExtendUnord;
87
use rustc_errors::{ErrorGuaranteed, StashKey};
98
use rustc_hir as hir;
109
use rustc_hir::intravisit::{self, Visitor};
1110
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
1211
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
1312
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
14-
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
13+
use rustc_middle::ty::visit::TypeVisitableExt;
1514
use rustc_middle::ty::{self, Ty, TyCtxt};
1615
use rustc_span::symbol::sym;
1716
use rustc_span::Span;
1817

1918
use std::mem;
20-
use std::ops::ControlFlow;
2119

2220
///////////////////////////////////////////////////////////////////////////
2321
// Entry point
@@ -565,23 +563,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
565563
let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span);
566564
let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span);
567565

568-
struct RecursionChecker {
569-
def_id: LocalDefId,
570-
}
571-
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for RecursionChecker {
572-
type BreakTy = ();
573-
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
574-
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() {
575-
if def_id == self.def_id.to_def_id() {
576-
return ControlFlow::Break(());
577-
}
578-
}
579-
t.super_visit_with(self)
580-
}
581-
}
582-
if hidden_type
583-
.visit_with(&mut RecursionChecker { def_id: opaque_type_key.def_id })
584-
.is_break()
566+
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
567+
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
568+
&& alias_ty.args == opaque_type_key.args
585569
{
586570
continue;
587571
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// issue: 113596
2+
3+
#![feature(type_alias_impl_trait)]
4+
5+
trait Test {}
6+
7+
struct A;
8+
9+
impl Test for A {}
10+
11+
struct B<T> {
12+
inner: T,
13+
}
14+
15+
impl<T: Test> Test for B<T> {}
16+
17+
type TestImpl = impl Test;
18+
19+
fn test() -> TestImpl {
20+
A
21+
}
22+
23+
fn make_option() -> Option<TestImpl> {
24+
Some(test())
25+
}
26+
27+
fn make_option2() -> Option<TestImpl> {
28+
let inner = make_option().unwrap();
29+
30+
Some(B { inner })
31+
//~^ ERROR concrete type differs from previous defining opaque type use
32+
}
33+
34+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: concrete type differs from previous defining opaque type use
2+
--> $DIR/recursive-tait-conflicting-defn.rs:30:3
3+
|
4+
LL | Some(B { inner })
5+
| ^^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
6+
|
7+
note: previous use here
8+
--> $DIR/recursive-tait-conflicting-defn.rs:20:3
9+
|
10+
LL | A
11+
| ^
12+
13+
error: aborting due to previous error
14+

0 commit comments

Comments
 (0)