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
|
@ -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):
|
mutable variable by prefixing them with `mut` (similar to regular arguments):
|
||||||
|
|
||||||
```
|
```
|
||||||
trait Changer {
|
trait Changer: Sized {
|
||||||
fn change(mut self) -> Self;
|
fn change(mut self) {}
|
||||||
fn modify(mut self: Box<Self>) -> Box<Self>;
|
fn modify(mut self: Box<Self>) {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,12 @@ declare_lint! {
|
||||||
"safe access to extern statics was erroneously allowed"
|
"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
|
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||||
/// which are used by other parts of the compiler.
|
/// which are used by other parts of the compiler.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -228,7 +234,8 @@ impl LintPass for HardwiredLints {
|
||||||
SUPER_OR_SELF_IN_GLOBAL_PATH,
|
SUPER_OR_SELF_IN_GLOBAL_PATH,
|
||||||
HR_LIFETIME_IN_ASSOC_TYPE,
|
HR_LIFETIME_IN_ASSOC_TYPE,
|
||||||
LIFETIME_UNDERSCORE,
|
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),
|
id: LintId::of(SAFE_EXTERN_STATICS),
|
||||||
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/35112>",
|
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
|
// Register renamed and removed lints
|
||||||
|
|
|
@ -190,8 +190,16 @@ impl<'a> Visitor for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
ItemKind::Trait(.., ref trait_items) => {
|
ItemKind::Trait(.., ref trait_items) => {
|
||||||
for trait_item in 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);
|
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());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
#[cfg(cfail1)]
|
||||||
trait TraitChangeModeSelfOwnToMut {
|
trait TraitChangeModeSelfOwnToMut: Sized {
|
||||||
fn method(self);
|
fn method(self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(cfail1))]
|
#[cfg(not(cfail1))]
|
||||||
|
@ -273,8 +273,8 @@ trait TraitChangeModeSelfOwnToMut {
|
||||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
#[rustc_metadata_clean(cfg="cfail3")]
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
trait TraitChangeModeSelfOwnToMut {
|
trait TraitChangeModeSelfOwnToMut: Sized {
|
||||||
fn method(mut self);
|
fn method(mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct X {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Changer {
|
trait Changer {
|
||||||
fn change(mut self) -> Self;
|
fn change(self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Changer for X {
|
impl Changer for X {
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct X {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Changer {
|
trait Changer {
|
||||||
fn change(mut self: Box<Self>) -> Box<Self>;
|
fn change(self: Box<Self>) -> Box<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Changer for X {
|
impl Changer for X {
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct Test {
|
||||||
const TEST_REPOS: &'static [Test] = &[Test {
|
const TEST_REPOS: &'static [Test] = &[Test {
|
||||||
name: "cargo",
|
name: "cargo",
|
||||||
repo: "https://github.com/rust-lang/cargo",
|
repo: "https://github.com/rust-lang/cargo",
|
||||||
sha: "d3bad1ab29efae414e9b4c24534b2d02b3a59782",
|
sha: "806e3c368a15f618244a3b4e918bf77f9c403fd0",
|
||||||
lock: None,
|
lock: None,
|
||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
|
|
Loading…
Reference in New Issue