Skip to content

Commit bd38e89

Browse files
committed
Rollup merge of #35480 - KiChjang:e0379-bonus, r=nikomatsakis
Move E0379 check from typeck to ast validation Part of #35233. Extension of #35338, #35364. Fixes #35404.
2 parents 37f3017 + e46b09a commit bd38e89

File tree

21 files changed

+131
-66
lines changed

21 files changed

+131
-66
lines changed

src/librustc/hir/lowering.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,8 @@ impl<'a> LoweringContext<'a> {
804804
}
805805
}
806806

807-
fn lower_constness(&mut self, c: Constness) -> hir::Constness {
808-
match c {
807+
fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
808+
match c.node {
809809
Constness::Const => hir::Constness::Const,
810810
Constness::NotConst => hir::Constness::NotConst,
811811
}

src/librustc/hir/map/blocks.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
2424
pub use self::Code::*;
2525

26+
use hir as ast;
2627
use hir::map::{self, Node};
27-
use syntax::abi;
2828
use hir::{Block, FnDecl};
29+
use hir::intravisit::FnKind;
30+
use syntax::abi;
2931
use syntax::ast::{Attribute, Name, NodeId};
30-
use hir as ast;
3132
use syntax_pos::Span;
32-
use hir::intravisit::FnKind;
3333

3434
/// An FnLikeNode is a Node that is like a fn, in that it has a decl
3535
/// and a body (as well as a NodeId, a span, etc).

src/librustc/infer/error_reporting.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10301030
= node_inner.expect("expect item fn");
10311031
let rebuilder = Rebuilder::new(self.tcx, fn_decl, generics, same_regions, &life_giver);
10321032
let (fn_decl, generics) = rebuilder.rebuild();
1033-
self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name, &generics, span);
1033+
self.give_expl_lifetime_param(
1034+
err, &fn_decl, unsafety, constness, name, &generics, span);
10341035
}
10351036

10361037
pub fn issue_32330_warnings(&self, span: Span, issue32330s: &[ty::Issue32330]) {

src/librustc_passes/ast_validation.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc::lint;
2020
use rustc::session::Session;
2121
use syntax::ast::*;
2222
use syntax::attr;
23+
use syntax::codemap::Spanned;
2324
use syntax::parse::token::{self, keywords};
2425
use syntax::visit::{self, Visitor};
2526
use syntax_pos::Span;
@@ -69,6 +70,18 @@ impl<'a> AstValidator<'a> {
6970
}
7071
}
7172
}
73+
74+
fn check_trait_fn_not_const(&self, constness: Spanned<Constness>) {
75+
match constness.node {
76+
Constness::Const => {
77+
struct_span_err!(self.session, constness.span, E0379,
78+
"trait fns cannot be declared const")
79+
.span_label(constness.span, &format!("trait fns cannot be const"))
80+
.emit();
81+
}
82+
_ => {}
83+
}
84+
}
7285
}
7386

7487
impl<'a> Visitor for AstValidator<'a> {
@@ -146,6 +159,9 @@ impl<'a> Visitor for AstValidator<'a> {
146159
self.invalid_visibility(&item.vis, item.span, None);
147160
for impl_item in impl_items {
148161
self.invalid_visibility(&impl_item.vis, impl_item.span, None);
162+
if let ImplItemKind::Method(ref sig, _) = impl_item.node {
163+
self.check_trait_fn_not_const(sig.constness);
164+
}
149165
}
150166
}
151167
ItemKind::Impl(_, _, _, None, _, _) => {
@@ -169,6 +185,13 @@ impl<'a> Visitor for AstValidator<'a> {
169185
}
170186
}
171187
}
188+
ItemKind::Trait(_, _, _, ref trait_items) => {
189+
for trait_item in trait_items {
190+
if let TraitItemKind::Method(ref sig, _) = trait_item.node {
191+
self.check_trait_fn_not_const(sig.constness);
192+
}
193+
}
194+
}
172195
ItemKind::Mod(_) => {
173196
// Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
174197
attr::first_attr_value_str_by_name(&item.attrs, "path");

src/librustc_passes/consts.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
147147
}
148148

149149
let mode = match fk {
150-
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => Mode::ConstFn,
150+
FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _)
151+
=> Mode::ConstFn,
151152
FnKind::Method(_, m, _, _) => {
152153
if m.constness == hir::Constness::Const {
153154
Mode::ConstFn

src/librustc_passes/diagnostics.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ fn some_func() {
176176
```
177177
"##,
178178

179+
E0379: r##"
180+
Trait methods cannot be declared `const` by design. For more information, see
181+
[RFC 911].
182+
183+
[RFC 911]: https://github.com/rust-lang/rfcs/pull/911
184+
"##,
185+
179186
E0449: r##"
180187
A visibility qualifier was used when it was unnecessary. Erroneous code
181188
examples:

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -836,13 +836,9 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
836836
check_const(ccx, &expr, trait_item.id)
837837
}
838838
hir::MethodTraitItem(ref sig, Some(ref body)) => {
839-
check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
840-
841839
check_bare_fn(ccx, &sig.decl, body, trait_item.id);
842840
}
843-
hir::MethodTraitItem(ref sig, None) => {
844-
check_trait_fn_not_const(ccx, trait_item.span, sig.constness);
845-
}
841+
hir::MethodTraitItem(_, None) |
846842
hir::ConstTraitItem(_, None) |
847843
hir::TypeTraitItem(..) => {
848844
// Nothing to do.
@@ -854,22 +850,6 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
854850
}
855851
}
856852

857-
fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
858-
span: Span,
859-
constness: hir::Constness)
860-
{
861-
match constness {
862-
hir::Constness::NotConst => {
863-
// good
864-
}
865-
hir::Constness::Const => {
866-
struct_span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const")
867-
.span_label(span, &format!("trait fns cannot be const"))
868-
.emit()
869-
}
870-
}
871-
}
872-
873853
fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
874854
def_id: DefId,
875855
item: &hir::Item) {
@@ -1027,9 +1007,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
10271007
err.emit()
10281008
}
10291009
}
1030-
hir::ImplItemKind::Method(ref sig, ref body) => {
1031-
check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
1032-
1010+
hir::ImplItemKind::Method(_, ref body) => {
10331011
let impl_method = match ty_impl_item {
10341012
ty::MethodTraitItem(ref mti) => mti,
10351013
_ => span_bug!(impl_item.span, "non-method impl-item for method")

src/librustc_typeck/diagnostics.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3422,13 +3422,6 @@ containing the unsized type is the last and only unsized type field in the
34223422
struct.
34233423
"##,
34243424

3425-
E0379: r##"
3426-
Trait methods cannot be declared `const` by design. For more information, see
3427-
[RFC 911].
3428-
3429-
[RFC 911]: https://github.com/rust-lang/rfcs/pull/911
3430-
"##,
3431-
34323425
E0380: r##"
34333426
Default impls are only allowed for traits with no methods or associated items.
34343427
For more information see the [opt-in builtin traits RFC](https://github.com/rust

src/libsyntax/ast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ pub struct MutTy {
11221122
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
11231123
pub struct MethodSig {
11241124
pub unsafety: Unsafety,
1125-
pub constness: Constness,
1125+
pub constness: Spanned<Constness>,
11261126
pub abi: Abi,
11271127
pub decl: P<FnDecl>,
11281128
pub generics: Generics,
@@ -1820,7 +1820,7 @@ pub enum ItemKind {
18201820
/// A function declaration (`fn` or `pub fn`).
18211821
///
18221822
/// E.g. `fn foo(bar: usize) -> usize { .. }`
1823-
Fn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
1823+
Fn(P<FnDecl>, Unsafety, Spanned<Constness>, Abi, Generics, P<Block>),
18241824
/// A module declaration (`mod` or `pub mod`).
18251825
///
18261826
/// E.g. `mod foo;` or `mod foo { .. }`

src/libsyntax/ext/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use abi::Abi;
1212
use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind};
1313
use attr;
1414
use syntax_pos::{Span, DUMMY_SP, Pos};
15-
use codemap::{respan, Spanned};
15+
use codemap::{dummy_spanned, respan, Spanned};
1616
use ext::base::ExtCtxt;
1717
use parse::token::{self, keywords, InternedString};
1818
use ptr::P;
@@ -1016,7 +1016,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
10161016
Vec::new(),
10171017
ast::ItemKind::Fn(self.fn_decl(inputs, output),
10181018
ast::Unsafety::Normal,
1019-
ast::Constness::NotConst,
1019+
dummy_spanned(ast::Constness::NotConst),
10201020
Abi::Rust,
10211021
generics,
10221022
body))

0 commit comments

Comments
 (0)