about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/collect.rs15
-rw-r--r--src/test/ui/target-feature-wrong.rs5
-rw-r--r--src/test/ui/target-feature-wrong.stderr8
3 files changed, 27 insertions, 1 deletions
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 6f24d06844b..59156bf0dfe 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1769,6 +1769,7 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
 
     let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);
 
+    let mut inline_span = None;
     for attr in attrs.iter() {
         if attr.check_name("cold") {
             trans_fn_attrs.flags |= TransFnAttrFlags::COLD;
@@ -1800,6 +1801,7 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
                     }
                     MetaItemKind::List(ref items) => {
                         mark_used(attr);
+                        inline_span = Some(attr.span);
                         if items.len() != 1 {
                             span_err!(tcx.sess.diagnostic(), attr.span, E0534,
                                         "expected one argument");
@@ -1855,5 +1857,18 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
         }
     }
 
+    // If a function uses #[target_feature] it can't be inlined into general
+    // purpose functions as they wouldn't have the right target features
+    // enabled. For that reason we also forbid #[inline(always)] as it can't be
+    // respected.
+    if trans_fn_attrs.target_features.len() > 0 {
+        if trans_fn_attrs.inline == InlineAttr::Always {
+            if let Some(span) = inline_span {
+                tcx.sess.span_err(span, "cannot use #[inline(always)] with \
+                                         #[target_feature]");
+            }
+        }
+    }
+
     trans_fn_attrs
 }
diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs
index c1e6245d24b..56acbed4721 100644
--- a/src/test/ui/target-feature-wrong.rs
+++ b/src/test/ui/target-feature-wrong.rs
@@ -33,6 +33,11 @@ fn bar() {}
 //~^ ERROR: should be applied to a function
 mod another {}
 
+#[inline(always)]
+//~^ ERROR: cannot use #[inline(always)]
+#[target_feature(enable = "sse2")]
+unsafe fn test() {}
+
 fn main() {
     unsafe {
         foo();
diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr
index 0fa6910f2bb..8773f8504cb 100644
--- a/src/test/ui/target-feature-wrong.stderr
+++ b/src/test/ui/target-feature-wrong.stderr
@@ -37,5 +37,11 @@ LL | //~^ ERROR: should be applied to a function
 LL | mod another {}
    | -------------- not a function
 
-error: aborting due to 5 previous errors
+error: cannot use #[inline(always)] with #[target_feature]
+  --> $DIR/target-feature-wrong.rs:36:1
+   |
+LL | #[inline(always)]
+   | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors