提交 0981211c 编写于 作者: Z Zack M. Davis

hard feature-gate for #[must_use] on functions

We'll actually want a new "soft" warning-only gate to maintain
backwards-compatibility, but it's cleaner to start out with the established,
well-understood gate before implementing the alternative warn-only behavior in
a later commit.

This is in the matter of #43302.
上级 469a6f9b
...@@ -160,21 +160,25 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { ...@@ -160,21 +160,25 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
}; };
let mut fn_warned = false; let mut fn_warned = false;
let maybe_def = match expr.node { if cx.tcx.sess.features.borrow().fn_must_use {
hir::ExprCall(ref callee, _) => { let maybe_def = match expr.node {
match callee.node { hir::ExprCall(ref callee, _) => {
hir::ExprPath(ref qpath) => Some(cx.tables.qpath_def(qpath, callee.hir_id)), match callee.node {
_ => None hir::ExprPath(ref qpath) => {
} Some(cx.tables.qpath_def(qpath, callee.hir_id))
}, },
hir::ExprMethodCall(..) => { _ => None
cx.tables.type_dependent_defs().get(expr.hir_id).cloned() }
}, },
_ => { None } hir::ExprMethodCall(..) => {
}; cx.tables.type_dependent_defs().get(expr.hir_id).cloned()
if let Some(def) = maybe_def { },
let def_id = def.def_id(); _ => None
fn_warned = check_must_use(cx, def_id, s.span, "return value of "); };
if let Some(def) = maybe_def {
let def_id = def.def_id();
fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
}
} }
if !(ty_warned || fn_warned) { if !(ty_warned || fn_warned) {
......
...@@ -372,6 +372,9 @@ pub fn new() -> Features { ...@@ -372,6 +372,9 @@ pub fn new() -> Features {
// #[doc(cfg(...))] // #[doc(cfg(...))]
(active, doc_cfg, "1.21.0", Some(43781)), (active, doc_cfg, "1.21.0", Some(43781)),
// allow `#[must_use]` on functions (RFC 1940)
(active, fn_must_use, "1.21.0", Some(43302)),
); );
declare_features! ( declare_features! (
...@@ -1014,7 +1017,7 @@ pub fn emit_feature_err(sess: &ParseSess, feature: &str, span: Span, issue: Gate ...@@ -1014,7 +1017,7 @@ pub fn emit_feature_err(sess: &ParseSess, feature: &str, span: Span, issue: Gate
} }
pub fn feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue: GateIssue, pub fn feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue: GateIssue,
explain: &str) -> DiagnosticBuilder<'a> { explain: &str) -> DiagnosticBuilder<'a> {
let diag = &sess.span_diagnostic; let diag = &sess.span_diagnostic;
let issue = match issue { let issue = match issue {
...@@ -1234,6 +1237,10 @@ fn visit_item(&mut self, i: &'a ast::Item) { ...@@ -1234,6 +1237,10 @@ fn visit_item(&mut self, i: &'a ast::Item) {
function may change over time, for now \ function may change over time, for now \
a top-level `fn main()` is required"); a top-level `fn main()` is required");
} }
if attr::contains_name(&i.attrs[..], "must_use") {
gate_feature_post!(&self, fn_must_use, i.span,
"`#[must_use]` on functions is experimental");
}
} }
ast::ItemKind::Struct(..) => { ast::ItemKind::Struct(..) => {
......
// Copyright 2017 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.
#[must_use]
fn need_to_use_it() -> bool { true } //~ ERROR `#[must_use]` on functions is experimental
fn main() {}
...@@ -680,6 +680,7 @@ mod must_use { ...@@ -680,6 +680,7 @@ mod must_use {
mod inner { #![must_use="1400"] } mod inner { #![must_use="1400"] }
#[must_use = "1400"] fn f() { } #[must_use = "1400"] fn f() { }
//~^ ERROR `#[must_use]` on functions is experimental
#[must_use = "1400"] struct S; #[must_use = "1400"] struct S;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![feature(fn_must_use)]
#![warn(unused_must_use)] #![warn(unused_must_use)]
struct MyStruct { struct MyStruct {
......
warning: unused return value of `need_to_use_this_value` which must be used: it's important warning: unused return value of `need_to_use_this_value` which must be used: it's important
--> $DIR/fn_must_use.rs:30:5 --> $DIR/fn_must_use.rs:31:5
| |
30 | need_to_use_this_value(); 31 | need_to_use_this_value();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
note: lint level defined here note: lint level defined here
--> $DIR/fn_must_use.rs:11:9 --> $DIR/fn_must_use.rs:12:9
| |
11 | #![warn(unused_must_use)] 12 | #![warn(unused_must_use)]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
--> $DIR/fn_must_use.rs:33:5 --> $DIR/fn_must_use.rs:34:5
| |
33 | m.need_to_use_this_method_value(); 34 | m.need_to_use_this_method_value();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册