use astconv::{AstConv, Bounds};
use constrained_type_params as ctp;
+use check::intrinsic::intrisic_operation_unsafety;
use lint;
use middle::lang_items::SizedTraitLangItem;
use middle::resolve_lifetime as rl;
use middle::weak_lang_items;
use rustc::mir::mono::Linkage;
use rustc::ty::query::Providers;
+use rustc::ty::query::queries;
use rustc::ty::subst::Substs;
use rustc::ty::util::Discr;
use rustc::ty::util::IntTypeExt;
use syntax::ast;
use syntax::ast::{Ident, MetaItemKind};
-use syntax::attr::{InlineAttr, list_contains_name, mark_used};
+use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used};
use syntax::source_map::Spanned;
use syntax::feature_gate;
use syntax::symbol::{keywords, Symbol};
// Main entry point
pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- let mut visitor = CollectItemTypesVisitor { tcx };
- tcx.hir()
- .krate()
- .visit_all_item_likes(&mut visitor.as_deep_visitor());
+ for &module in tcx.hir().krate().modules.keys() {
+ queries::collect_mod_item_types::ensure(tcx, tcx.hir().local_def_id(module));
+ }
+}
+
+fn collect_mod_item_types<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
+ tcx.hir().visit_item_likes_in_module(
+ module_def_id,
+ &mut CollectItemTypesVisitor { tcx }.as_deep_visitor()
+ );
}
pub fn provide(providers: &mut Providers) {
impl_polarity,
is_foreign_item,
codegen_fn_attrs,
+ collect_mod_item_types,
..*providers
};
}
tcx.sess,
span,
E0202,
- "associated types are not allowed in inherent impls"
+ "associated types are not yet supported in inherent impls (see #8995)"
);
}
}
},
- Node::GenericParam(param) => match param.kind {
+ Node::GenericParam(param) => match ¶m.kind {
hir::GenericParamKind::Type {
default: Some(ref ty),
..
} => icx.to_ty(ty),
- _ => bug!("unexpected non-type NodeGenericParam"),
+ x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
},
x => {
abi: abi::Abi,
) -> ty::PolyFnSig<'tcx> {
let unsafety = if abi == abi::Abi::RustIntrinsic {
- match &*tcx.item_name(def_id).as_str() {
- "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
- _ => hir::Unsafety::Unsafe,
- }
+ intrisic_operation_unsafety(&*tcx.item_name(def_id).as_str())
} else {
hir::Unsafety::Unsafe
};
) {
let list = match attr.meta_item_list() {
Some(list) => list,
- None => {
- let msg = "#[target_feature] attribute must be of the form \
- #[target_feature(..)]";
- tcx.sess.span_err(attr.span, &msg);
- return;
- }
+ None => return,
};
let rust_features = tcx.features();
for item in list {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
} else if attr.check_name("thread_local") {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
- } else if attr.check_name("inline") {
- codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
- if attr.path != "inline" {
- return ia;
- }
- let meta = match attr.meta() {
- Some(meta) => meta.node,
- None => return ia,
- };
- match meta {
- MetaItemKind::Word => {
- mark_used(attr);
- InlineAttr::Hint
- }
- 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"
- );
- InlineAttr::None
- } else if list_contains_name(&items[..], "always") {
- InlineAttr::Always
- } else if list_contains_name(&items[..], "never") {
- InlineAttr::Never
- } else {
- span_err!(
- tcx.sess.diagnostic(),
- items[0].span,
- E0535,
- "invalid argument"
- );
-
- InlineAttr::None
- }
- }
- _ => ia,
- }
- });
} else if attr.check_name("export_name") {
if let Some(s) = attr.value_str() {
if s.as_str().contains("\0") {
).emit();
}
codegen_fn_attrs.export_name = Some(s);
- } else {
- struct_span_err!(
- tcx.sess,
- attr.span,
- E0558,
- "`export_name` attribute has invalid format"
- ).span_label(attr.span, "did you mean #[export_name=\"*\"]?")
- .emit();
}
} else if attr.check_name("target_feature") {
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
}
}
+ codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
+ if attr.path != "inline" {
+ return ia;
+ }
+ match attr.meta().map(|i| i.node) {
+ Some(MetaItemKind::Word) => {
+ mark_used(attr);
+ InlineAttr::Hint
+ }
+ Some(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"
+ );
+ InlineAttr::None
+ } else if list_contains_name(&items[..], "always") {
+ InlineAttr::Always
+ } else if list_contains_name(&items[..], "never") {
+ InlineAttr::Never
+ } else {
+ span_err!(
+ tcx.sess.diagnostic(),
+ items[0].span,
+ E0535,
+ "invalid argument"
+ );
+
+ InlineAttr::None
+ }
+ }
+ Some(MetaItemKind::NameValue(_)) => ia,
+ None => ia,
+ }
+ });
+
+ codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
+ if attr.path != "optimize" {
+ return ia;
+ }
+ let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s);
+ match attr.meta().map(|i| i.node) {
+ Some(MetaItemKind::Word) => {
+ err(attr.span, "expected one argument");
+ ia
+ }
+ Some(MetaItemKind::List(ref items)) => {
+ mark_used(attr);
+ inline_span = Some(attr.span);
+ if items.len() != 1 {
+ err(attr.span, "expected one argument");
+ OptimizeAttr::None
+ } else if list_contains_name(&items[..], "size") {
+ OptimizeAttr::Size
+ } else if list_contains_name(&items[..], "speed") {
+ OptimizeAttr::Speed
+ } else {
+ err(items[0].span, "invalid argument");
+ OptimizeAttr::None
+ }
+ }
+ Some(MetaItemKind::NameValue(_)) => ia,
+ None => ia,
+ }
+ });
+
// 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