Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prohibit patterns in trait methods without bodies #37378

Merged
merged 2 commits into from Oct 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/doc/reference.md
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
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
Expand Up @@ -212,6 +212,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
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
@@ -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
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
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
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
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