Skip to content

Commit bd38e89

Browse files
committed
Rollup merge of rust-lang#35480 - KiChjang:e0379-bonus, r=nikomatsakis
Move E0379 check from typeck to ast validation Part of rust-lang#35233. Extension of rust-lang#35338, rust-lang#35364. Fixes rust-lang#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

+2-2
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

+3-3
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

+2-1
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

+23
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

+2-1
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

+7
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

+2-24
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

-7
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

+2-2
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

+2-2
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))

src/libsyntax/feature_gate.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use ast::{NodeId, PatKind};
3030
use ast;
3131
use attr;
3232
use attr::AttrMetaMethods;
33-
use codemap::CodeMap;
33+
use codemap::{CodeMap, Spanned};
3434
use syntax_pos::Span;
3535
use errors::Handler;
3636
use visit::{self, FnKind, Visitor};
@@ -1046,7 +1046,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
10461046
_node_id: NodeId) {
10471047
// check for const fn declarations
10481048
match fn_kind {
1049-
FnKind::ItemFn(_, _, _, ast::Constness::Const, _, _) => {
1049+
FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _) => {
10501050
gate_feature_post!(&self, const_fn, span, "const fn is unstable");
10511051
}
10521052
_ => {
@@ -1078,7 +1078,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
10781078
if block.is_none() {
10791079
self.check_abi(sig.abi, ti.span);
10801080
}
1081-
if sig.constness == ast::Constness::Const {
1081+
if sig.constness.node == ast::Constness::Const {
10821082
gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
10831083
}
10841084
}
@@ -1105,7 +1105,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
11051105
"associated constants are experimental")
11061106
}
11071107
ast::ImplItemKind::Method(ref sig, _) => {
1108-
if sig.constness == ast::Constness::Const {
1108+
if sig.constness.node == ast::Constness::Const {
11091109
gate_feature_post!(&self, const_fn, ii.span, "const fn is unstable");
11101110
}
11111111
}

src/libsyntax/parse/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,10 @@ mod tests {
937937
variadic: false
938938
}),
939939
ast::Unsafety::Normal,
940-
ast::Constness::NotConst,
940+
Spanned {
941+
span: sp(0,2),
942+
node: ast::Constness::NotConst,
943+
},
941944
Abi::Rust,
942945
ast::Generics{ // no idea on either of these:
943946
lifetimes: Vec::new(),

src/libsyntax/parse/parser.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
3939
use ast::{Visibility, WhereClause};
4040
use ast::{BinOpKind, UnOp};
4141
use ast;
42-
use codemap::{self, CodeMap, Spanned, spanned};
42+
use codemap::{self, CodeMap, Spanned, spanned, respan};
4343
use syntax_pos::{self, Span, BytePos, mk_sp};
4444
use errors::{self, DiagnosticBuilder};
4545
use ext::tt::macro_parser;
@@ -4770,7 +4770,7 @@ impl<'a> Parser<'a> {
47704770
/// Parse an item-position function declaration.
47714771
fn parse_item_fn(&mut self,
47724772
unsafety: Unsafety,
4773-
constness: Constness,
4773+
constness: Spanned<Constness>,
47744774
abi: abi::Abi)
47754775
-> PResult<'a, ItemInfo> {
47764776
let (ident, mut generics) = self.parse_fn_header()?;
@@ -4796,18 +4796,21 @@ impl<'a> Parser<'a> {
47964796
/// - `extern fn`
47974797
/// - etc
47984798
pub fn parse_fn_front_matter(&mut self)
4799-
-> PResult<'a, (ast::Constness, ast::Unsafety, abi::Abi)> {
4799+
-> PResult<'a, (Spanned<ast::Constness>,
4800+
ast::Unsafety,
4801+
abi::Abi)> {
48004802
let is_const_fn = self.eat_keyword(keywords::Const);
4803+
let const_span = self.last_span;
48014804
let unsafety = self.parse_unsafety()?;
48024805
let (constness, unsafety, abi) = if is_const_fn {
4803-
(Constness::Const, unsafety, Abi::Rust)
4806+
(respan(const_span, Constness::Const), unsafety, Abi::Rust)
48044807
} else {
48054808
let abi = if self.eat_keyword(keywords::Extern) {
48064809
self.parse_opt_abi()?.unwrap_or(Abi::C)
48074810
} else {
48084811
Abi::Rust
48094812
};
4810-
(Constness::NotConst, unsafety, abi)
4813+
(respan(self.last_span, Constness::NotConst), unsafety, abi)
48114814
};
48124815
self.expect_keyword(keywords::Fn)?;
48134816
Ok((constness, unsafety, abi))
@@ -5706,9 +5709,12 @@ impl<'a> Parser<'a> {
57065709

57075710
if self.eat_keyword(keywords::Fn) {
57085711
// EXTERN FUNCTION ITEM
5712+
let fn_span = self.last_span;
57095713
let abi = opt_abi.unwrap_or(Abi::C);
57105714
let (ident, item_, extra_attrs) =
5711-
self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi)?;
5715+
self.parse_item_fn(Unsafety::Normal,
5716+
respan(fn_span, Constness::NotConst),
5717+
abi)?;
57125718
let last_span = self.last_span;
57135719
let item = self.mk_item(lo,
57145720
last_span.hi,
@@ -5742,6 +5748,7 @@ impl<'a> Parser<'a> {
57425748
return Ok(Some(item));
57435749
}
57445750
if self.eat_keyword(keywords::Const) {
5751+
let const_span = self.last_span;
57455752
if self.check_keyword(keywords::Fn)
57465753
|| (self.check_keyword(keywords::Unsafe)
57475754
&& self.look_ahead(1, |t| t.is_keyword(keywords::Fn))) {
@@ -5753,7 +5760,9 @@ impl<'a> Parser<'a> {
57535760
};
57545761
self.bump();
57555762
let (ident, item_, extra_attrs) =
5756-
self.parse_item_fn(unsafety, Constness::Const, Abi::Rust)?;
5763+
self.parse_item_fn(unsafety,
5764+
respan(const_span, Constness::Const),
5765+
Abi::Rust)?;
57575766
let last_span = self.last_span;
57585767
let item = self.mk_item(lo,
57595768
last_span.hi,
@@ -5817,8 +5826,11 @@ impl<'a> Parser<'a> {
58175826
if self.check_keyword(keywords::Fn) {
58185827
// FUNCTION ITEM
58195828
self.bump();
5829+
let fn_span = self.last_span;
58205830
let (ident, item_, extra_attrs) =
5821-
self.parse_item_fn(Unsafety::Normal, Constness::NotConst, Abi::Rust)?;
5831+
self.parse_item_fn(Unsafety::Normal,
5832+
respan(fn_span, Constness::NotConst),
5833+
Abi::Rust)?;
58225834
let last_span = self.last_span;
58235835
let item = self.mk_item(lo,
58245836
last_span.hi,
@@ -5838,8 +5850,11 @@ impl<'a> Parser<'a> {
58385850
Abi::Rust
58395851
};
58405852
self.expect_keyword(keywords::Fn)?;
5853+
let fn_span = self.last_span;
58415854
let (ident, item_, extra_attrs) =
5842-
self.parse_item_fn(Unsafety::Unsafe, Constness::NotConst, abi)?;
5855+
self.parse_item_fn(Unsafety::Unsafe,
5856+
respan(fn_span, Constness::NotConst),
5857+
abi)?;
58435858
let last_span = self.last_span;
58445859
let item = self.mk_item(lo,
58455860
last_span.hi,

src/libsyntax/print/pprust.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,7 @@ impl<'a> State<'a> {
11851185
try!(self.print_fn(
11861186
decl,
11871187
unsafety,
1188-
constness,
1188+
constness.node,
11891189
abi,
11901190
Some(item.ident),
11911191
typarams,
@@ -1519,7 +1519,7 @@ impl<'a> State<'a> {
15191519
-> io::Result<()> {
15201520
self.print_fn(&m.decl,
15211521
m.unsafety,
1522-
m.constness,
1522+
m.constness.node,
15231523
m.abi,
15241524
Some(ident),
15251525
&m.generics,

src/libsyntax/test.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use attr;
2424
use syntax_pos::{self, DUMMY_SP, NO_EXPANSION, Span, FileMap, BytePos};
2525
use std::rc::Rc;
2626

27-
use codemap::{self, CodeMap, ExpnInfo, NameAndSpan, MacroAttribute};
27+
use codemap::{self, CodeMap, ExpnInfo, NameAndSpan, MacroAttribute, dummy_spanned};
2828
use errors;
2929
use errors::snippet::{SnippetData};
3030
use config;
@@ -485,7 +485,7 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> {
485485
let main_body = ecx.block(sp, vec![call_test_main]);
486486
let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty),
487487
ast::Unsafety::Normal,
488-
ast::Constness::NotConst,
488+
dummy_spanned(ast::Constness::NotConst),
489489
::abi::Abi::Rust, ast::Generics::default(), main_body);
490490
let main = P(ast::Item {
491491
ident: token::str_to_ident("main"),

0 commit comments

Comments
 (0)