Skip to content

Commit 710270d

Browse files
committed
Add feature-gate to calling const fn
1 parent 3a433b9 commit 710270d

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

src/librustc/middle/check_const.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,23 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
199199
}
200200

201201
/// Returns true if the call is to a const fn or method.
202-
fn handle_const_fn_call(&mut self, def_id: ast::DefId, ret_ty: Ty<'tcx>) -> bool {
202+
fn handle_const_fn_call(&mut self,
203+
expr: &ast::Expr,
204+
def_id: ast::DefId,
205+
ret_ty: Ty<'tcx>)
206+
-> bool {
203207
if let Some(fn_like) = const_eval::lookup_const_fn_by_id(self.tcx, def_id) {
208+
if self.mode != Mode::Var && !self.tcx.sess.features.borrow().const_fn {
209+
self.tcx.sess.span_err(
210+
expr.span,
211+
&format!("const fns are an unstable feature"));
212+
fileline_help!(
213+
self.tcx.sess,
214+
expr.span,
215+
"in Nightly builds, add `#![feature(const_fn)]` to the crate \
216+
attributes to enable");
217+
}
218+
204219
let qualif = self.fn_like(fn_like.kind(),
205220
fn_like.decl(),
206221
fn_like.body(),
@@ -657,7 +672,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
657672
}
658673
Some(def::DefMethod(did, def::FromImpl(_))) |
659674
Some(def::DefFn(did, _)) => {
660-
v.handle_const_fn_call(did, node_ty)
675+
v.handle_const_fn_call(e, did, node_ty)
661676
}
662677
_ => false
663678
};
@@ -677,7 +692,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
677692
_ => None
678693
};
679694
let is_const = match method_did {
680-
Some(did) => v.handle_const_fn_call(did, node_ty),
695+
Some(did) => v.handle_const_fn_call(e, did, node_ty),
681696
None => false
682697
};
683698
if !is_const {

src/libsyntax/feature_gate.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,8 @@ pub struct Features {
332332
/// spans of #![feature] attrs for stable language features. for error reporting
333333
pub declared_stable_lang_features: Vec<Span>,
334334
/// #![feature] attrs for non-language (library) features
335-
pub declared_lib_features: Vec<(InternedString, Span)>
335+
pub declared_lib_features: Vec<(InternedString, Span)>,
336+
pub const_fn: bool,
336337
}
337338

338339
impl Features {
@@ -352,7 +353,8 @@ impl Features {
352353
unmarked_api: false,
353354
negate_unsigned: false,
354355
declared_stable_lang_features: Vec::new(),
355-
declared_lib_features: Vec::new()
356+
declared_lib_features: Vec::new(),
357+
const_fn: false,
356358
}
357359
}
358360
}
@@ -802,7 +804,8 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
802804
unmarked_api: cx.has_feature("unmarked_api"),
803805
negate_unsigned: cx.has_feature("negate_unsigned"),
804806
declared_stable_lang_features: accepted_features,
805-
declared_lib_features: unknown_features
807+
declared_lib_features: unknown_features,
808+
const_fn: cx.has_feature("const_fn"),
806809
}
807810
}
808811

src/test/compile-fail/const-fn-stability.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@ impl Foo for u32 {
2525
const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable
2626
}
2727

28-
fn main() { }
28+
static FOO: usize = foo();
29+
const BAR: usize = foo();
30+
31+
fn main() {
32+
let x: [usize; foo()] = [];
33+
}

0 commit comments

Comments
 (0)