@@ -13,32 +13,41 @@ use rustc_hir::def_id::{DefId, LocalDefId};
13
13
use rustc_middle:: ty:: fast_reject:: { simplify_type, SimplifiedType , TreatParams } ;
14
14
use rustc_middle:: ty:: { self , CrateInherentImpls , Ty , TyCtxt } ;
15
15
use rustc_span:: symbol:: sym;
16
+ use rustc_span:: ErrorGuaranteed ;
16
17
17
18
use crate :: errors;
18
19
19
20
/// On-demand query: yields a map containing all types mapped to their inherent impls.
20
- pub fn crate_inherent_impls ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> CrateInherentImpls {
21
+ pub fn crate_inherent_impls (
22
+ tcx : TyCtxt < ' _ > ,
23
+ ( ) : ( ) ,
24
+ ) -> Result < & ' _ CrateInherentImpls , ErrorGuaranteed > {
21
25
let mut collect = InherentCollect { tcx, impls_map : Default :: default ( ) } ;
26
+ let mut res = Ok ( ( ) ) ;
22
27
for id in tcx. hir ( ) . items ( ) {
23
- collect. check_item ( id) ;
28
+ res = res . and ( collect. check_item ( id) ) ;
24
29
}
25
- collect. impls_map
30
+ res?;
31
+ Ok ( tcx. arena . alloc ( collect. impls_map ) )
26
32
}
27
33
28
- pub fn crate_incoherent_impls ( tcx : TyCtxt < ' _ > , simp : SimplifiedType ) -> & [ DefId ] {
29
- let crate_map = tcx. crate_inherent_impls ( ( ) ) ;
30
- tcx. arena . alloc_from_iter (
34
+ pub fn crate_incoherent_impls (
35
+ tcx : TyCtxt < ' _ > ,
36
+ simp : SimplifiedType ,
37
+ ) -> Result < & [ DefId ] , ErrorGuaranteed > {
38
+ let crate_map = tcx. crate_inherent_impls ( ( ) ) ?;
39
+ Ok ( tcx. arena . alloc_from_iter (
31
40
crate_map. incoherent_impls . get ( & simp) . unwrap_or ( & Vec :: new ( ) ) . iter ( ) . map ( |d| d. to_def_id ( ) ) ,
32
- )
41
+ ) )
33
42
}
34
43
35
44
/// On-demand query: yields a vector of the inherent impls for a specific type.
36
- pub fn inherent_impls ( tcx : TyCtxt < ' _ > , ty_def_id : LocalDefId ) -> & [ DefId ] {
37
- let crate_map = tcx. crate_inherent_impls ( ( ) ) ;
38
- match crate_map. inherent_impls . get ( & ty_def_id) {
45
+ pub fn inherent_impls ( tcx : TyCtxt < ' _ > , ty_def_id : LocalDefId ) -> Result < & [ DefId ] , ErrorGuaranteed > {
46
+ let crate_map = tcx. crate_inherent_impls ( ( ) ) ? ;
47
+ Ok ( match crate_map. inherent_impls . get ( & ty_def_id) {
39
48
Some ( v) => & v[ ..] ,
40
49
None => & [ ] ,
41
- }
50
+ } )
42
51
}
43
52
44
53
struct InherentCollect < ' tcx > {
@@ -47,33 +56,36 @@ struct InherentCollect<'tcx> {
47
56
}
48
57
49
58
impl < ' tcx > InherentCollect < ' tcx > {
50
- fn check_def_id ( & mut self , impl_def_id : LocalDefId , self_ty : Ty < ' tcx > , ty_def_id : DefId ) {
59
+ fn check_def_id (
60
+ & mut self ,
61
+ impl_def_id : LocalDefId ,
62
+ self_ty : Ty < ' tcx > ,
63
+ ty_def_id : DefId ,
64
+ ) -> Result < ( ) , ErrorGuaranteed > {
51
65
if let Some ( ty_def_id) = ty_def_id. as_local ( ) {
52
66
// Add the implementation to the mapping from implementation to base
53
67
// type def ID, if there is a base type for this implementation and
54
68
// the implementation does not have any associated traits.
55
69
let vec = self . impls_map . inherent_impls . entry ( ty_def_id) . or_default ( ) ;
56
70
vec. push ( impl_def_id. to_def_id ( ) ) ;
57
- return ;
71
+ return Ok ( ( ) ) ;
58
72
}
59
73
60
74
if self . tcx . features ( ) . rustc_attrs {
61
75
let items = self . tcx . associated_item_def_ids ( impl_def_id) ;
62
76
63
77
if !self . tcx . has_attr ( ty_def_id, sym:: rustc_has_incoherent_inherent_impls) {
64
78
let impl_span = self . tcx . def_span ( impl_def_id) ;
65
- self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutside { span : impl_span } ) ;
66
- return ;
79
+ return Err ( self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutside { span : impl_span } ) ) ;
67
80
}
68
81
69
82
for & impl_item in items {
70
83
if !self . tcx . has_attr ( impl_item, sym:: rustc_allow_incoherent_impl) {
71
84
let impl_span = self . tcx . def_span ( impl_def_id) ;
72
- self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutsideRelevant {
85
+ return Err ( self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutsideRelevant {
73
86
span : impl_span,
74
87
help_span : self . tcx . def_span ( impl_item) ,
75
- } ) ;
76
- return ;
88
+ } ) ) ;
77
89
}
78
90
}
79
91
@@ -82,24 +94,28 @@ impl<'tcx> InherentCollect<'tcx> {
82
94
} else {
83
95
bug ! ( "unexpected self type: {:?}" , self_ty) ;
84
96
}
97
+ Ok ( ( ) )
85
98
} else {
86
99
let impl_span = self . tcx . def_span ( impl_def_id) ;
87
- self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutsideNew { span : impl_span } ) ;
100
+ Err ( self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutsideNew { span : impl_span } ) )
88
101
}
89
102
}
90
103
91
- fn check_primitive_impl ( & mut self , impl_def_id : LocalDefId , ty : Ty < ' tcx > ) {
104
+ fn check_primitive_impl (
105
+ & mut self ,
106
+ impl_def_id : LocalDefId ,
107
+ ty : Ty < ' tcx > ,
108
+ ) -> Result < ( ) , ErrorGuaranteed > {
92
109
let items = self . tcx . associated_item_def_ids ( impl_def_id) ;
93
110
if !self . tcx . hir ( ) . rustc_coherence_is_core ( ) {
94
111
if self . tcx . features ( ) . rustc_attrs {
95
112
for & impl_item in items {
96
113
if !self . tcx . has_attr ( impl_item, sym:: rustc_allow_incoherent_impl) {
97
114
let span = self . tcx . def_span ( impl_def_id) ;
98
- self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutsidePrimitive {
115
+ return Err ( self . tcx . dcx ( ) . emit_err ( errors:: InherentTyOutsidePrimitive {
99
116
span,
100
117
help_span : self . tcx . def_span ( impl_item) ,
101
- } ) ;
102
- return ;
118
+ } ) ) ;
103
119
}
104
120
}
105
121
} else {
@@ -108,8 +124,7 @@ impl<'tcx> InherentCollect<'tcx> {
108
124
if let ty:: Ref ( _, subty, _) = ty. kind ( ) {
109
125
note = Some ( errors:: InherentPrimitiveTyNote { subty : * subty } ) ;
110
126
}
111
- self . tcx . dcx ( ) . emit_err ( errors:: InherentPrimitiveTy { span, note } ) ;
112
- return ;
127
+ return Err ( self . tcx . dcx ( ) . emit_err ( errors:: InherentPrimitiveTy { span, note } ) ) ;
113
128
}
114
129
}
115
130
@@ -118,11 +133,12 @@ impl<'tcx> InherentCollect<'tcx> {
118
133
} else {
119
134
bug ! ( "unexpected primitive type: {:?}" , ty) ;
120
135
}
136
+ Ok ( ( ) )
121
137
}
122
138
123
- fn check_item ( & mut self , id : hir:: ItemId ) {
139
+ fn check_item ( & mut self , id : hir:: ItemId ) -> Result < ( ) , ErrorGuaranteed > {
124
140
if !matches ! ( self . tcx. def_kind( id. owner_id) , DefKind :: Impl { of_trait: false } ) {
125
- return ;
141
+ return Ok ( ( ) ) ;
126
142
}
127
143
128
144
let id = id. owner_id . def_id ;
@@ -132,10 +148,10 @@ impl<'tcx> InherentCollect<'tcx> {
132
148
ty:: Adt ( def, _) => self . check_def_id ( id, self_ty, def. did ( ) ) ,
133
149
ty:: Foreign ( did) => self . check_def_id ( id, self_ty, did) ,
134
150
ty:: Dynamic ( data, ..) if data. principal_def_id ( ) . is_some ( ) => {
135
- self . check_def_id ( id, self_ty, data. principal_def_id ( ) . unwrap ( ) ) ;
151
+ self . check_def_id ( id, self_ty, data. principal_def_id ( ) . unwrap ( ) )
136
152
}
137
153
ty:: Dynamic ( ..) => {
138
- self . tcx . dcx ( ) . emit_err ( errors:: InherentDyn { span : item_span } ) ;
154
+ Err ( self . tcx . dcx ( ) . emit_err ( errors:: InherentDyn { span : item_span } ) )
139
155
}
140
156
ty:: Bool
141
157
| ty:: Char
@@ -151,7 +167,7 @@ impl<'tcx> InherentCollect<'tcx> {
151
167
| ty:: FnPtr ( _)
152
168
| ty:: Tuple ( ..) => self . check_primitive_impl ( id, self_ty) ,
153
169
ty:: Alias ( ..) | ty:: Param ( _) => {
154
- self . tcx . dcx ( ) . emit_err ( errors:: InherentNominal { span : item_span } ) ;
170
+ Err ( self . tcx . dcx ( ) . emit_err ( errors:: InherentNominal { span : item_span } ) )
155
171
}
156
172
ty:: FnDef ( ..)
157
173
| ty:: Closure ( ..)
@@ -162,7 +178,8 @@ impl<'tcx> InherentCollect<'tcx> {
162
178
| ty:: Infer ( _) => {
163
179
bug ! ( "unexpected impl self type of impl: {:?} {:?}" , id, self_ty) ;
164
180
}
165
- ty:: Error ( _) => { }
181
+ // We could bail out here, but that will silence other useful errors.
182
+ ty:: Error ( _) => Ok ( ( ) ) ,
166
183
}
167
184
}
168
185
}
0 commit comments