11use rustc_errors:: StashKey ;
22use rustc_hir:: def:: DefKind ;
33use rustc_hir:: def_id:: LocalDefId ;
4- use rustc_hir:: intravisit:: { self , Visitor } ;
5- use rustc_hir:: { self as hir, def, Expr , ImplItem , Item , Node , TraitItem } ;
6- use rustc_middle:: bug;
4+ use rustc_hir:: { self as hir, def, intravisit, Expr , ImplItem , Item , Node , TraitItem } ;
75use rustc_middle:: hir:: nested_filter;
86use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeVisitableExt } ;
7+ use rustc_middle:: { bug, span_bug} ;
98use rustc_span:: DUMMY_SP ;
109
11- use crate :: errors:: { TaitForwardCompat , TaitForwardCompat2 , UnconstrainedOpaqueType } ;
10+ use crate :: errors:: { TaitForwardCompat2 , UnconstrainedOpaqueType } ;
1211
1312/// Checks "defining uses" of opaque `impl Trait` in associated types.
1413/// These can only be defined by associated items of the same trait.
@@ -82,38 +81,9 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
8281/// ```
8382#[ instrument( skip( tcx) , level = "debug" ) ]
8483pub ( super ) fn find_opaque_ty_constraints_for_tait ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> Ty < ' _ > {
85- let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
86- let scope = tcx. hir ( ) . get_defining_scope ( hir_id) ;
8784 let mut locator = TaitConstraintLocator { def_id, tcx, found : None , typeck_types : vec ! [ ] } ;
8885
89- debug ! ( ?scope) ;
90-
91- if scope == hir:: CRATE_HIR_ID {
92- tcx. hir ( ) . walk_toplevel_module ( & mut locator) ;
93- } else {
94- trace ! ( "scope={:#?}" , tcx. hir_node( scope) ) ;
95- match tcx. hir_node ( scope) {
96- // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
97- // This allows our visitor to process the defining item itself, causing
98- // it to pick up any 'sibling' defining uses.
99- //
100- // For example, this code:
101- // ```
102- // fn foo() {
103- // type Blah = impl Debug;
104- // let my_closure = || -> Blah { true };
105- // }
106- // ```
107- //
108- // requires us to explicitly process `foo()` in order
109- // to notice the defining usage of `Blah`.
110- Node :: Item ( it) => locator. visit_item ( it) ,
111- Node :: ImplItem ( it) => locator. visit_impl_item ( it) ,
112- Node :: TraitItem ( it) => locator. visit_trait_item ( it) ,
113- Node :: ForeignItem ( it) => locator. visit_foreign_item ( it) ,
114- other => bug ! ( "{:?} is not a valid scope for an opaque type item" , other) ,
115- }
116- }
86+ tcx. hir ( ) . walk_toplevel_module ( & mut locator) ;
11787
11888 if let Some ( hidden) = locator. found {
11989 // Only check against typeck if we didn't already error
@@ -137,12 +107,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
137107 let reported = tcx. dcx ( ) . emit_err ( UnconstrainedOpaqueType {
138108 span : tcx. def_span ( def_id) ,
139109 name : tcx. item_name ( parent_def_id. to_def_id ( ) ) ,
140- what : match tcx. hir_node ( scope) {
141- _ if scope == hir:: CRATE_HIR_ID => "module" ,
142- Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Mod ( _) , .. } ) => "module" ,
143- Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Impl ( _) , .. } ) => "impl" ,
144- _ => "item" ,
145- } ,
110+ what : "crate" ,
146111 } ) ;
147112 Ty :: new_error ( tcx, reported)
148113 }
@@ -176,6 +141,13 @@ impl TaitConstraintLocator<'_> {
176141 return ;
177142 }
178143
144+ let opaque_types_defined_by = self . tcx . opaque_types_defined_by ( item_def_id) ;
145+ // Don't try to check items that cannot possibly constrain the type.
146+ if opaque_types_defined_by. is_empty ( ) {
147+ debug ! ( "no constraint: no opaque types defined" ) ;
148+ return ;
149+ }
150+
179151 // Function items with `_` in their return type already emit an error, skip any
180152 // "non-defining use" errors for them.
181153 // Note that we use `Node::fn_sig` instead of `Node::fn_decl` here, because the former
@@ -215,8 +187,6 @@ impl TaitConstraintLocator<'_> {
215187 return ;
216188 }
217189
218- let opaque_types_defined_by = self . tcx . opaque_types_defined_by ( item_def_id) ;
219-
220190 let mut constrained = false ;
221191 for ( & opaque_type_key, & hidden_type) in & tables. concrete_opaque_types {
222192 if opaque_type_key. def_id != self . def_id {
@@ -225,13 +195,12 @@ impl TaitConstraintLocator<'_> {
225195 constrained = true ;
226196
227197 if !opaque_types_defined_by. contains ( & self . def_id ) {
228- self . tcx . dcx ( ) . emit_err ( TaitForwardCompat {
229- span : hidden_type. span ,
230- item_span : self
231- . tcx
232- . def_ident_span ( item_def_id)
233- . unwrap_or_else ( || self . tcx . def_span ( item_def_id) ) ,
234- } ) ;
198+ span_bug ! (
199+ hidden_type. span,
200+ "item registered hidden type {} for {:?}, even though it does not define it" ,
201+ hidden_type. ty,
202+ opaque_type_key
203+ ) ;
235204 }
236205 let concrete_type =
237206 self . tcx . erase_regions ( hidden_type. remap_generic_params_to_declaration_params (
@@ -247,14 +216,20 @@ impl TaitConstraintLocator<'_> {
247216 if !constrained {
248217 debug ! ( "no constraints in typeck results" ) ;
249218 if opaque_types_defined_by. contains ( & self . def_id ) {
250- self . tcx . dcx ( ) . emit_err ( TaitForwardCompat2 {
219+ let guar = self . tcx . dcx ( ) . emit_err ( TaitForwardCompat2 {
251220 span : self
252221 . tcx
253222 . def_ident_span ( item_def_id)
254223 . unwrap_or_else ( || self . tcx . def_span ( item_def_id) ) ,
255224 opaque_type_span : self . tcx . def_span ( self . def_id ) ,
256225 opaque_type : self . tcx . def_path_str ( self . def_id ) ,
257226 } ) ;
227+ // TODO: land this change as a separate PR on master, it works on its own.
228+ // Avoid "opaque type not constrained" errors on the opaque itself.
229+ self . found = Some ( ty:: OpaqueHiddenType {
230+ span : DUMMY_SP ,
231+ ty : Ty :: new_error ( self . tcx , guar) ,
232+ } ) ;
258233 }
259234 return ;
260235 } ;
@@ -300,19 +275,13 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
300275 }
301276 fn visit_item ( & mut self , it : & ' tcx Item < ' tcx > ) {
302277 trace ! ( ?it. owner_id) ;
303- // The opaque type itself or its children are not within its reveal scope.
304- if it. owner_id . def_id != self . def_id {
305- self . check ( it. owner_id . def_id ) ;
306- intravisit:: walk_item ( self , it) ;
307- }
278+ self . check ( it. owner_id . def_id ) ;
279+ intravisit:: walk_item ( self , it) ;
308280 }
309281 fn visit_impl_item ( & mut self , it : & ' tcx ImplItem < ' tcx > ) {
310282 trace ! ( ?it. owner_id) ;
311- // The opaque type itself or its children are not within its reveal scope.
312- if it. owner_id . def_id != self . def_id {
313- self . check ( it. owner_id . def_id ) ;
314- intravisit:: walk_impl_item ( self , it) ;
315- }
283+ self . check ( it. owner_id . def_id ) ;
284+ intravisit:: walk_impl_item ( self , it) ;
316285 }
317286 fn visit_trait_item ( & mut self , it : & ' tcx TraitItem < ' tcx > ) {
318287 trace ! ( ?it. owner_id) ;
0 commit comments