diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 46124d0f97359e65338234f0a61d81b7b9eb8455..f10f1fba4c25eb21a2e263815e8561b330cdc0f7 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -69,6 +69,17 @@ fn check_decl_no_pat(&self, decl: &FnDecl, report_err: } } } + + 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 @@ fn visit_item(&mut self, item: &Item) { 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 @@ fn visit_item(&mut self, item: &Item) { } } } + 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 7049040678e39f706499e9a7cc920dfe89f797aa..89b8aa81411b381ed7b1de79470440acb81e2be0 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 e972a5ca7fb3894848b2816b77f880e624d6a935..c8d2f9144dcc69d7f5f2321658cf334fae4112d9 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 8bb5efdcad2c348f882ab234ff6fbe73948abc09..3f1374db36936093418193e6b326429b41a4e6b8 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3422,13 +3422,6 @@ impl CoerceUnsized> for Foo where T: CoerceUnsized {} 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 92568b27f7c1da143e24a4fd2a982f3df13026d7..7ea72e23779ec5f40871851c233fc0a401aff4c8 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 191f3e025270fd7c23b2911c3a7790a296ea059e..257d4d5ee99210fbe514ba571378836f23fa51a4 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() { }