Skip to content

Commit 0981211

Browse files
committed
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.
1 parent 469a6f9 commit 0981211

File tree

6 files changed

+49
-22
lines changed

6 files changed

+49
-22
lines changed

src/librustc_lint/unused.rs

+19-15
Original file line numberDiff line numberDiff line change
@@ -160,21 +160,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
160160
};
161161

162162
let mut fn_warned = false;
163-
let maybe_def = match expr.node {
164-
hir::ExprCall(ref callee, _) => {
165-
match callee.node {
166-
hir::ExprPath(ref qpath) => Some(cx.tables.qpath_def(qpath, callee.hir_id)),
167-
_ => None
168-
}
169-
},
170-
hir::ExprMethodCall(..) => {
171-
cx.tables.type_dependent_defs().get(expr.hir_id).cloned()
172-
},
173-
_ => { None }
174-
};
175-
if let Some(def) = maybe_def {
176-
let def_id = def.def_id();
177-
fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
163+
if cx.tcx.sess.features.borrow().fn_must_use {
164+
let maybe_def = match expr.node {
165+
hir::ExprCall(ref callee, _) => {
166+
match callee.node {
167+
hir::ExprPath(ref qpath) => {
168+
Some(cx.tables.qpath_def(qpath, callee.hir_id))
169+
},
170+
_ => None
171+
}
172+
},
173+
hir::ExprMethodCall(..) => {
174+
cx.tables.type_dependent_defs().get(expr.hir_id).cloned()
175+
},
176+
_ => None
177+
};
178+
if let Some(def) = maybe_def {
179+
let def_id = def.def_id();
180+
fn_warned = check_must_use(cx, def_id, s.span, "return value of ");
181+
}
178182
}
179183

180184
if !(ty_warned || fn_warned) {

src/libsyntax/feature_gate.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,9 @@ declare_features! (
372372

373373
// #[doc(cfg(...))]
374374
(active, doc_cfg, "1.21.0", Some(43781)),
375+
376+
// allow `#[must_use]` on functions (RFC 1940)
377+
(active, fn_must_use, "1.21.0", Some(43302)),
375378
);
376379

377380
declare_features! (
@@ -1014,7 +1017,7 @@ pub fn emit_feature_err(sess: &ParseSess, feature: &str, span: Span, issue: Gate
10141017
}
10151018

10161019
pub fn feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue: GateIssue,
1017-
explain: &str) -> DiagnosticBuilder<'a> {
1020+
explain: &str) -> DiagnosticBuilder<'a> {
10181021
let diag = &sess.span_diagnostic;
10191022

10201023
let issue = match issue {
@@ -1234,6 +1237,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
12341237
function may change over time, for now \
12351238
a top-level `fn main()` is required");
12361239
}
1240+
if attr::contains_name(&i.attrs[..], "must_use") {
1241+
gate_feature_post!(&self, fn_must_use, i.span,
1242+
"`#[must_use]` on functions is experimental");
1243+
}
12371244
}
12381245

12391246
ast::ItemKind::Struct(..) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[must_use]
12+
fn need_to_use_it() -> bool { true } //~ ERROR `#[must_use]` on functions is experimental
13+
14+
fn main() {}

src/test/compile-fail/feature-gate/issue-43106-gating-of-builtin-attrs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ mod must_use {
680680
mod inner { #![must_use="1400"] }
681681

682682
#[must_use = "1400"] fn f() { }
683+
//~^ ERROR `#[must_use]` on functions is experimental
683684

684685
#[must_use = "1400"] struct S;
685686

src/test/ui/lint/fn_must_use.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(fn_must_use)]
1112
#![warn(unused_must_use)]
1213

1314
struct MyStruct {

src/test/ui/lint/fn_must_use.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
warning: unused return value of `need_to_use_this_value` which must be used: it's important
2-
--> $DIR/fn_must_use.rs:30:5
2+
--> $DIR/fn_must_use.rs:31:5
33
|
4-
30 | need_to_use_this_value();
4+
31 | need_to_use_this_value();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: lint level defined here
8-
--> $DIR/fn_must_use.rs:11:9
8+
--> $DIR/fn_must_use.rs:12:9
99
|
10-
11 | #![warn(unused_must_use)]
10+
12 | #![warn(unused_must_use)]
1111
| ^^^^^^^^^^^^^^^
1212

1313
warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
14-
--> $DIR/fn_must_use.rs:33:5
14+
--> $DIR/fn_must_use.rs:34:5
1515
|
16-
33 | m.need_to_use_this_method_value();
16+
34 | m.need_to_use_this_method_value();
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

0 commit comments

Comments
 (0)