From 1e9e798ccea7f70480c3bcc86e271ca2191b8675 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 7 Aug 2016 14:33:35 -0700 Subject: [PATCH] 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 46124d0f9735..f10f1fba4c25 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 7049040678e3..89b8aa81411b 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 e972a5ca7fb3..c8d2f9144dcc 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 8bb5efdcad2c..3f1374db3693 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 92568b27f7c1..7ea72e23779e 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 191f3e025270..257d4d5ee992 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() { }