@@ -38,6 +38,7 @@ use rustc::util::nodemap::{ItemLocalSet, NodeSet};
38
38
use rustc:: hir;
39
39
use rustc_data_structures:: sync:: Lrc ;
40
40
use syntax:: ast;
41
+ use syntax:: attr;
41
42
use syntax_pos:: { Span , DUMMY_SP } ;
42
43
use rustc:: hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
43
44
@@ -119,7 +120,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
119
120
!ty. needs_drop ( self . tcx , self . param_env )
120
121
}
121
122
122
- fn handle_const_fn_call ( & mut self , def_id : DefId , ret_ty : Ty < ' gcx > ) {
123
+ fn handle_const_fn_call ( & mut self , def_id : DefId , ret_ty : Ty < ' gcx > , span : Span ) {
123
124
self . promotable &= self . type_has_only_promotable_values ( ret_ty) ;
124
125
125
126
self . promotable &= if let Some ( fn_id) = self . tcx . hir . as_local_node_id ( def_id) {
@@ -129,6 +130,25 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
129
130
} else {
130
131
self . tcx . is_const_fn ( def_id)
131
132
} ;
133
+
134
+ if let Some ( & attr:: Stability {
135
+ rustc_const_unstable : Some ( attr:: RustcConstUnstable {
136
+ feature : ref feature_name
137
+ } ) ,
138
+ .. } ) = self . tcx . lookup_stability ( def_id) {
139
+ self . promotable &=
140
+ // feature-gate is enabled,
141
+ self . tcx . features ( )
142
+ . declared_lib_features
143
+ . iter ( )
144
+ . any ( |& ( ref sym, _) | sym == feature_name) ||
145
+
146
+ // this comes from a crate with the feature-gate enabled,
147
+ !def_id. is_local ( ) ||
148
+
149
+ // this comes from a macro that has #[allow_internal_unstable]
150
+ span. allows_unstable ( ) ;
151
+ }
132
152
}
133
153
}
134
154
@@ -359,12 +379,12 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
359
379
Def :: StructCtor ( _, CtorKind :: Fn ) |
360
380
Def :: VariantCtor ( _, CtorKind :: Fn ) => { }
361
381
Def :: Fn ( did) => {
362
- v. handle_const_fn_call ( did, node_ty)
382
+ v. handle_const_fn_call ( did, node_ty, e . span )
363
383
}
364
384
Def :: Method ( did) => {
365
385
match v. tcx . associated_item ( did) . container {
366
386
ty:: ImplContainer ( _) => {
367
- v. handle_const_fn_call ( did, node_ty)
387
+ v. handle_const_fn_call ( did, node_ty, e . span )
368
388
}
369
389
ty:: TraitContainer ( _) => v. promotable = false
370
390
}
@@ -376,7 +396,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
376
396
if let Some ( def) = v. tables . type_dependent_defs ( ) . get ( e. hir_id ) {
377
397
let def_id = def. def_id ( ) ;
378
398
match v. tcx . associated_item ( def_id) . container {
379
- ty:: ImplContainer ( _) => v. handle_const_fn_call ( def_id, node_ty) ,
399
+ ty:: ImplContainer ( _) => v. handle_const_fn_call ( def_id, node_ty, e . span ) ,
380
400
ty:: TraitContainer ( _) => v. promotable = false
381
401
}
382
402
} else {
0 commit comments