From 1e9e798ccea7f70480c3bcc86e271ca2191b8675 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 7 Aug 2016 14:33:35 -0700 Subject: [PATCH 1/3] Move E0379 check from typeck to ast validation --- src/librustc_passes/ast_validation.rs | 21 +++++++++++++++ src/librustc_passes/diagnostics.rs | 7 +++++ src/librustc_typeck/check/mod.rs | 26 ++----------------- src/librustc_typeck/diagnostics.rs | 7 ----- src/test/compile-fail/const-fn-mismatch.rs | 2 +- .../compile-fail/const-fn-not-in-trait.rs | 8 ++++-- 6 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 46124d0f97359..f10f1fba4c25e 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -69,6 +69,17 @@ impl<'a> AstValidator<'a> { } } } + + fn check_trait_fn_not_const(&self, span: Span, constness: Constness) { + match constness { + Constness::Const => { + struct_span_err!(self.session, span, E0379, "trait fns cannot be declared const") + .span_label(span, &format!("trait fns cannot be const")) + .emit(); + } + _ => {} + } + } } impl<'a> Visitor for AstValidator<'a> { @@ -146,6 +157,9 @@ impl<'a> Visitor for AstValidator<'a> { self.invalid_visibility(&item.vis, item.span, None); for impl_item in impl_items { self.invalid_visibility(&impl_item.vis, impl_item.span, None); + if let ImplItemKind::Method(ref sig, _) = impl_item.node { + self.check_trait_fn_not_const(impl_item.span, sig.constness); + } } } ItemKind::Impl(_, _, _, None, _, _) => { @@ -169,6 +183,13 @@ impl<'a> Visitor for AstValidator<'a> { } } } + ItemKind::Trait(_, _, _, ref trait_items) => { + for trait_item in trait_items { + if let TraitItemKind::Method(ref sig, _) = trait_item.node { + self.check_trait_fn_not_const(trait_item.span, sig.constness); + } + } + } ItemKind::Mod(_) => { // Ensure that `path` attributes on modules are recorded as used (c.f. #35584). attr::first_attr_value_str_by_name(&item.attrs, "path"); diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 7049040678e39..89b8aa81411b3 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -176,6 +176,13 @@ fn some_func() { ``` "##, +E0379: r##" +Trait methods cannot be declared `const` by design. For more information, see +[RFC 911]. + +[RFC 911]: https://github.com/rust-lang/rfcs/pull/911 +"##, + E0449: r##" A visibility qualifier was used when it was unnecessary. Erroneous code examples: diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e972a5ca7fb38..c8d2f9144dcc6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -836,13 +836,9 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { check_const(ccx, &expr, trait_item.id) } hir::MethodTraitItem(ref sig, Some(ref body)) => { - check_trait_fn_not_const(ccx, trait_item.span, sig.constness); - check_bare_fn(ccx, &sig.decl, body, trait_item.id); } - hir::MethodTraitItem(ref sig, None) => { - check_trait_fn_not_const(ccx, trait_item.span, sig.constness); - } + hir::MethodTraitItem(_, None) | hir::ConstTraitItem(_, None) | hir::TypeTraitItem(..) => { // Nothing to do. @@ -854,22 +850,6 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } } -fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - span: Span, - constness: hir::Constness) -{ - match constness { - hir::Constness::NotConst => { - // good - } - hir::Constness::Const => { - struct_span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const") - .span_label(span, &format!("trait fns cannot be const")) - .emit() - } - } -} - fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: DefId, item: &hir::Item) { @@ -1027,9 +1007,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, err.emit() } } - hir::ImplItemKind::Method(ref sig, ref body) => { - check_trait_fn_not_const(ccx, impl_item.span, sig.constness); - + hir::ImplItemKind::Method(_, ref body) => { let impl_method = match ty_impl_item { ty::MethodTraitItem(ref mti) => mti, _ => span_bug!(impl_item.span, "non-method impl-item for method") diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8bb5efdcad2c3..3f1374db36936 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3422,13 +3422,6 @@ containing the unsized type is the last and only unsized type field in the struct. "##, -E0379: r##" -Trait methods cannot be declared `const` by design. For more information, see -[RFC 911]. - -[RFC 911]: https://github.com/rust-lang/rfcs/pull/911 -"##, - E0380: r##" Default impls are only allowed for traits with no methods or associated items. For more information see the [opt-in builtin traits RFC](https://github.com/rust diff --git a/src/test/compile-fail/const-fn-mismatch.rs b/src/test/compile-fail/const-fn-mismatch.rs index 92568b27f7c1d..7ea72e23779ec 100644 --- a/src/test/compile-fail/const-fn-mismatch.rs +++ b/src/test/compile-fail/const-fn-mismatch.rs @@ -21,7 +21,7 @@ trait Foo { impl Foo for u32 { const fn f() -> u32 { 22 } - //~^ ERROR E0379 + //~^ ERROR trait fns cannot be declared const //~| NOTE trait fns cannot be const } diff --git a/src/test/compile-fail/const-fn-not-in-trait.rs b/src/test/compile-fail/const-fn-not-in-trait.rs index 191f3e025270f..257d4d5ee9921 100644 --- a/src/test/compile-fail/const-fn-not-in-trait.rs +++ b/src/test/compile-fail/const-fn-not-in-trait.rs @@ -14,8 +14,12 @@ #![feature(const_fn)] trait Foo { - const fn f() -> u32; //~ ERROR trait fns cannot be declared const - const fn g() -> u32 { 0 } //~ ERROR trait fns cannot be declared const + const fn f() -> u32; + //~^ ERROR trait fns cannot be declared const + //~| NOTE trait fns cannot be const + const fn g() -> u32 { 0 } + //~^ ERROR trait fns cannot be declared const + //~| NOTE trait fns cannot be const } fn main() { } From aa5c4bb05d1d5d10a2fdbb80f098ba06e73214b9 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 10 Aug 2016 16:20:12 -0700 Subject: [PATCH 2/3] Change Constness to Spanned --- src/librustc/hir/lowering.rs | 4 +-- src/librustc/hir/map/blocks.rs | 6 ++--- src/librustc/infer/error_reporting.rs | 3 ++- src/librustc_passes/ast_validation.rs | 14 +++++----- src/librustc_passes/consts.rs | 3 ++- src/libsyntax/ast.rs | 4 +-- src/libsyntax/ext/build.rs | 4 +-- src/libsyntax/feature_gate.rs | 8 +++--- src/libsyntax/parse/mod.rs | 5 +++- src/libsyntax/parse/parser.rs | 33 ++++++++++++++++------- src/libsyntax/print/pprust.rs | 4 +-- src/libsyntax/test.rs | 4 +-- src/libsyntax/visit.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 5 ++-- 14 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b45610c3fe820..be5eb7f83769e 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -809,8 +809,8 @@ impl<'a> LoweringContext<'a> { } } - fn lower_constness(&mut self, c: Constness) -> hir::Constness { - match c { + fn lower_constness(&mut self, c: Spanned) -> hir::Constness { + match c.node { Constness::Const => hir::Constness::Const, Constness::NotConst => hir::Constness::NotConst, } diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 50e8c6e7ab842..4487234885692 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -23,13 +23,13 @@ pub use self::Code::*; +use hir as ast; use hir::map::{self, Node}; -use syntax::abi; use hir::{Block, FnDecl}; +use hir::intravisit::FnKind; +use syntax::abi; use syntax::ast::{Attribute, Name, NodeId}; -use hir as ast; use syntax_pos::Span; -use hir::intravisit::FnKind; /// An FnLikeNode is a Node that is like a fn, in that it has a decl /// and a body (as well as a NodeId, a span, etc). diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 9169d299e040b..eab7f37382e67 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -1030,7 +1030,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { = node_inner.expect("expect item fn"); let rebuilder = Rebuilder::new(self.tcx, fn_decl, generics, same_regions, &life_giver); let (fn_decl, generics) = rebuilder.rebuild(); - self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name, &generics, span); + self.give_expl_lifetime_param( + err, &fn_decl, unsafety, constness, name, &generics, span); } pub fn issue_32330_warnings(&self, span: Span, issue32330s: &[ty::Issue32330]) { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index f10f1fba4c25e..dde1a4a759563 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -20,6 +20,7 @@ use rustc::lint; use rustc::session::Session; use syntax::ast::*; use syntax::attr; +use syntax::codemap::Spanned; use syntax::parse::token::{self, keywords}; use syntax::visit::{self, Visitor}; use syntax_pos::Span; @@ -70,11 +71,12 @@ impl<'a> AstValidator<'a> { } } - fn check_trait_fn_not_const(&self, span: Span, constness: Constness) { - match constness { + fn check_trait_fn_not_const(&self, constness: Spanned) { + match constness.node { Constness::Const => { - struct_span_err!(self.session, span, E0379, "trait fns cannot be declared const") - .span_label(span, &format!("trait fns cannot be const")) + struct_span_err!(self.session, constness.span, E0379, + "trait fns cannot be declared const") + .span_label(constness.span, &format!("trait fns cannot be const")) .emit(); } _ => {} @@ -158,7 +160,7 @@ impl<'a> Visitor for AstValidator<'a> { for impl_item in impl_items { self.invalid_visibility(&impl_item.vis, impl_item.span, None); if let ImplItemKind::Method(ref sig, _) = impl_item.node { - self.check_trait_fn_not_const(impl_item.span, sig.constness); + self.check_trait_fn_not_const(sig.constness); } } } @@ -186,7 +188,7 @@ impl<'a> Visitor for AstValidator<'a> { ItemKind::Trait(_, _, _, ref trait_items) => { for trait_item in trait_items { if let TraitItemKind::Method(ref sig, _) = trait_item.node { - self.check_trait_fn_not_const(trait_item.span, sig.constness); + self.check_trait_fn_not_const(sig.constness); } } } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 4aae6d690c4df..2d1b6e1315f8b 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -147,7 +147,8 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { } let mode = match fk { - FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => Mode::ConstFn, + FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) + => Mode::ConstFn, FnKind::Method(_, m, _, _) => { if m.constness == hir::Constness::Const { Mode::ConstFn diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f8a5cb0b04a8e..427a44d2e740c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1120,7 +1120,7 @@ pub struct MutTy { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct MethodSig { pub unsafety: Unsafety, - pub constness: Constness, + pub constness: Spanned, pub abi: Abi, pub decl: P, pub generics: Generics, @@ -1846,7 +1846,7 @@ pub enum ItemKind { /// A function declaration (`fn` or `pub fn`). /// /// E.g. `fn foo(bar: usize) -> usize { .. }` - Fn(P, Unsafety, Constness, Abi, Generics, P), + Fn(P, Unsafety, Spanned, Abi, Generics, P), /// A module declaration (`mod` or `pub mod`). /// /// E.g. `mod foo;` or `mod foo { .. }` diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 5d6429f7bdfff..14c7e46246d0d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -12,7 +12,7 @@ use abi::Abi; use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind}; use attr; use syntax_pos::{Span, DUMMY_SP, Pos}; -use codemap::{respan, Spanned}; +use codemap::{dummy_spanned, respan, Spanned}; use ext::base::ExtCtxt; use parse::token::{self, keywords, InternedString}; use ptr::P; @@ -1016,7 +1016,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { Vec::new(), ast::ItemKind::Fn(self.fn_decl(inputs, output), ast::Unsafety::Normal, - ast::Constness::NotConst, + dummy_spanned(ast::Constness::NotConst), Abi::Rust, generics, body)) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index dc68e06463464..9114c31d29816 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -30,7 +30,7 @@ use ast::{NodeId, PatKind}; use ast; use attr; use attr::AttrMetaMethods; -use codemap::CodeMap; +use codemap::{CodeMap, Spanned}; use syntax_pos::Span; use errors::Handler; use visit::{self, FnKind, Visitor}; @@ -1046,7 +1046,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { _node_id: NodeId) { // check for const fn declarations match fn_kind { - FnKind::ItemFn(_, _, _, ast::Constness::Const, _, _) => { + FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _) => { gate_feature_post!(&self, const_fn, span, "const fn is unstable"); } _ => { @@ -1078,7 +1078,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { if block.is_none() { self.check_abi(sig.abi, ti.span); } - if sig.constness == ast::Constness::Const { + if sig.constness.node == ast::Constness::Const { gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable"); } } @@ -1105,7 +1105,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> { "associated constants are experimental") } ast::ImplItemKind::Method(ref sig, _) => { - if sig.constness == ast::Constness::Const { + if sig.constness.node == ast::Constness::Const { gate_feature_post!(&self, const_fn, ii.span, "const fn is unstable"); } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index cd1fdcfe9d130..a89dc80df4b08 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -937,7 +937,10 @@ mod tests { variadic: false }), ast::Unsafety::Normal, - ast::Constness::NotConst, + Spanned { + span: sp(0,2), + node: ast::Constness::NotConst, + }, Abi::Rust, ast::Generics{ // no idea on either of these: lifetimes: Vec::new(), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1646246069ead..757c0779e352a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -39,7 +39,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; use ast::{BinOpKind, UnOp}; use ast; -use codemap::{self, CodeMap, Spanned, spanned}; +use codemap::{self, CodeMap, Spanned, spanned, respan}; use syntax_pos::{self, Span, BytePos, mk_sp}; use errors::{self, DiagnosticBuilder}; use ext::tt::macro_parser; @@ -4768,7 +4768,7 @@ impl<'a> Parser<'a> { /// Parse an item-position function declaration. fn parse_item_fn(&mut self, unsafety: Unsafety, - constness: Constness, + constness: Spanned, abi: abi::Abi) -> PResult<'a, ItemInfo> { let (ident, mut generics) = self.parse_fn_header()?; @@ -4794,18 +4794,21 @@ impl<'a> Parser<'a> { /// - `extern fn` /// - etc pub fn parse_fn_front_matter(&mut self) - -> PResult<'a, (ast::Constness, ast::Unsafety, abi::Abi)> { + -> PResult<'a, (Spanned, + ast::Unsafety, + abi::Abi)> { let is_const_fn = self.eat_keyword(keywords::Const); + let const_span = self.last_span; let unsafety = self.parse_unsafety()?; let (constness, unsafety, abi) = if is_const_fn { - (Constness::Const, unsafety, Abi::Rust) + (respan(const_span, Constness::Const), unsafety, Abi::Rust) } else { let abi = if self.eat_keyword(keywords::Extern) { self.parse_opt_abi()?.unwrap_or(Abi::C) } else { Abi::Rust }; - (Constness::NotConst, unsafety, abi) + (respan(self.last_span, Constness::NotConst), unsafety, abi) }; self.expect_keyword(keywords::Fn)?; Ok((constness, unsafety, abi)) @@ -5704,9 +5707,12 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::Fn) { // EXTERN FUNCTION ITEM + let fn_span = self.last_span; let abi = opt_abi.unwrap_or(Abi::C); let (ident, item_, extra_attrs) = - self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi)?; + self.parse_item_fn(Unsafety::Normal, + respan(fn_span, Constness::NotConst), + abi)?; let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, @@ -5740,6 +5746,7 @@ impl<'a> Parser<'a> { return Ok(Some(item)); } if self.eat_keyword(keywords::Const) { + let const_span = self.last_span; if self.check_keyword(keywords::Fn) || (self.check_keyword(keywords::Unsafe) && self.look_ahead(1, |t| t.is_keyword(keywords::Fn))) { @@ -5751,7 +5758,9 @@ impl<'a> Parser<'a> { }; self.bump(); let (ident, item_, extra_attrs) = - self.parse_item_fn(unsafety, Constness::Const, Abi::Rust)?; + self.parse_item_fn(unsafety, + respan(const_span, Constness::Const), + Abi::Rust)?; let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, @@ -5815,8 +5824,11 @@ impl<'a> Parser<'a> { if self.check_keyword(keywords::Fn) { // FUNCTION ITEM self.bump(); + let fn_span = self.last_span; let (ident, item_, extra_attrs) = - self.parse_item_fn(Unsafety::Normal, Constness::NotConst, Abi::Rust)?; + self.parse_item_fn(Unsafety::Normal, + respan(fn_span, Constness::NotConst), + Abi::Rust)?; let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, @@ -5836,8 +5848,11 @@ impl<'a> Parser<'a> { Abi::Rust }; self.expect_keyword(keywords::Fn)?; + let fn_span = self.last_span; let (ident, item_, extra_attrs) = - self.parse_item_fn(Unsafety::Unsafe, Constness::NotConst, abi)?; + self.parse_item_fn(Unsafety::Unsafe, + respan(fn_span, Constness::NotConst), + abi)?; let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a77c678248b56..4c83440306306 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1184,7 +1184,7 @@ impl<'a> State<'a> { try!(self.print_fn( decl, unsafety, - constness, + constness.node, abi, Some(item.ident), typarams, @@ -1518,7 +1518,7 @@ impl<'a> State<'a> { -> io::Result<()> { self.print_fn(&m.decl, m.unsafety, - m.constness, + m.constness.node, m.abi, Some(ident), &m.generics, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index faf6a17a15045..cbf9aa8c6c17f 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -24,7 +24,7 @@ use attr; use syntax_pos::{self, DUMMY_SP, NO_EXPANSION, Span, FileMap, BytePos}; use std::rc::Rc; -use codemap::{self, CodeMap, ExpnInfo, NameAndSpan, MacroAttribute}; +use codemap::{self, CodeMap, ExpnInfo, NameAndSpan, MacroAttribute, dummy_spanned}; use errors; use errors::snippet::{SnippetData}; use config; @@ -485,7 +485,7 @@ fn mk_main(cx: &mut TestCtxt) -> P { let main_body = ecx.block(sp, vec![call_test_main]); let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty), ast::Unsafety::Normal, - ast::Constness::NotConst, + dummy_spanned(ast::Constness::NotConst), ::abi::Abi::Rust, ast::Generics::default(), main_body); let main = P(ast::Item { ident: token::str_to_ident("main"), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 582412119caa8..d75110b2654ce 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -31,7 +31,7 @@ use codemap::Spanned; #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { /// fn foo() or extern "Abi" fn foo() - ItemFn(Ident, &'a Generics, Unsafety, Constness, Abi, &'a Visibility), + ItemFn(Ident, &'a Generics, Unsafety, Spanned, Abi, &'a Visibility), /// fn foo(&self) Method(Ident, &'a MethodSig, Option<&'a Visibility>), diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index cd49e7ec9d2c6..809f444b9936e 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -197,7 +197,7 @@ use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::build::AstBuilder; -use syntax::codemap::{self, respan}; +use syntax::codemap::{self, dummy_spanned, respan}; use syntax::util::move_map::MoveMap; use syntax::parse::token::{InternedString, keywords}; use syntax::ptr::P; @@ -901,7 +901,8 @@ impl<'a> MethodDef<'a> { generics: fn_generics, abi: abi, unsafety: unsafety, - constness: ast::Constness::NotConst, + constness: + dummy_spanned(ast::Constness::NotConst), decl: fn_decl, }, body_block), From e46b09a1f9051a65544dee08f4d8d749d474d586 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 12 Aug 2016 15:47:42 -0700 Subject: [PATCH 3/3] Add UI test for E0379 --- .../ui/mismatched_types/const-fn-in-trait.rs | 25 +++++++++++++++++++ .../mismatched_types/const-fn-in-trait.stderr | 14 +++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/test/ui/mismatched_types/const-fn-in-trait.rs create mode 100644 src/test/ui/mismatched_types/const-fn-in-trait.stderr diff --git a/src/test/ui/mismatched_types/const-fn-in-trait.rs b/src/test/ui/mismatched_types/const-fn-in-trait.rs new file mode 100644 index 0000000000000..5e44030eab71a --- /dev/null +++ b/src/test/ui/mismatched_types/const-fn-in-trait.rs @@ -0,0 +1,25 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// rustc-env:RUST_NEW_ERROR_FORMAT + +#![feature(const_fn)] + +trait Foo { + fn f() -> u32; + const fn g(); +} + +impl Foo for u32 { + const fn f() -> u32 { 22 } + fn g() {} +} + +fn main() { } diff --git a/src/test/ui/mismatched_types/const-fn-in-trait.stderr b/src/test/ui/mismatched_types/const-fn-in-trait.stderr new file mode 100644 index 0000000000000..f7b7635e41aec --- /dev/null +++ b/src/test/ui/mismatched_types/const-fn-in-trait.stderr @@ -0,0 +1,14 @@ +error[E0379]: trait fns cannot be declared const + --> $DIR/const-fn-in-trait.rs:17:5 + | +17 | const fn g(); + | ^^^^^ trait fns cannot be const + +error[E0379]: trait fns cannot be declared const + --> $DIR/const-fn-in-trait.rs:21:5 + | +21 | const fn f() -> u32 { 22 } + | ^^^^^ trait fns cannot be const + +error: aborting due to 2 previous errors +