@@ -44,6 +44,59 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
44
44
} ;
45
45
let sp = tcx. sess . source_map ( ) . guess_head_span ( item. span ) ;
46
46
let tr = impl_. of_trait . as_ref ( ) . unwrap ( ) ;
47
+
48
+ // Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples,
49
+ // and #84660 where it would otherwise allow unsoundness.
50
+ if trait_ref. has_opaque_types ( ) {
51
+ trace ! ( "{:#?}" , item) ;
52
+ // First we find the opaque type in question.
53
+ for ty in trait_ref. substs {
54
+ for ty in ty. walk ( ) {
55
+ let ty:: subst:: GenericArgKind :: Type ( ty) = ty. unpack ( ) else { continue } ;
56
+ let ty:: Opaque ( def_id, _) = * ty. kind ( ) else { continue } ;
57
+ trace ! ( ?def_id) ;
58
+
59
+ // Then we search for mentions of the opaque type's type alias in the HIR
60
+ struct SpanFinder < ' tcx > {
61
+ sp : Span ,
62
+ def_id : DefId ,
63
+ tcx : TyCtxt < ' tcx > ,
64
+ }
65
+ impl < ' v , ' tcx > hir:: intravisit:: Visitor < ' v > for SpanFinder < ' tcx > {
66
+ #[ instrument( level = "trace" , skip( self , _id) ) ]
67
+ fn visit_path ( & mut self , path : & ' v hir:: Path < ' v > , _id : hir:: HirId ) {
68
+ // You can't mention an opaque type directly, so we look for type aliases
69
+ if let hir:: def:: Res :: Def ( hir:: def:: DefKind :: TyAlias , def_id) = path. res {
70
+ // And check if that type alias's type contains the opaque type we're looking for
71
+ for arg in self . tcx . type_of ( def_id) . walk ( ) {
72
+ if let GenericArgKind :: Type ( ty) = arg. unpack ( ) {
73
+ if let ty:: Opaque ( def_id, _) = * ty. kind ( ) {
74
+ if def_id == self . def_id {
75
+ // Finally we update the span to the mention of the type alias
76
+ self . sp = path. span ;
77
+ return ;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ hir:: intravisit:: walk_path ( self , path)
84
+ }
85
+ }
86
+
87
+ let mut visitor = SpanFinder { sp, def_id, tcx } ;
88
+ hir:: intravisit:: walk_item ( & mut visitor, item) ;
89
+ let reported = tcx
90
+ . sess
91
+ . struct_span_err ( visitor. sp , "cannot implement trait on type alias impl trait" )
92
+ . span_note ( tcx. def_span ( def_id) , "type alias impl trait defined here" )
93
+ . emit ( ) ;
94
+ return Err ( reported) ;
95
+ }
96
+ }
97
+ span_bug ! ( sp, "opaque type not found, but `has_opaque_types` is set" )
98
+ }
99
+
47
100
match traits:: orphan_check ( tcx, item. def_id . to_def_id ( ) ) {
48
101
Ok ( ( ) ) => { }
49
102
Err ( err) => emit_orphan_check_error (
@@ -143,58 +196,6 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
143
196
}
144
197
}
145
198
146
- // Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples,
147
- // and #84660 where it would otherwise allow unsoundness.
148
- if trait_ref. has_opaque_types ( ) {
149
- trace ! ( "{:#?}" , item) ;
150
- // First we find the opaque type in question.
151
- for ty in trait_ref. substs {
152
- for ty in ty. walk ( ) {
153
- let ty:: subst:: GenericArgKind :: Type ( ty) = ty. unpack ( ) else { continue } ;
154
- let ty:: Opaque ( def_id, _) = * ty. kind ( ) else { continue } ;
155
- trace ! ( ?def_id) ;
156
-
157
- // Then we search for mentions of the opaque type's type alias in the HIR
158
- struct SpanFinder < ' tcx > {
159
- sp : Span ,
160
- def_id : DefId ,
161
- tcx : TyCtxt < ' tcx > ,
162
- }
163
- impl < ' v , ' tcx > hir:: intravisit:: Visitor < ' v > for SpanFinder < ' tcx > {
164
- #[ instrument( level = "trace" , skip( self , _id) ) ]
165
- fn visit_path ( & mut self , path : & ' v hir:: Path < ' v > , _id : hir:: HirId ) {
166
- // You can't mention an opaque type directly, so we look for type aliases
167
- if let hir:: def:: Res :: Def ( hir:: def:: DefKind :: TyAlias , def_id) = path. res {
168
- // And check if that type alias's type contains the opaque type we're looking for
169
- for arg in self . tcx . type_of ( def_id) . walk ( ) {
170
- if let GenericArgKind :: Type ( ty) = arg. unpack ( ) {
171
- if let ty:: Opaque ( def_id, _) = * ty. kind ( ) {
172
- if def_id == self . def_id {
173
- // Finally we update the span to the mention of the type alias
174
- self . sp = path. span ;
175
- return ;
176
- }
177
- }
178
- }
179
- }
180
- }
181
- hir:: intravisit:: walk_path ( self , path)
182
- }
183
- }
184
-
185
- let mut visitor = SpanFinder { sp, def_id, tcx } ;
186
- hir:: intravisit:: walk_item ( & mut visitor, item) ;
187
- let reported = tcx
188
- . sess
189
- . struct_span_err ( visitor. sp , "cannot implement trait on type alias impl trait" )
190
- . span_note ( tcx. def_span ( def_id) , "type alias impl trait defined here" )
191
- . emit ( ) ;
192
- return Err ( reported) ;
193
- }
194
- }
195
- span_bug ! ( sp, "opaque type not found, but `has_opaque_types` is set" )
196
- }
197
-
198
199
Ok ( ( ) )
199
200
}
200
201
0 commit comments