From 811a2b91de8fe0c6bbd8d49186d0d5be192f644e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 22 Oct 2016 03:33:36 +0300 Subject: [PATCH] Prohibit patterns in trait methods without bodies --- src/doc/reference.md | 6 ++--- src/librustc/lint/builtin.rs | 9 +++++++- src/librustc_lint/lib.rs | 4 ++++ src/librustc_passes/ast_validation.rs | 10 +++++++- .../compile-fail/no-patterns-in-args-2.rs | 23 +++++++++++++++++++ src/test/incremental/hashes/trait_defs.rs | 8 +++---- .../run-pass/by-value-self-in-mut-slot.rs | 2 +- src/test/run-pass/uniq-self-in-mut-slot.rs | 2 +- 8 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 src/test/compile-fail/no-patterns-in-args-2.rs diff --git a/src/doc/reference.md b/src/doc/reference.md index 84f459bf872..94b45570985 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -4023,9 +4023,9 @@ Methods that take either `self` or `Box` 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) -> Box; +trait Changer: Sized { + fn change(mut self) {} + fn modify(mut self: Box) {} } ``` diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 7fc3f638979..d7ec544c954 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -192,6 +192,12 @@ "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 @@ fn get_lints(&self) -> LintArray { SUPER_OR_SELF_IN_GLOBAL_PATH, HR_LIFETIME_IN_ASSOC_TYPE, LIFETIME_UNDERSCORE, - SAFE_EXTERN_STATICS + SAFE_EXTERN_STATICS, + PATTERNS_IN_FNS_WITHOUT_BODY ) } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 74483b89cea..ef7bab8de8c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -212,6 +212,10 @@ macro_rules! add_lint_group { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue 36247 ", }, + FutureIncompatibleInfo { + id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), + reference: "issue #35203 ", + }, ]); // Register renamed and removed lints diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 5096a574e2b..828efbf3731 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -190,8 +190,16 @@ fn visit_item(&mut self, item: &Item) { } 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()); + }); + } } } } diff --git a/src/test/compile-fail/no-patterns-in-args-2.rs b/src/test/compile-fail/no-patterns-in-args-2.rs new file mode 100644 index 00000000000..385d012cade --- /dev/null +++ b/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 or the MIT license +// , 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() {} diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index 937f053e320..391c2e75ba4 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -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) {} } diff --git a/src/test/run-pass/by-value-self-in-mut-slot.rs b/src/test/run-pass/by-value-self-in-mut-slot.rs index 5bbdec95b15..846b695c35b 100644 --- a/src/test/run-pass/by-value-self-in-mut-slot.rs +++ b/src/test/run-pass/by-value-self-in-mut-slot.rs @@ -14,7 +14,7 @@ struct X { } trait Changer { - fn change(mut self) -> Self; + fn change(self) -> Self; } impl Changer for X { diff --git a/src/test/run-pass/uniq-self-in-mut-slot.rs b/src/test/run-pass/uniq-self-in-mut-slot.rs index baca157a488..7910380abee 100644 --- a/src/test/run-pass/uniq-self-in-mut-slot.rs +++ b/src/test/run-pass/uniq-self-in-mut-slot.rs @@ -17,7 +17,7 @@ struct X { } trait Changer { - fn change(mut self: Box) -> Box; + fn change(self: Box) -> Box; } impl Changer for X {