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