99
1010use rustc_errors:: struct_span_err;
1111use rustc_hir as hir;
12+ use rustc_hir:: def:: DefKind ;
1213use rustc_hir:: def_id:: { CrateNum , DefId , LocalDefId } ;
13- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
1414use rustc_middle:: ty:: fast_reject:: { simplify_type, SimplifiedType , TreatParams } ;
1515use rustc_middle:: ty:: { self , CrateInherentImpls , Ty , TyCtxt } ;
1616use rustc_span:: symbol:: sym;
@@ -19,7 +19,9 @@ use rustc_span::Span;
1919/// On-demand query: yields a map containing all types mapped to their inherent impls.
2020pub fn crate_inherent_impls ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> CrateInherentImpls {
2121 let mut collect = InherentCollect { tcx, impls_map : Default :: default ( ) } ;
22- tcx. hir ( ) . visit_all_item_likes ( & mut collect) ;
22+ for id in tcx. hir ( ) . items ( ) {
23+ collect. check_item ( id) ;
24+ }
2325 collect. impls_map
2426}
2527
@@ -46,79 +48,6 @@ struct InherentCollect<'tcx> {
4648 impls_map : CrateInherentImpls ,
4749}
4850
49- impl < ' tcx > ItemLikeVisitor < ' _ > for InherentCollect < ' tcx > {
50- fn visit_item ( & mut self , item : & hir:: Item < ' _ > ) {
51- let hir:: ItemKind :: Impl ( hir:: Impl { of_trait : None , self_ty : ty, ref items, .. } ) = item. kind else {
52- return ;
53- } ;
54-
55- let self_ty = self . tcx . type_of ( item. def_id ) ;
56- match * self_ty. kind ( ) {
57- ty:: Adt ( def, _) => {
58- self . check_def_id ( item, self_ty, def. did ( ) ) ;
59- }
60- ty:: Foreign ( did) => {
61- self . check_def_id ( item, self_ty, did) ;
62- }
63- ty:: Dynamic ( data, ..) if data. principal_def_id ( ) . is_some ( ) => {
64- self . check_def_id ( item, self_ty, data. principal_def_id ( ) . unwrap ( ) ) ;
65- }
66- ty:: Dynamic ( ..) => {
67- struct_span_err ! (
68- self . tcx. sess,
69- ty. span,
70- E0785 ,
71- "cannot define inherent `impl` for a dyn auto trait"
72- )
73- . span_label ( ty. span , "impl requires at least one non-auto trait" )
74- . note ( "define and implement a new trait or type instead" )
75- . emit ( ) ;
76- }
77- ty:: Bool
78- | ty:: Char
79- | ty:: Int ( _)
80- | ty:: Uint ( _)
81- | ty:: Float ( _)
82- | ty:: Str
83- | ty:: Array ( ..)
84- | ty:: Slice ( _)
85- | ty:: RawPtr ( _)
86- | ty:: Ref ( ..)
87- | ty:: Never
88- | ty:: Tuple ( ..) => self . check_primitive_impl ( item. def_id , self_ty, items, ty. span ) ,
89- ty:: FnPtr ( _) | ty:: Projection ( ..) | ty:: Opaque ( ..) | ty:: Param ( _) => {
90- let mut err = struct_span_err ! (
91- self . tcx. sess,
92- ty. span,
93- E0118 ,
94- "no nominal type found for inherent implementation"
95- ) ;
96-
97- err. span_label ( ty. span , "impl requires a nominal type" )
98- . note ( "either implement a trait on it or create a newtype to wrap it instead" ) ;
99-
100- err. emit ( ) ;
101- }
102- ty:: FnDef ( ..)
103- | ty:: Closure ( ..)
104- | ty:: Generator ( ..)
105- | ty:: GeneratorWitness ( ..)
106- | ty:: Bound ( ..)
107- | ty:: Placeholder ( _)
108- | ty:: Infer ( _) => {
109- bug ! ( "unexpected impl self type of impl: {:?} {:?}" , item. def_id, self_ty) ;
110- }
111- ty:: Error ( _) => { }
112- }
113- }
114-
115- fn visit_trait_item ( & mut self , _trait_item : & hir:: TraitItem < ' _ > ) { }
116-
117- fn visit_impl_item ( & mut self , _impl_item : & hir:: ImplItem < ' _ > ) { }
118-
119- fn visit_foreign_item ( & mut self , _foreign_item : & hir:: ForeignItem < ' _ > ) { }
120- }
121-
12251const INTO_CORE : & str = "consider moving this inherent impl into `core` if possible" ;
12352const INTO_DEFINING_CRATE : & str =
12453 "consider moving this inherent impl into the crate defining the type if possible" ;
@@ -246,4 +175,74 @@ impl<'tcx> InherentCollect<'tcx> {
246175 bug ! ( "unexpected primitive type: {:?}" , ty) ;
247176 }
248177 }
178+
179+ fn check_item ( & mut self , id : hir:: ItemId ) {
180+ if !matches ! ( self . tcx. hir( ) . def_kind( id. def_id) , DefKind :: Impl ) {
181+ return ;
182+ }
183+
184+ let item = self . tcx . hir ( ) . item ( id) ;
185+ let hir:: ItemKind :: Impl ( hir:: Impl { of_trait : None , self_ty : ty, ref items, .. } ) = item. kind else {
186+ return ;
187+ } ;
188+
189+ let self_ty = self . tcx . type_of ( item. def_id ) ;
190+ match * self_ty. kind ( ) {
191+ ty:: Adt ( def, _) => {
192+ self . check_def_id ( item, self_ty, def. did ( ) ) ;
193+ }
194+ ty:: Foreign ( did) => {
195+ self . check_def_id ( item, self_ty, did) ;
196+ }
197+ ty:: Dynamic ( data, ..) if data. principal_def_id ( ) . is_some ( ) => {
198+ self . check_def_id ( item, self_ty, data. principal_def_id ( ) . unwrap ( ) ) ;
199+ }
200+ ty:: Dynamic ( ..) => {
201+ struct_span_err ! (
202+ self . tcx. sess,
203+ ty. span,
204+ E0785 ,
205+ "cannot define inherent `impl` for a dyn auto trait"
206+ )
207+ . span_label ( ty. span , "impl requires at least one non-auto trait" )
208+ . note ( "define and implement a new trait or type instead" )
209+ . emit ( ) ;
210+ }
211+ ty:: Bool
212+ | ty:: Char
213+ | ty:: Int ( _)
214+ | ty:: Uint ( _)
215+ | ty:: Float ( _)
216+ | ty:: Str
217+ | ty:: Array ( ..)
218+ | ty:: Slice ( _)
219+ | ty:: RawPtr ( _)
220+ | ty:: Ref ( ..)
221+ | ty:: Never
222+ | ty:: Tuple ( ..) => self . check_primitive_impl ( item. def_id , self_ty, items, ty. span ) ,
223+ ty:: FnPtr ( _) | ty:: Projection ( ..) | ty:: Opaque ( ..) | ty:: Param ( _) => {
224+ let mut err = struct_span_err ! (
225+ self . tcx. sess,
226+ ty. span,
227+ E0118 ,
228+ "no nominal type found for inherent implementation"
229+ ) ;
230+
231+ err. span_label ( ty. span , "impl requires a nominal type" )
232+ . note ( "either implement a trait on it or create a newtype to wrap it instead" ) ;
233+
234+ err. emit ( ) ;
235+ }
236+ ty:: FnDef ( ..)
237+ | ty:: Closure ( ..)
238+ | ty:: Generator ( ..)
239+ | ty:: GeneratorWitness ( ..)
240+ | ty:: Bound ( ..)
241+ | ty:: Placeholder ( _)
242+ | ty:: Infer ( _) => {
243+ bug ! ( "unexpected impl self type of impl: {:?} {:?}" , item. def_id, self_ty) ;
244+ }
245+ ty:: Error ( _) => { }
246+ }
247+ }
249248}
0 commit comments