Skip to content

Commit 27dfd33

Browse files
committed
Make various fixes:
- add feature gate - add basic tests - adjust parser to eliminate conflict between `const fn` and associated constants - allow `const fn` in traits/trait-impls, but forbid later in type check - correct some merge conflicts
1 parent 8b5699b commit 27dfd33

37 files changed

+326
-108
lines changed

src/librustc/diagnostics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -846,5 +846,6 @@ register_diagnostics! {
846846
E0314, // closure outlives stack frame
847847
E0315, // cannot invoke closure outside of its lifetime
848848
E0316, // nested quantification of lifetimes
849-
E0370 // discriminant overflow
849+
E0370, // discriminant overflow
850+
E0378 // method calls limited to constant inherent methods
850851
}

src/librustc/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// TODO list:
12+
// 1. Check that const fns cannot be defined in a trait or trait impl.
13+
// (This used to be enforced in the parser.) Make sure there are test cases.
14+
1115
//! The Rust compiler.
1216
//!
1317
//! # Note

src/librustc/metadata/encoder.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -879,12 +879,11 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
879879
let any_types = !scheme.generics.types.is_empty();
880880
let needs_inline = any_types || is_default_impl ||
881881
attr::requests_inline(&impl_item.attrs);
882-
let constness = ast_method.pe_constness();
883-
if needs_inline || constness == ast::Constness::Const {
882+
if needs_inline || sig.constness == ast::Constness::Const {
884883
encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id),
885884
impl_item));
886885
}
887-
encode_constness(rbml_w, constness);
886+
encode_constness(rbml_w, sig.constness);
888887
if !any_types {
889888
encode_symbol(ecx, rbml_w, m.def_id.node);
890889
}

src/librustc/middle/check_const.rs

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use util::nodemap::NodeMap;
3535
use util::ppaux;
3636

3737
use syntax::ast;
38-
use syntax::ast_util::PostExpansionMethod;
3938
use syntax::codemap::Span;
4039
use syntax::print::pprust;
4140
use syntax::visit::{self, Visitor};
@@ -149,16 +148,16 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
149148
Entry::Occupied(entry) => return *entry.get(),
150149
Entry::Vacant(entry) => {
151150
// Prevent infinite recursion on re-entry.
152-
entry.insert(PURE_CONST);
151+
entry.insert(ConstQualif::empty());
153152
}
154153
}
155154

156155
let mode = match fk {
157-
visit::FkItemFn(_, _, _, ast::Constness::Const, _) => {
156+
visit::FkItemFn(_, _, _, ast::Constness::Const, _, _) => {
158157
Mode::ConstFn
159158
}
160-
visit::FkMethod(_, _, m) => {
161-
if m.pe_constness() == ast::Constness::Const {
159+
visit::FkMethod(_, m, _) => {
160+
if m.constness == ast::Constness::Const {
162161
Mode::ConstFn
163162
} else {
164163
Mode::Var
@@ -189,7 +188,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
189188

190189
// Keep only bits that aren't affected by function body (NON_ZERO_SIZED),
191190
// and bits that don't change semantics, just optimizations (PREFER_IN_PLACE).
192-
let qualif = qualif & (NON_ZERO_SIZED | PREFER_IN_PLACE);
191+
let qualif = qualif & (ConstQualif::NON_ZERO_SIZED | ConstQualif::PREFER_IN_PLACE);
193192

194193
self.tcx.const_qualif_map.borrow_mut().insert(fn_id, qualif);
195194
qualif
@@ -210,7 +209,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
210209
self.add_qualif(qualif);
211210

212211
if ty::type_contents(self.tcx, ret_ty).interior_unsafe() {
213-
self.add_qualif(MUTABLE_MEM);
212+
self.add_qualif(ConstQualif::MUTABLE_MEM);
214213
}
215214

216215
true
@@ -366,7 +365,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
366365
macro in const?!")
367366
}
368367
};
369-
self.add_qualif(NOT_CONST);
368+
self.add_qualif(ConstQualif::NOT_CONST);
370369
if self.mode != Mode::Var {
371370
span_err!(self.tcx.sess, span, E0016,
372371
"blocks in {}s are limited to items and \
@@ -611,7 +610,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
611610
}
612611
Some(def::DefLocal(_)) if v.mode == Mode::ConstFn => {
613612
// Sadly, we can't determine whether the types are zero-sized.
614-
v.add_qualif(NOT_CONST | NON_ZERO_SIZED);
613+
v.add_qualif(ConstQualif::NOT_CONST | ConstQualif::NON_ZERO_SIZED);
615614
}
616615
def => {
617616
v.add_qualif(ConstQualif::NOT_CONST);
@@ -660,20 +659,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
660659
}
661660
}
662661
}
663-
ast::ExprBlock(ref block) => {
664-
// Check all statements in the block
665-
let mut block_span_err = |span| {
666-
v.add_qualif(ConstQualif::NOT_CONST);
667-
if v.mode != Mode::Var {
668-
span_err!(v.tcx.sess, e.span, E0015,
669-
"function calls in {}s are limited to \
670-
constant functions, \
671-
struct and enum constructors", v.msg());
672-
}
673-
}
674-
}
675662
ast::ExprMethodCall(..) => {
676-
let method_did = match v.tcx.method_map.borrow()[method_call].origin {
663+
let method_did = match v.tcx.method_map.borrow()[&method_call].origin {
677664
ty::MethodStatic(did) => Some(did),
678665
_ => None
679666
};
@@ -682,9 +669,9 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
682669
None => false
683670
};
684671
if !is_const {
685-
v.add_qualif(NOT_CONST);
672+
v.add_qualif(ConstQualif::NOT_CONST);
686673
if v.mode != Mode::Var {
687-
span_err!(v.tcx.sess, e.span, E0021,
674+
span_err!(v.tcx.sess, e.span, E0378,
688675
"method calls in {}s are limited to \
689676
constant inherent methods", v.msg());
690677
}

src/librustc/middle/const_eval.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use util::ppaux::Repr;
2525

2626
use syntax::ast::{self, Expr};
2727
use syntax::ast_map::blocks::FnLikeNode;
28-
use syntax::ast_util::{self, PostExpansionMethod};
28+
use syntax::ast_util;
2929
use syntax::codemap::Span;
3030
use syntax::feature_gate;
3131
use syntax::parse::token::InternedString;
@@ -216,17 +216,17 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: ast::DefId)
216216
let fn_id = match csearch::maybe_get_item_ast(tcx, def_id,
217217
box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
218218
csearch::FoundAst::Found(&ast::IIItem(ref item)) => Some(item.id),
219-
csearch::FoundAst::Found(&ast::IIImplItem(_, ast::MethodImplItem(ref m))) => Some(m.id),
219+
csearch::FoundAst::Found(&ast::IIImplItem(_, ref item)) => Some(item.id),
220220
_ => None
221221
};
222222
tcx.extern_const_fns.borrow_mut().insert(def_id,
223223
fn_id.unwrap_or(ast::DUMMY_NODE_ID));
224224
fn_id
225225
}
226226

227-
pub fn lookup_const_fn_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
228-
-> Option<FnLikeNode<'a>> {
229-
227+
pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: ast::DefId)
228+
-> Option<FnLikeNode<'tcx>>
229+
{
230230
let fn_id = if !ast_util::is_local(def_id) {
231231
if let Some(fn_id) = inline_const_fn_from_external_crate(tcx, def_id) {
232232
fn_id
@@ -243,11 +243,11 @@ pub fn lookup_const_fn_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
243243
};
244244

245245
match fn_like.kind() {
246-
visit::FkItemFn(_, _, _, ast::Constness::Const, _) => {
246+
visit::FkItemFn(_, _, _, ast::Constness::Const, _, _) => {
247247
Some(fn_like)
248248
}
249-
visit::FkMethod(_, _, m) => {
250-
if m.pe_constness() == ast::Constness::Const {
249+
visit::FkMethod(_, m, _) => {
250+
if m.constness == ast::Constness::Const {
251251
Some(fn_like)
252252
} else {
253253
None

src/librustc/middle/effect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
8787
block: &'v ast::Block, span: Span, _: ast::NodeId) {
8888

8989
let (is_item_fn, is_unsafe_fn) = match fn_kind {
90-
visit::FkItemFn(_, _, unsafety, _, _) =>
90+
visit::FkItemFn(_, _, unsafety, _, _, _) =>
9191
(true, unsafety == ast::Unsafety::Unsafe),
9292
visit::FkMethod(_, sig, _) =>
9393
(true, sig.unsafety == ast::Unsafety::Unsafe),

src/librustc/middle/resolve_lifetime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ impl<'a> LifetimeContext<'a> {
447447
fb: &'b ast::Block,
448448
_span: Span) {
449449
match fk {
450-
visit::FkItemFn(_, generics, _, _, _) => {
450+
visit::FkItemFn(_, generics, _, _, _, _) => {
451451
visit::walk_fn_decl(self, fd);
452452
self.visit_generics(generics);
453453
}

src/librustc/middle/stability.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use syntax::{attr, visit};
2323
use syntax::ast;
2424
use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
2525
use syntax::ast::{Item, Generics, StructField};
26-
use syntax::ast_util::{is_local, PostExpansionMethod};
26+
use syntax::ast_util::is_local;
2727
use syntax::attr::{Stability, AttrMetaMethods};
2828
use syntax::visit::{FnKind, Visitor};
2929
use syntax::feature_gate::emit_feature_err;

src/librustc_lint/builtin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ impl LintPass for UnsafeCode {
13241324
fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
13251325
_: &ast::Block, span: Span, _: ast::NodeId) {
13261326
match fk {
1327-
visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _, _) =>
1327+
visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _, _, _) =>
13281328
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
13291329

13301330
visit::FkMethod(_, sig, _) => {

src/librustc_resolve/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
245245
_: Span,
246246
node_id: NodeId) {
247247
let rib_kind = match function_kind {
248-
visit::FkItemFn(_, generics, _, _, _) => {
248+
visit::FkItemFn(_, generics, _, _, _, _) => {
249249
self.visit_generics(generics);
250250
ItemRibKind
251251
}

0 commit comments

Comments
 (0)