Skip to content

Commit 811a2b9

Browse files
committed
Prohibit patterns in trait methods without bodies
1 parent a6b3b01 commit 811a2b9

File tree

8 files changed

+53
-11
lines changed

8 files changed

+53
-11
lines changed

src/doc/reference.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -4023,9 +4023,9 @@ Methods that take either `self` or `Box<Self>` can optionally place them in a
40234023
mutable variable by prefixing them with `mut` (similar to regular arguments):
40244024

40254025
```
4026-
trait Changer {
4027-
fn change(mut self) -> Self;
4028-
fn modify(mut self: Box<Self>) -> Box<Self>;
4026+
trait Changer: Sized {
4027+
fn change(mut self) {}
4028+
fn modify(mut self: Box<Self>) {}
40294029
}
40304030
```
40314031

src/librustc/lint/builtin.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ declare_lint! {
192192
"safe access to extern statics was erroneously allowed"
193193
}
194194

195+
declare_lint! {
196+
pub PATTERNS_IN_FNS_WITHOUT_BODY,
197+
Warn,
198+
"patterns in functions without body were erroneously allowed"
199+
}
200+
195201
/// Does nothing as a lint pass, but registers some `Lint`s
196202
/// which are used by other parts of the compiler.
197203
#[derive(Copy, Clone)]
@@ -228,7 +234,8 @@ impl LintPass for HardwiredLints {
228234
SUPER_OR_SELF_IN_GLOBAL_PATH,
229235
HR_LIFETIME_IN_ASSOC_TYPE,
230236
LIFETIME_UNDERSCORE,
231-
SAFE_EXTERN_STATICS
237+
SAFE_EXTERN_STATICS,
238+
PATTERNS_IN_FNS_WITHOUT_BODY
232239
)
233240
}
234241
}

src/librustc_lint/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
212212
id: LintId::of(SAFE_EXTERN_STATICS),
213213
reference: "issue 36247 <https://github.com/rust-lang/rust/issues/35112>",
214214
},
215+
FutureIncompatibleInfo {
216+
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
217+
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
218+
},
215219
]);
216220

217221
// Register renamed and removed lints

src/librustc_passes/ast_validation.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,16 @@ impl<'a> Visitor for AstValidator<'a> {
190190
}
191191
ItemKind::Trait(.., ref trait_items) => {
192192
for trait_item in trait_items {
193-
if let TraitItemKind::Method(ref sig, _) = trait_item.node {
193+
if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
194194
self.check_trait_fn_not_const(sig.constness);
195+
if block.is_none() {
196+
self.check_decl_no_pat(&sig.decl, |span, _| {
197+
self.session.add_lint(lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
198+
trait_item.id, span,
199+
"patterns aren't allowed in methods \
200+
without bodies".to_string());
201+
});
202+
}
195203
}
196204
}
197205
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(patterns_in_fns_without_body)]
12+
13+
trait Tr {
14+
fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in methods without bodies
15+
//~^ WARN was previously accepted
16+
fn f2(&arg: u8); //~ ERROR patterns aren't allowed in methods without bodies
17+
//~^ WARN was previously accepted
18+
fn g1(arg: u8); // OK
19+
fn g2(_: u8); // OK
20+
fn g3(u8); // OK
21+
}
22+
23+
fn main() {}

src/test/incremental/hashes/trait_defs.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -264,17 +264,17 @@ trait TraitChangeModeSelfRefToMut {
264264

265265

266266
#[cfg(cfail1)]
267-
trait TraitChangeModeSelfOwnToMut {
268-
fn method(self);
267+
trait TraitChangeModeSelfOwnToMut: Sized {
268+
fn method(self) {}
269269
}
270270

271271
#[cfg(not(cfail1))]
272272
#[rustc_dirty(label="Hir", cfg="cfail2")]
273273
#[rustc_clean(label="Hir", cfg="cfail3")]
274274
#[rustc_metadata_dirty(cfg="cfail2")]
275275
#[rustc_metadata_clean(cfg="cfail3")]
276-
trait TraitChangeModeSelfOwnToMut {
277-
fn method(mut self);
276+
trait TraitChangeModeSelfOwnToMut: Sized {
277+
fn method(mut self) {}
278278
}
279279

280280

src/test/run-pass/by-value-self-in-mut-slot.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct X {
1414
}
1515

1616
trait Changer {
17-
fn change(mut self) -> Self;
17+
fn change(self) -> Self;
1818
}
1919

2020
impl Changer for X {

src/test/run-pass/uniq-self-in-mut-slot.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct X {
1717
}
1818

1919
trait Changer {
20-
fn change(mut self: Box<Self>) -> Box<Self>;
20+
fn change(self: Box<Self>) -> Box<Self>;
2121
}
2222

2323
impl Changer for X {

0 commit comments

Comments
 (0)