Skip to content

Commit

Permalink
Allow #[inline] on closures
Browse files Browse the repository at this point in the history
Fixes #49632
  • Loading branch information
Amanieu committed Apr 27, 2018
1 parent 9822b57 commit 5f2c111
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 32 deletions.
15 changes: 10 additions & 5 deletions src/librustc/hir/check_attr.rs
Expand Up @@ -30,6 +30,7 @@ enum Target {
ForeignMod,
Expression,
Statement,
Closure,
Other,
}

Expand Down Expand Up @@ -103,14 +104,14 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
self.check_repr(item, target);
}

/// Check if an `#[inline]` is applied to a function.
/// Check if an `#[inline]` is applied to a function or a closure.
fn check_inline(&self, attr: &hir::Attribute, span: &Span, target: Target) {
if target != Target::Fn {
if target != Target::Fn && target != Target::Closure {
struct_span_err!(self.tcx.sess,
attr.span,
E0518,
"attribute should be applied to function")
.span_label(*span, "not a function")
"attribute should be applied to function or closure")
.span_label(*span, "not a function or closure")
.emit();
}
}
Expand Down Expand Up @@ -286,9 +287,13 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
}

fn check_expr_attributes(&self, expr: &hir::Expr) {
let target = match expr.node {
hir::ExprClosure(..) => Target::Closure,
_ => Target::Expression,
};
for attr in expr.attrs.iter() {
if attr.check_name("inline") {
self.check_inline(attr, &expr.span, Target::Expression);
self.check_inline(attr, &expr.span, target);
}
if attr.check_name("repr") {
self.emit_repr_error(
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/attr-usage-inline.rs
Expand Up @@ -13,7 +13,7 @@
#[inline]
fn f() {}

#[inline] //~ ERROR: attribute should be applied to function
#[inline] //~ ERROR: attribute should be applied to function or closure
struct S;

fn main() {}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-31769.rs
Expand Up @@ -9,6 +9,6 @@
// except according to those terms.

fn main() {
#[inline] struct Foo; //~ ERROR attribute should be applied to function
#[inline] struct Foo; //~ ERROR attribute should be applied to function or closure
#[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum or union
}
6 changes: 3 additions & 3 deletions src/test/compile-fail/issue-43988.rs
Expand Up @@ -14,12 +14,12 @@ fn main() {

#[inline]
let _a = 4;
//~^^ ERROR attribute should be applied to function
//~^^ ERROR attribute should be applied to function or closure


#[inline(XYZ)]
let _b = 4;
//~^^ ERROR attribute should be applied to function
//~^^ ERROR attribute should be applied to function or closure

#[repr(nothing)]
let _x = 0;
Expand All @@ -40,7 +40,7 @@ fn main() {

#[inline(ABC)]
foo();
//~^^ ERROR attribute should be applied to function
//~^^ ERROR attribute should be applied to function or closure

let _z = #[repr] 1;
//~^ ERROR attribute should not be applied to an expression
Expand Down
17 changes: 17 additions & 0 deletions src/test/run-pass/issue-49632.rs
@@ -0,0 +1,17 @@
// Copyright 2018 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.

#![feature(stmt_expr_attributes)]

pub fn main() {
let _x = #[inline(always)] || {};
let _y = #[inline(never)] || {};
let _z = #[inline] || {};
}
8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0518.stderr
@@ -1,19 +1,19 @@
error[E0518]: attribute should be applied to function
error[E0518]: attribute should be applied to function or closure
--> $DIR/E0518.rs:11:1
|
LL | #[inline(always)] //~ ERROR: E0518
| ^^^^^^^^^^^^^^^^^
LL | struct Foo;
| ----------- not a function
| ----------- not a function or closure

error[E0518]: attribute should be applied to function
error[E0518]: attribute should be applied to function or closure
--> $DIR/E0518.rs:14:1
|
LL | #[inline(never)] //~ ERROR: E0518
| ^^^^^^^^^^^^^^^^
LL | / impl Foo {
LL | | }
| |_- not a function
| |_- not a function or closure

error: aborting due to 2 previous errors

Expand Down
10 changes: 5 additions & 5 deletions src/test/ui/feature-gate/issue-43106-gating-of-inline.rs
Expand Up @@ -19,21 +19,21 @@
#![inline = "2100"]

#[inline = "2100"]
//~^ ERROR attribute should be applied to function
//~^ ERROR attribute should be applied to function or closure
mod inline {
mod inner { #![inline="2100"] }
//~^ ERROR attribute should be applied to function
//~^ ERROR attribute should be applied to function or closure

#[inline = "2100"] fn f() { }

#[inline = "2100"] struct S;
//~^ ERROR attribute should be applied to function
//~^ ERROR attribute should be applied to function or closure

#[inline = "2100"] type T = S;
//~^ ERROR attribute should be applied to function
//~^ ERROR attribute should be applied to function or closure

#[inline = "2100"] impl S { }
//~^ ERROR attribute should be applied to function
//~^ ERROR attribute should be applied to function or closure
}

fn main() {}
26 changes: 13 additions & 13 deletions src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr
@@ -1,41 +1,41 @@
error[E0518]: attribute should be applied to function
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43106-gating-of-inline.rs:21:1
|
LL | #[inline = "2100"]
| ^^^^^^^^^^^^^^^^^^
LL | //~^ ERROR attribute should be applied to function
LL | //~^ ERROR attribute should be applied to function or closure
LL | / mod inline {
LL | | mod inner { #![inline="2100"] }
LL | | //~^ ERROR attribute should be applied to function
LL | | //~^ ERROR attribute should be applied to function or closure
LL | |
... |
LL | | //~^ ERROR attribute should be applied to function
LL | | //~^ ERROR attribute should be applied to function or closure
LL | | }
| |_- not a function
| |_- not a function or closure

error[E0518]: attribute should be applied to function
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43106-gating-of-inline.rs:24:17
|
LL | mod inner { #![inline="2100"] }
| ------------^^^^^^^^^^^^^^^^^-- not a function
| ------------^^^^^^^^^^^^^^^^^-- not a function or closure

error[E0518]: attribute should be applied to function
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43106-gating-of-inline.rs:29:5
|
LL | #[inline = "2100"] struct S;
| ^^^^^^^^^^^^^^^^^^ --------- not a function
| ^^^^^^^^^^^^^^^^^^ --------- not a function or closure

error[E0518]: attribute should be applied to function
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43106-gating-of-inline.rs:32:5
|
LL | #[inline = "2100"] type T = S;
| ^^^^^^^^^^^^^^^^^^ ----------- not a function
| ^^^^^^^^^^^^^^^^^^ ----------- not a function or closure

error[E0518]: attribute should be applied to function
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43106-gating-of-inline.rs:35:5
|
LL | #[inline = "2100"] impl S { }
| ^^^^^^^^^^^^^^^^^^ ---------- not a function
| ^^^^^^^^^^^^^^^^^^ ---------- not a function or closure

error: aborting due to 5 previous errors

Expand Down

0 comments on commit 5f2c111

Please sign in to comment.