diff options
Diffstat (limited to 'compiler/rustc_passes')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_const.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 132 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/entry.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/loops.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/naked_functions.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/reachable.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/stability.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/weak_lang_items.rs | 2 | 
9 files changed, 117 insertions, 69 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4f9b362e237..197b335bdec 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, IntoDiagnosticArg, MultiSpan}; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID, @@ -2465,10 +2465,10 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) } } -fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { +fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let check_attr_visitor = &mut CheckAttrVisitor { tcx, abort: Cell::new(false) }; tcx.hir().visit_item_likes_in_module(module_def_id, check_attr_visitor); - if module_def_id.is_top_level_module() { + if module_def_id.to_local_def_id().is_top_level_module() { check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None); check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs()); } diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index e70817d7b7c..8437e9a40e2 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -9,7 +9,7 @@ use rustc_attr as attr; use rustc_hir as hir; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; @@ -45,7 +45,7 @@ impl NonConstExpr { Self::Loop(ForLoop) | Self::Match(ForLoopDesugar) => &[sym::const_for], - Self::Match(TryDesugar) => &[sym::const_try], + Self::Match(TryDesugar(_)) => &[sym::const_try], // All other expressions are allowed. Self::Loop(Loop | While) | Self::Match(Normal | FormatArgs) => &[], @@ -55,7 +55,7 @@ impl NonConstExpr { } } -fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { +fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let mut vis = CheckConstVisitor::new(tcx); tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis); } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 07b437f463f..d1c3bcf3839 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -4,10 +4,11 @@ use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use itertools::Itertools; +use rustc_data_structures::unord::UnordSet; use rustc_errors::MultiSpan; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Node, PatKind, TyKind}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; @@ -42,8 +43,16 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { ) } +/// Determine if a work from the worklist is coming from the a `#[allow]` +/// or a `#[expect]` of `dead_code` +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +enum ComesFromAllowExpect { + Yes, + No, +} + struct MarkSymbolVisitor<'tcx> { - worklist: Vec<LocalDefId>, + worklist: Vec<(LocalDefId, ComesFromAllowExpect)>, tcx: TyCtxt<'tcx>, maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, live_symbols: LocalDefIdSet, @@ -72,7 +81,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { fn check_def_id(&mut self, def_id: DefId) { if let Some(def_id) = def_id.as_local() { if should_explore(self.tcx, def_id) || self.struct_constructors.contains_key(&def_id) { - self.worklist.push(def_id); + self.worklist.push((def_id, ComesFromAllowExpect::No)); } self.live_symbols.insert(def_id); } @@ -269,12 +278,14 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } fn mark_live_symbols(&mut self) { - let mut scanned = LocalDefIdSet::default(); - while let Some(id) = self.worklist.pop() { - if !scanned.insert(id) { + let mut scanned = UnordSet::default(); + while let Some(work) = self.worklist.pop() { + if !scanned.insert(work) { continue; } + let (id, comes_from_allow_expect) = work; + // Avoid accessing the HIR for the synthesized associated type generated for RPITITs. if self.tcx.is_impl_trait_in_trait(id.to_def_id()) { self.live_symbols.insert(id); @@ -286,7 +297,30 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { let id = self.struct_constructors.get(&id).copied().unwrap_or(id); if let Some(node) = self.tcx.hir().find_by_def_id(id) { - self.live_symbols.insert(id); + // When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement + // by declaring fn calls, statics, ... within said items as live, as well as + // the item itself, although technically this is not the case. + // + // This means that the lint for said items will never be fired. + // + // This doesn't make any difference for the item declared with `#[allow]`, as + // the lint firing will be a nop, as it will be silenced by the `#[allow]` of + // the item. + // + // However, for `#[expect]`, the presence or absence of the lint is relevant, + // so we don't add it to the list of live symbols when it comes from a + // `#[expect]`. This means that we will correctly report an item as live or not + // for the `#[expect]` case. + // + // Note that an item can and will be duplicated on the worklist with different + // `ComesFromAllowExpect`, particulary if it was added from the + // `effective_visibilities` query or from the `#[allow]`/`#[expect]` checks, + // this "duplication" is essential as otherwise a function with `#[expect]` + // called from a `pub fn` may be falsely reported as not live, falsely + // triggering the `unfulfilled_lint_expectations` lint. + if comes_from_allow_expect != ComesFromAllowExpect::Yes { + self.live_symbols.insert(id); + } self.visit_node(node); } } @@ -513,16 +547,20 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { } } -fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { +fn has_allow_dead_code_or_lang_attr( + tcx: TyCtxt<'_>, + def_id: LocalDefId, +) -> Option<ComesFromAllowExpect> { fn has_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { tcx.has_attr(def_id, sym::lang) // Stable attribute for #[lang = "panic_impl"] || tcx.has_attr(def_id, sym::panic_handler) } - fn has_allow_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + fn has_allow_expect_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0 == lint::Allow + let lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0; + matches!(lint_level, lint::Allow | lint::Expect(_)) } fn has_used_like_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { @@ -537,9 +575,13 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool } } - has_allow_dead_code(tcx, def_id) - || has_used_like_attr(tcx, def_id) - || has_lang_attr(tcx, def_id) + if has_allow_expect_dead_code(tcx, def_id) { + Some(ComesFromAllowExpect::Yes) + } else if has_used_like_attr(tcx, def_id) || has_lang_attr(tcx, def_id) { + Some(ComesFromAllowExpect::No) + } else { + None + } } // These check_* functions seeds items that @@ -557,21 +599,23 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool // * Implementations of traits and trait methods fn check_item<'tcx>( tcx: TyCtxt<'tcx>, - worklist: &mut Vec<LocalDefId>, + worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, struct_constructors: &mut LocalDefIdMap<LocalDefId>, id: hir::ItemId, ) { let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id); - if allow_dead_code { - worklist.push(id.owner_id.def_id); + if let Some(comes_from_allow) = allow_dead_code { + worklist.push((id.owner_id.def_id, comes_from_allow)); } match tcx.def_kind(id.owner_id) { DefKind::Enum => { let item = tcx.hir().item(id); if let hir::ItemKind::Enum(ref enum_def, _) = item.kind { - if allow_dead_code { - worklist.extend(enum_def.variants.iter().map(|variant| variant.def_id)); + if let Some(comes_from_allow) = allow_dead_code { + worklist.extend( + enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)), + ); } for variant in enum_def.variants { @@ -583,7 +627,7 @@ fn check_item<'tcx>( } DefKind::Impl { of_trait } => { if of_trait { - worklist.push(id.owner_id.def_id); + worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No)); } // get DefIds from another query @@ -594,8 +638,10 @@ fn check_item<'tcx>( // And we access the Map here to get HirId from LocalDefId for id in local_def_ids { - if of_trait || has_allow_dead_code_or_lang_attr(tcx, id) { - worklist.push(id); + if of_trait { + worklist.push((id, ComesFromAllowExpect::No)); + } else if let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id) { + worklist.push((id, comes_from_allow)); } } } @@ -609,43 +655,59 @@ fn check_item<'tcx>( } DefKind::GlobalAsm => { // global_asm! is always live. - worklist.push(id.owner_id.def_id); + worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No)); } _ => {} } } -fn check_trait_item(tcx: TyCtxt<'_>, worklist: &mut Vec<LocalDefId>, id: hir::TraitItemId) { +fn check_trait_item( + tcx: TyCtxt<'_>, + worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, + id: hir::TraitItemId, +) { use hir::TraitItemKind::{Const, Fn}; if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) { let trait_item = tcx.hir().trait_item(id); if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_))) - && has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) + && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id) { - worklist.push(trait_item.owner_id.def_id); + worklist.push((trait_item.owner_id.def_id, comes_from_allow)); } } } -fn check_foreign_item(tcx: TyCtxt<'_>, worklist: &mut Vec<LocalDefId>, id: hir::ForeignItemId) { +fn check_foreign_item( + tcx: TyCtxt<'_>, + worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>, + id: hir::ForeignItemId, +) { if matches!(tcx.def_kind(id.owner_id), DefKind::Static(_) | DefKind::Fn) - && has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id) + && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id) { - worklist.push(id.owner_id.def_id); + worklist.push((id.owner_id.def_id, comes_from_allow)); } } -fn create_and_seed_worklist(tcx: TyCtxt<'_>) -> (Vec<LocalDefId>, LocalDefIdMap<LocalDefId>) { +fn create_and_seed_worklist( + tcx: TyCtxt<'_>, +) -> (Vec<(LocalDefId, ComesFromAllowExpect)>, LocalDefIdMap<LocalDefId>) { let effective_visibilities = &tcx.effective_visibilities(()); // see `MarkSymbolVisitor::struct_constructors` let mut struct_constructors = Default::default(); let mut worklist = effective_visibilities .iter() .filter_map(|(&id, effective_vis)| { - effective_vis.is_public_at_level(Level::Reachable).then_some(id) + effective_vis + .is_public_at_level(Level::Reachable) + .then_some(id) + .map(|id| (id, ComesFromAllowExpect::No)) }) // Seed entry point - .chain(tcx.entry_fn(()).and_then(|(def_id, _)| def_id.as_local())) + .chain( + tcx.entry_fn(()) + .and_then(|(def_id, _)| def_id.as_local().map(|id| (id, ComesFromAllowExpect::No))), + ) .collect::<Vec<_>>(); let crate_items = tcx.hir_crate_items(()); @@ -878,13 +940,11 @@ impl<'tcx> DeadVisitor<'tcx> { return true; }; - self.live_symbols.contains(&def_id) - || has_allow_dead_code_or_lang_attr(self.tcx, def_id) - || name.as_str().starts_with('_') + self.live_symbols.contains(&def_id) || name.as_str().starts_with('_') } } -fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) { +fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { let (live_symbols, ignored_derived_traits) = tcx.live_symbols_and_ignored_derived_traits(()); let mut visitor = DeadVisitor { tcx, live_symbols, ignored_derived_traits }; @@ -909,7 +969,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) { if !live_symbols.contains(&item.owner_id.def_id) { let parent = tcx.local_parent(item.owner_id.def_id); - if parent != module && !live_symbols.contains(&parent) { + if parent != module.to_local_def_id() && !live_symbols.contains(&parent) { // We already have diagnosed something. continue; } diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index ffd8f77b78b..4f71704b885 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -31,7 +31,7 @@ struct EntryContext<'tcx> { } fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { - let any_exe = tcx.sess.crate_types().iter().any(|ty| *ty == CrateType::Executable); + let any_exe = tcx.crate_types().iter().any(|ty| *ty == CrateType::Executable); if !any_exe { // No need to find a main function. return None; @@ -187,12 +187,6 @@ fn sigpipe(tcx: TyCtxt<'_>, def_id: DefId) -> u8 { fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) { let sp = tcx.def_span(CRATE_DEF_ID); - if tcx.sess.parse_sess.reached_eof.load(rustc_data_structures::sync::Ordering::Relaxed) { - // There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about - // the missing `fn main()` then as it might have been hidden inside an unclosed block. - tcx.sess.delay_span_bug(sp, "`main` not found, but expected unclosed brace error"); - return; - } // There is no main function. let mut has_filename = true; diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 7c64df6a50e..0aaf85086e4 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -1,7 +1,7 @@ use Context::*; use rustc_hir as hir; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Destination, Movability, Node}; use rustc_middle::hir::map::Map; @@ -34,7 +34,7 @@ struct CheckLoopVisitor<'a, 'hir> { cx: Context, } -fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { +fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { tcx.hir().visit_item_likes_in_module( module_def_id, &mut CheckLoopVisitor { sess: &tcx.sess, hir_map: tcx.hir(), cx: Normal }, diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 769b389009b..7f36c59ad98 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -3,7 +3,7 @@ use rustc_ast::InlineAsmOptions; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::def_id::LocalDefId; +use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::{ExprKind, InlineAsmOperand, StmtKind}; use rustc_middle::query::Providers; @@ -23,7 +23,7 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { check_mod_naked_functions, ..*providers }; } -fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { +fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let items = tcx.hir_module_items(module_def_id); for def_id in items.definitions() { if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) { diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 7dec5b0acc8..f9d34ea71ba 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -364,10 +364,10 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet { let effective_visibilities = &tcx.effective_visibilities(()); - let any_library = - tcx.sess.crate_types().iter().any(|ty| { - *ty == CrateType::Rlib || *ty == CrateType::Dylib || *ty == CrateType::ProcMacro - }); + let any_library = tcx + .crate_types() + .iter() + .any(|ty| *ty == CrateType::Rlib || *ty == CrateType::Dylib || *ty == CrateType::ProcMacro); let mut reachable_context = ReachableContext { tcx, maybe_typeck_results: None, diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 25a3d38c144..9c265e8ec11 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -9,7 +9,7 @@ use rustc_attr::{ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::def_id::{LocalDefId, LocalModDefId, CRATE_DEF_ID}; use rustc_hir::hir_id::CRATE_HIR_ID; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant}; @@ -115,7 +115,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { let attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id)); debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs); - let depr = attr::find_deprecation(&self.tcx.sess, attrs); + let depr = attr::find_deprecation(self.tcx.sess, self.tcx.features(), attrs); let mut is_deprecated = false; if let Some((depr, span)) = &depr { is_deprecated = true; @@ -682,7 +682,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { /// Cross-references the feature names of unstable APIs with enabled /// features and possibly prints errors. -fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { +fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }); } @@ -732,13 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(hir::Impl { - of_trait: Some(ref t), - self_ty, - items, - constness, - .. - }) => { + hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => { let features = self.tcx.features(); if features.staged_api { let attrs = self.tcx.hir().attrs(item.hir_id()); @@ -769,7 +763,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable // needs to have an error emitted. if features.const_trait_impl - && *constness == hir::Constness::Const + && self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id()) && const_stab.is_some_and(|(stab, _)| stab.is_const_stable()) { self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span }); diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index fc6372cf99e..75e071f1fcf 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -43,7 +43,7 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) { fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) { // We only need to check for the presence of weak lang items if we're // emitting something that's not an rlib. - let needs_check = tcx.sess.crate_types().iter().any(|kind| match *kind { + let needs_check = tcx.crate_types().iter().any(|kind| match *kind { CrateType::Dylib | CrateType::ProcMacro | CrateType::Cdylib  | 
