Skip to content

Commit

Permalink
Auto merge of #37378 - petrochenkov:nopat, r=eddyb
Browse files Browse the repository at this point in the history
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 #35015.

Given the [statistics from crater](#37378 (comment)), the effect of this PR is mostly equivalent to improving `unused_mut` lint.

cc #35078 (comment) #35015 rust-lang/rfcs#1685 #35203
r? @eddyb
  • Loading branch information
bors authored Oct 29, 2016
2 parents 5db21c3 + 4ca11ce commit 75a87c5
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 12 deletions.
6 changes: 3 additions & 3 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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>) {}
}
```

Expand Down
9 changes: 8 additions & 1 deletion src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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
)
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
});
}
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions src/test/compile-fail/no-patterns-in-args-2.rs
Original file line number Diff line number Diff line change
@@ -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() {}
8 changes: 4 additions & 4 deletions src/test/incremental/hashes/trait_defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,17 +264,17 @@ trait TraitChangeModeSelfRefToMut {


#[cfg(cfail1)]
trait TraitChangeModeSelfOwnToMut {
fn method(self);
trait TraitChangeModeSelfOwnToMut: Sized {
fn method(self) {}
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[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) {}
}


Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/by-value-self-in-mut-slot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct X {
}

trait Changer {
fn change(mut self) -> Self;
fn change(self) -> Self;
}

impl Changer for X {
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/uniq-self-in-mut-slot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/cargotest/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 75a87c5

Please sign in to comment.