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, Expr , ImplItem , Item , Node , TraitItem , def} ;
4+ use rustc_hir:: { self as hir, Expr , ImplItem , Item , Node , TraitItem , def, intravisit} ;
65use rustc_middle:: bug;
76use rustc_middle:: hir:: nested_filter;
87use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeVisitableExt } ;
98use rustc_span:: DUMMY_SP ;
109use tracing:: { debug, instrument, trace} ;
1110
12- use crate :: errors:: { TaitForwardCompat , TaitForwardCompat2 , UnconstrainedOpaqueType } ;
11+ use crate :: errors:: { TaitForwardCompat2 , UnconstrainedOpaqueType } ;
1312
1413/// Checks "defining uses" of opaque `impl Trait` in associated types.
1514/// These can only be defined by associated items of the same trait.
@@ -83,38 +82,9 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
8382/// ```
8483#[ instrument( skip( tcx) , level = "debug" ) ]
8584pub ( super ) fn find_opaque_ty_constraints_for_tait ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> Ty < ' _ > {
86- let hir_id = tcx. local_def_id_to_hir_id ( def_id) ;
87- let scope = tcx. hir ( ) . get_defining_scope ( hir_id) ;
8885 let mut locator = TaitConstraintLocator { def_id, tcx, found : None , typeck_types : vec ! [ ] } ;
8986
90- debug ! ( ?scope) ;
91-
92- if scope == hir:: CRATE_HIR_ID {
93- tcx. hir ( ) . walk_toplevel_module ( & mut locator) ;
94- } else {
95- trace ! ( "scope={:#?}" , tcx. hir_node( scope) ) ;
96- match tcx. hir_node ( scope) {
97- // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods
98- // This allows our visitor to process the defining item itself, causing
99- // it to pick up any 'sibling' defining uses.
100- //
101- // For example, this code:
102- // ```
103- // fn foo() {
104- // type Blah = impl Debug;
105- // let my_closure = || -> Blah { true };
106- // }
107- // ```
108- //
109- // requires us to explicitly process `foo()` in order
110- // to notice the defining usage of `Blah`.
111- Node :: Item ( it) => locator. visit_item ( it) ,
112- Node :: ImplItem ( it) => locator. visit_impl_item ( it) ,
113- Node :: TraitItem ( it) => locator. visit_trait_item ( it) ,
114- Node :: ForeignItem ( it) => locator. visit_foreign_item ( it) ,
115- other => bug ! ( "{:?} is not a valid scope for an opaque type item" , other) ,
116- }
117- }
87+ tcx. hir ( ) . walk_toplevel_module ( & mut locator) ;
11888
11989 if let Some ( hidden) = locator. found {
12090 // Only check against typeck if we didn't already error
@@ -138,12 +108,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
138108 let reported = tcx. dcx ( ) . emit_err ( UnconstrainedOpaqueType {
139109 span : tcx. def_span ( def_id) ,
140110 name : tcx. item_name ( parent_def_id. to_def_id ( ) ) ,
141- what : match tcx. hir_node ( scope) {
142- _ if scope == hir:: CRATE_HIR_ID => "module" ,
143- Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Mod ( _) , .. } ) => "module" ,
144- Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Impl ( _) , .. } ) => "impl" ,
145- _ => "item" ,
146- } ,
111+ what : "crate" ,
147112 } ) ;
148113 Ty :: new_error ( tcx, reported)
149114 }
@@ -177,6 +142,13 @@ impl TaitConstraintLocator<'_> {
177142 return ;
178143 }
179144
145+ let opaque_types_defined_by = self . tcx . opaque_types_defined_by ( item_def_id) ;
146+ // Don't try to check items that cannot possibly constrain the type.
147+ if !opaque_types_defined_by. contains ( & self . def_id ) {
148+ debug ! ( "no constraint: no opaque types defined" ) ;
149+ return ;
150+ }
151+
180152 // Function items with `_` in their return type already emit an error, skip any
181153 // "non-defining use" errors for them.
182154 // Note that we use `Node::fn_sig` instead of `Node::fn_decl` here, because the former
@@ -216,29 +188,13 @@ impl TaitConstraintLocator<'_> {
216188 return ;
217189 }
218190
219- let opaque_types_defined_by = self . tcx . opaque_types_defined_by ( item_def_id) ;
220-
221191 let mut constrained = false ;
222192 for ( & opaque_type_key, & hidden_type) in & tables. concrete_opaque_types {
223193 if opaque_type_key. def_id != self . def_id {
224194 continue ;
225195 }
226196 constrained = true ;
227197
228- if !opaque_types_defined_by. contains ( & self . def_id ) {
229- let guar = self . tcx . dcx ( ) . emit_err ( TaitForwardCompat {
230- span : hidden_type. span ,
231- item_span : self
232- . tcx
233- . def_ident_span ( item_def_id)
234- . unwrap_or_else ( || self . tcx . def_span ( item_def_id) ) ,
235- } ) ;
236- // Avoid "opaque type not constrained" errors on the opaque itself.
237- self . found = Some ( ty:: OpaqueHiddenType {
238- span : DUMMY_SP ,
239- ty : Ty :: new_error ( self . tcx , guar) ,
240- } ) ;
241- }
242198 let concrete_type =
243199 self . tcx . erase_regions ( hidden_type. remap_generic_params_to_declaration_params (
244200 opaque_type_key,
@@ -311,19 +267,13 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
311267 }
312268 fn visit_item ( & mut self , it : & ' tcx Item < ' tcx > ) {
313269 trace ! ( ?it. owner_id) ;
314- // The opaque type itself or its children are not within its reveal scope.
315- if it. owner_id . def_id != self . def_id {
316- self . check ( it. owner_id . def_id ) ;
317- intravisit:: walk_item ( self , it) ;
318- }
270+ self . check ( it. owner_id . def_id ) ;
271+ intravisit:: walk_item ( self , it) ;
319272 }
320273 fn visit_impl_item ( & mut self , it : & ' tcx ImplItem < ' tcx > ) {
321274 trace ! ( ?it. owner_id) ;
322- // The opaque type itself or its children are not within its reveal scope.
323- if it. owner_id . def_id != self . def_id {
324- self . check ( it. owner_id . def_id ) ;
325- intravisit:: walk_impl_item ( self , it) ;
326- }
275+ self . check ( it. owner_id . def_id ) ;
276+ intravisit:: walk_impl_item ( self , it) ;
327277 }
328278 fn visit_trait_item ( & mut self , it : & ' tcx TraitItem < ' tcx > ) {
329279 trace ! ( ?it. owner_id) ;
0 commit comments