about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2016-08-07 14:33:35 -0700
committerKeith Yeung <kungfukeith11@gmail.com>2016-08-27 22:43:51 -0700
commit1e9e798ccea7f70480c3bcc86e271ca2191b8675 (patch)
tree101518975e431334726a05b595a3966b8320836a
parente17d6db80a6baeb43cf37b784e58128c81d5a462 (diff)
downloadrust-1e9e798ccea7f70480c3bcc86e271ca2191b8675.tar.gz
rust-1e9e798ccea7f70480c3bcc86e271ca2191b8675.zip
Move E0379 check from typeck to ast validation
-rw-r--r--src/librustc_passes/ast_validation.rs21
-rw-r--r--src/librustc_passes/diagnostics.rs7
-rw-r--r--src/librustc_typeck/check/mod.rs26
-rw-r--r--src/librustc_typeck/diagnostics.rs7
-rw-r--r--src/test/compile-fail/const-fn-mismatch.rs2
-rw-r--r--src/test/compile-fail/const-fn-not-in-trait.rs8
6 files changed, 37 insertions, 34 deletions
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 46124d0f973..f10f1fba4c2 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 7049040678e..89b8aa81411 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 e972a5ca7fb..c8d2f9144dc 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 8bb5efdcad2..3f1374db369 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 92568b27f7c..7ea72e23779 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 191f3e02527..257d4d5ee99 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() { }