@@ -18,7 +18,11 @@ use std::borrow::Cow;
1818
1919type McfResult = Result < ( ) , ( Span , Cow < ' static , str > ) > ;
2020
21- pub fn is_min_const_fn < ' a , ' tcx > ( tcx : TyCtxt < ' tcx > , body : & ' a Body < ' tcx > , msrv : Option < RustcVersion > ) -> McfResult {
21+ pub fn is_min_const_fn < ' a , ' tcx > (
22+ tcx : TyCtxt < ' tcx > ,
23+ body : & ' a Body < ' tcx > ,
24+ msrv : Option < RustcVersion > ,
25+ ) -> McfResult {
2226 let def_id = body. source . def_id ( ) ;
2327 let mut current = def_id;
2428 loop {
@@ -33,10 +37,18 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv:
3337 | ty:: PredicateKind :: ConstEquate ( ..)
3438 | ty:: PredicateKind :: Trait ( ..)
3539 | ty:: PredicateKind :: TypeWellFormedFromEnv ( ..) => continue ,
36- ty:: PredicateKind :: ObjectSafe ( _) => panic ! ( "object safe predicate on function: {:#?}" , predicate) ,
37- ty:: PredicateKind :: ClosureKind ( ..) => panic ! ( "closure kind predicate on function: {:#?}" , predicate) ,
38- ty:: PredicateKind :: Subtype ( _) => panic ! ( "subtype predicate on function: {:#?}" , predicate) ,
39- ty:: PredicateKind :: Coerce ( _) => panic ! ( "coerce predicate on function: {:#?}" , predicate) ,
40+ ty:: PredicateKind :: ObjectSafe ( _) => {
41+ panic ! ( "object safe predicate on function: {:#?}" , predicate)
42+ }
43+ ty:: PredicateKind :: ClosureKind ( ..) => {
44+ panic ! ( "closure kind predicate on function: {:#?}" , predicate)
45+ }
46+ ty:: PredicateKind :: Subtype ( _) => {
47+ panic ! ( "subtype predicate on function: {:#?}" , predicate)
48+ }
49+ ty:: PredicateKind :: Coerce ( _) => {
50+ panic ! ( "coerce predicate on function: {:#?}" , predicate)
51+ }
4052 }
4153 }
4254 match predicates. parent {
@@ -77,22 +89,23 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
7789 match ty. kind ( ) {
7890 ty:: Ref ( _, _, hir:: Mutability :: Mut ) => {
7991 return Err ( ( span, "mutable references in const fn are unstable" . into ( ) ) ) ;
80- } ,
92+ }
8193 ty:: Opaque ( ..) => return Err ( ( span, "`impl Trait` in const fn is unstable" . into ( ) ) ) ,
8294 ty:: FnPtr ( ..) => {
8395 return Err ( ( span, "function pointers in const fn are unstable" . into ( ) ) ) ;
84- } ,
85- ty:: Dynamic ( preds, _) => {
96+ }
97+ ty:: Dynamic ( preds, _, _ ) => {
8698 for pred in preds. iter ( ) {
8799 match pred. skip_binder ( ) {
88- ty:: ExistentialPredicate :: AutoTrait ( _) | ty:: ExistentialPredicate :: Projection ( _) => {
100+ ty:: ExistentialPredicate :: AutoTrait ( _)
101+ | ty:: ExistentialPredicate :: Projection ( _) => {
89102 return Err ( (
90103 span,
91104 "trait bounds other than `Sized` \
92105 on const fn parameters are unstable"
93106 . into ( ) ,
94107 ) ) ;
95- } ,
108+ }
96109 ty:: ExistentialPredicate :: Trait ( trait_ref) => {
97110 if Some ( trait_ref. def_id ) != tcx. lang_items ( ) . sized_trait ( ) {
98111 return Err ( (
@@ -102,11 +115,11 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
102115 . into ( ) ,
103116 ) ) ;
104117 }
105- } ,
118+ }
106119 }
107120 }
108- } ,
109- _ => { } ,
121+ }
122+ _ => { }
110123 }
111124 }
112125 Ok ( ( ) )
@@ -120,10 +133,13 @@ fn check_rvalue<'tcx>(
120133 span : Span ,
121134) -> McfResult {
122135 match rvalue {
123- Rvalue :: ThreadLocalRef ( _) => Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) ) ,
124- Rvalue :: Len ( place) | Rvalue :: Discriminant ( place) | Rvalue :: Ref ( _, _, place) | Rvalue :: AddressOf ( _, place) => {
125- check_place ( tcx, * place, span, body)
126- } ,
136+ Rvalue :: ThreadLocalRef ( _) => {
137+ Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) )
138+ }
139+ Rvalue :: Len ( place)
140+ | Rvalue :: Discriminant ( place)
141+ | Rvalue :: Ref ( _, _, place)
142+ | Rvalue :: AddressOf ( _, place) => check_place ( tcx, * place, span, body) ,
127143 Rvalue :: CopyForDeref ( place) => check_place ( tcx, * place, span, body) ,
128144 Rvalue :: Repeat ( operand, _)
129145 | Rvalue :: Use ( operand)
@@ -136,7 +152,9 @@ fn check_rvalue<'tcx>(
136152 ) => check_operand ( tcx, operand, span, body) ,
137153 Rvalue :: Cast (
138154 CastKind :: Pointer (
139- PointerCast :: UnsafeFnPointer | PointerCast :: ClosureFnPointer ( _) | PointerCast :: ReifyFnPointer ,
155+ PointerCast :: UnsafeFnPointer
156+ | PointerCast :: ClosureFnPointer ( _)
157+ | PointerCast :: ReifyFnPointer ,
140158 ) ,
141159 _,
142160 _,
@@ -146,7 +164,10 @@ fn check_rvalue<'tcx>(
146164 deref_ty. ty
147165 } else {
148166 // We cannot allow this for now.
149- return Err ( ( span, "unsizing casts are only allowed for references right now" . into ( ) ) ) ;
167+ return Err ( (
168+ span,
169+ "unsizing casts are only allowed for references right now" . into ( ) ,
170+ ) ) ;
150171 } ;
151172 let unsized_ty = tcx. struct_tail_erasing_lifetimes ( pointee_ty, tcx. param_env ( def_id) ) ;
152173 if let ty:: Slice ( _) | ty:: Str = unsized_ty. kind ( ) {
@@ -157,10 +178,14 @@ fn check_rvalue<'tcx>(
157178 // We just can't allow trait objects until we have figured out trait method calls.
158179 Err ( ( span, "unsizing casts are not allowed in const fn" . into ( ) ) )
159180 }
160- } ,
181+ }
161182 Rvalue :: Cast ( CastKind :: PointerExposeAddress , _, _) => {
162183 Err ( ( span, "casting pointers to ints is unstable in const fn" . into ( ) ) )
163- } ,
184+ }
185+ Rvalue :: Cast ( CastKind :: DynStar , _, _) => {
186+ // FIXME(dyn-star)
187+ unimplemented ! ( )
188+ }
164189 // binops are fine on integers
165190 Rvalue :: BinaryOp ( _, box ( lhs, rhs) ) | Rvalue :: CheckedBinaryOp ( _, box ( lhs, rhs) ) => {
166191 check_operand ( tcx, lhs, span, body) ?;
@@ -169,27 +194,26 @@ fn check_rvalue<'tcx>(
169194 if ty. is_integral ( ) || ty. is_bool ( ) || ty. is_char ( ) {
170195 Ok ( ( ) )
171196 } else {
172- Err ( (
173- span,
174- "only int, `bool` and `char` operations are stable in const fn" . into ( ) ,
175- ) )
197+ Err ( ( span, "only int, `bool` and `char` operations are stable in const fn" . into ( ) ) )
176198 }
177- } ,
178- Rvalue :: NullaryOp ( NullOp :: SizeOf | NullOp :: AlignOf , _) | Rvalue :: ShallowInitBox ( _, _) => Ok ( ( ) ) ,
199+ }
200+ Rvalue :: NullaryOp ( NullOp :: SizeOf | NullOp :: AlignOf , _) | Rvalue :: ShallowInitBox ( _, _) => {
201+ Ok ( ( ) )
202+ }
179203 Rvalue :: UnaryOp ( _, operand) => {
180204 let ty = operand. ty ( body, tcx) ;
181205 if ty. is_integral ( ) || ty. is_bool ( ) {
182206 check_operand ( tcx, operand, span, body)
183207 } else {
184208 Err ( ( span, "only int and `bool` operations are stable in const fn" . into ( ) ) )
185209 }
186- } ,
210+ }
187211 Rvalue :: Aggregate ( _, operands) => {
188212 for operand in operands {
189213 check_operand ( tcx, operand, span, body) ?;
190214 }
191215 Ok ( ( ) )
192- } ,
216+ }
193217 }
194218}
195219
@@ -204,7 +228,7 @@ fn check_statement<'tcx>(
204228 StatementKind :: Assign ( box ( place, rval) ) => {
205229 check_place ( tcx, * place, span, body) ?;
206230 check_rvalue ( tcx, body, def_id, rval, span)
207- } ,
231+ }
208232
209233 StatementKind :: FakeRead ( box ( _, place) ) => check_place ( tcx, * place, span, body) ,
210234 // just an assignment
@@ -214,14 +238,15 @@ fn check_statement<'tcx>(
214238
215239 StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: Assume ( op) ) => check_operand ( tcx, op, span, body) ,
216240
217- StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: CopyNonOverlapping (
218- rustc_middle:: mir:: CopyNonOverlapping { dst, src, count } ,
219- ) ) => {
241+ StatementKind :: CopyNonOverlapping ( box rustc_middle:: mir:: CopyNonOverlapping {
242+ dst,
243+ src,
244+ count,
245+ } ) => {
220246 check_operand ( tcx, dst, span, body) ?;
221247 check_operand ( tcx, src, span, body) ?;
222248 check_operand ( tcx, count, span, body)
223- } ,
224-
249+ }
225250 // These are all NOPs
226251 StatementKind :: StorageLive ( _)
227252 | StatementKind :: StorageDead ( _)
@@ -232,7 +257,12 @@ fn check_statement<'tcx>(
232257 }
233258}
234259
235- fn check_operand < ' tcx > ( tcx : TyCtxt < ' tcx > , operand : & Operand < ' tcx > , span : Span , body : & Body < ' tcx > ) -> McfResult {
260+ fn check_operand < ' tcx > (
261+ tcx : TyCtxt < ' tcx > ,
262+ operand : & Operand < ' tcx > ,
263+ span : Span ,
264+ body : & Body < ' tcx > ,
265+ ) -> McfResult {
236266 match operand {
237267 Operand :: Move ( place) | Operand :: Copy ( place) => check_place ( tcx, * place, span, body) ,
238268 Operand :: Constant ( c) => match c. check_static_ptr ( tcx) {
@@ -242,7 +272,12 @@ fn check_operand<'tcx>(tcx: TyCtxt<'tcx>, operand: &Operand<'tcx>, span: Span, b
242272 }
243273}
244274
245- fn check_place < ' tcx > ( tcx : TyCtxt < ' tcx > , place : Place < ' tcx > , span : Span , body : & Body < ' tcx > ) -> McfResult {
275+ fn check_place < ' tcx > (
276+ tcx : TyCtxt < ' tcx > ,
277+ place : Place < ' tcx > ,
278+ span : Span ,
279+ body : & Body < ' tcx > ,
280+ ) -> McfResult {
246281 let mut cursor = place. projection . as_ref ( ) ;
247282 while let [ ref proj_base @ .., elem] = * cursor {
248283 cursor = proj_base;
@@ -255,12 +290,12 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
255290 return Err ( ( span, "accessing union fields is unstable" . into ( ) ) ) ;
256291 }
257292 }
258- } ,
293+ }
259294 ProjectionElem :: ConstantIndex { .. }
260295 | ProjectionElem :: Downcast ( ..)
261296 | ProjectionElem :: Subslice { .. }
262297 | ProjectionElem :: Deref
263- | ProjectionElem :: Index ( _) => { } ,
298+ | ProjectionElem :: Index ( _) => { }
264299 }
265300 }
266301
@@ -286,18 +321,16 @@ fn check_terminator<'a, 'tcx>(
286321 TerminatorKind :: DropAndReplace { place, value, .. } => {
287322 check_place ( tcx, * place, span, body) ?;
288323 check_operand ( tcx, value, span, body)
289- } ,
324+ }
290325
291- TerminatorKind :: SwitchInt {
292- discr,
293- switch_ty : _,
294- targets : _,
295- } => check_operand ( tcx, discr, span, body) ,
326+ TerminatorKind :: SwitchInt { discr, switch_ty : _, targets : _ } => {
327+ check_operand ( tcx, discr, span, body)
328+ }
296329
297330 TerminatorKind :: Abort => Err ( ( span, "abort is not stable in const fn" . into ( ) ) ) ,
298331 TerminatorKind :: GeneratorDrop | TerminatorKind :: Yield { .. } => {
299332 Err ( ( span, "const fn generators are unstable" . into ( ) ) )
300- } ,
333+ }
301334
302335 TerminatorKind :: Call {
303336 func,
@@ -342,17 +375,15 @@ fn check_terminator<'a, 'tcx>(
342375 } else {
343376 Err ( ( span, "can only call other const fns within const fn" . into ( ) ) )
344377 }
345- } ,
378+ }
346379
347- TerminatorKind :: Assert {
348- cond,
349- expected : _,
350- msg : _,
351- target : _,
352- cleanup : _,
353- } => check_operand ( tcx, cond, span, body) ,
380+ TerminatorKind :: Assert { cond, expected : _, msg : _, target : _, cleanup : _ } => {
381+ check_operand ( tcx, cond, span, body)
382+ }
354383
355- TerminatorKind :: InlineAsm { .. } => Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) ) ,
384+ TerminatorKind :: InlineAsm { .. } => {
385+ Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) )
386+ }
356387 }
357388}
358389
0 commit comments