Auto merge of #37378 - petrochenkov:nopat, r=eddyb
Prohibit patterns in trait methods without bodies They are not properly type checked ```rust trait Tr { fn f(&a: u8); // <- This compiles } ``` , mostly rejected by the parser already and generally don't make much sense. This PR is kind of a missing part of https://github.com/rust-lang/rust/pull/35015. Given the [statistics from crater](https://github.com/rust-lang/rust/pull/37378#issuecomment-256154994), the effect of this PR is mostly equivalent to improving `unused_mut` lint. cc https://github.com/rust-lang/rust/issues/35078#issuecomment-255707355 https://github.com/rust-lang/rust/pull/35015 https://github.com/rust-lang/rfcs/pull/1685 https://github.com/rust-lang/rust/issues/35203 r? @eddyb
This commit is contained in:
commit
75a87c54d0
9 changed files with 54 additions and 12 deletions
|
@ -4023,9 +4023,9 @@ Methods that take either `self` or `Box<Self>` can optionally place them in a
|
|||
mutable variable by prefixing them with `mut` (similar to regular arguments):
|
||||
|
||||
```
|
||||
trait Changer {
|
||||
fn change(mut self) -> Self;
|
||||
fn modify(mut self: Box<Self>) -> Box<Self>;
|
||||
trait Changer: Sized {
|
||||
fn change(mut self) {}
|
||||
fn modify(mut self: Box<Self>) {}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -192,6 +192,12 @@ declare_lint! {
|
|||
"safe access to extern statics was erroneously allowed"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
Warn,
|
||||
"patterns in functions without body were erroneously allowed"
|
||||
}
|
||||
|
||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||
/// which are used by other parts of the compiler.
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -228,7 +234,8 @@ impl LintPass for HardwiredLints {
|
|||
SUPER_OR_SELF_IN_GLOBAL_PATH,
|
||||
HR_LIFETIME_IN_ASSOC_TYPE,
|
||||
LIFETIME_UNDERSCORE,
|
||||
SAFE_EXTERN_STATICS
|
||||
SAFE_EXTERN_STATICS,
|
||||
PATTERNS_IN_FNS_WITHOUT_BODY
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,6 +225,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
id: LintId::of(SAFE_EXTERN_STATICS),
|
||||
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/35112>",
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
|
||||
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
|
||||
},
|
||||
]);
|
||||
|
||||
// Register renamed and removed lints
|
||||
|
|
|
@ -190,8 +190,16 @@ 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 {
|
||||
if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
|
||||
self.check_trait_fn_not_const(sig.constness);
|
||||
if block.is_none() {
|
||||
self.check_decl_no_pat(&sig.decl, |span, _| {
|
||||
self.session.add_lint(lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
trait_item.id, span,
|
||||
"patterns aren't allowed in methods \
|
||||
without bodies".to_string());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
src/test/compile-fail/no-patterns-in-args-2.rs
Normal file
23
src/test/compile-fail/no-patterns-in-args-2.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![deny(patterns_in_fns_without_body)]
|
||||
|
||||
trait Tr {
|
||||
fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in methods without bodies
|
||||
//~^ WARN was previously accepted
|
||||
fn f2(&arg: u8); //~ ERROR patterns aren't allowed in methods without bodies
|
||||
//~^ WARN was previously accepted
|
||||
fn g1(arg: u8); // OK
|
||||
fn g2(_: u8); // OK
|
||||
fn g3(u8); // OK
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -264,8 +264,8 @@ trait TraitChangeModeSelfRefToMut {
|
|||
|
||||
|
||||
#[cfg(cfail1)]
|
||||
trait TraitChangeModeSelfOwnToMut {
|
||||
fn method(self);
|
||||
trait TraitChangeModeSelfOwnToMut: Sized {
|
||||
fn method(self) {}
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
|
@ -273,8 +273,8 @@ trait TraitChangeModeSelfOwnToMut {
|
|||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
trait TraitChangeModeSelfOwnToMut {
|
||||
fn method(mut self);
|
||||
trait TraitChangeModeSelfOwnToMut: Sized {
|
||||
fn method(mut self) {}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ struct X {
|
|||
}
|
||||
|
||||
trait Changer {
|
||||
fn change(mut self) -> Self;
|
||||
fn change(self) -> Self;
|
||||
}
|
||||
|
||||
impl Changer for X {
|
||||
|
|
|
@ -17,7 +17,7 @@ struct X {
|
|||
}
|
||||
|
||||
trait Changer {
|
||||
fn change(mut self: Box<Self>) -> Box<Self>;
|
||||
fn change(self: Box<Self>) -> Box<Self>;
|
||||
}
|
||||
|
||||
impl Changer for X {
|
||||
|
|
|
@ -24,7 +24,7 @@ struct Test {
|
|||
const TEST_REPOS: &'static [Test] = &[Test {
|
||||
name: "cargo",
|
||||
repo: "https://github.com/rust-lang/cargo",
|
||||
sha: "d3bad1ab29efae414e9b4c24534b2d02b3a59782",
|
||||
sha: "806e3c368a15f618244a3b4e918bf77f9c403fd0",
|
||||
lock: None,
|
||||
},
|
||||
Test {
|
||||
|
|
Loading…
Add table
Reference in a new issue