diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index feefc43f4013e..0e885d82f7894 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -101,7 +101,8 @@ impl PathResolution { } // Definition mapping -pub type DefMap = NodeMap; +pub type DefMap = NodeMap; +pub type AssocMap = NodeMap; // This is the replacement export map. It maps a module to all of the exports // within. pub type ExportMap = NodeMap>; diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7b04259d1c3be..4b2d30c1f8956 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -44,7 +44,7 @@ use hir; use hir::map::Definitions; use hir::map::definitions::DefPathData; use hir::def_id::{DefIndex, DefId}; -use hir::def::{Def, PathResolution}; +use hir::def::Def; use session::Session; use std::collections::BTreeMap; @@ -74,7 +74,7 @@ pub trait Resolver { fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def; // Obtain the resolution for a node id - fn get_resolution(&mut self, id: NodeId) -> Option; + fn get_resolution(&mut self, id: NodeId) -> Option; // Record the resolution of a path or binding generated by the lowerer when expanding. fn record_resolution(&mut self, id: NodeId, def: Def); @@ -873,7 +873,7 @@ impl<'a> LoweringContext<'a> { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, pth1, ref sub) => { self.with_parent_def(p.id, |this| { - match this.resolver.get_resolution(p.id).map(|d| d.base_def) { + match this.resolver.get_resolution(p.id) { // `None` can occur in body-less function signatures None | Some(Def::Local(..)) => { hir::PatKind::Binding(this.lower_binding_mode(binding_mode), diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 0deea94146361..2de4bdbc96606 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -57,7 +57,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Struct(..) => { - match dm.get(&pat.id).map(|d| d.full_def()) { + match dm.get(&pat.id).cloned() { Some(Def::Variant(..)) | Some(Def::VariantCtor(..)) => true, _ => false } @@ -70,7 +70,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool { match pat.node { PatKind::Path(..) => { - match dm.get(&pat.id).map(|d| d.full_def()) { + match dm.get(&pat.id).cloned() { Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true, _ => false } @@ -173,7 +173,7 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec { PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Struct(..) => { - match dm.get(&p.id).map(|d| d.full_def()) { + match dm.get(&p.id).cloned() { Some(Def::Variant(id)) | Some(Def::VariantCtor(id, ..)) => variants.push(id), _ => () diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index f47eab013c2b2..db9392f09d604 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -89,13 +89,16 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn lookup_and_handle_definition(&mut self, id: ast::NodeId) { let def = self.tcx.expect_def(id); - // If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar` + // If it is an associated item, mark the type as alive match def { - Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_) - if self.tcx.trait_of_item(def.def_id()).is_some() => { - if let Some(substs) = self.tcx.tables().item_substs.get(&id) { - if let ty::TyAdt(tyid, _) = substs.substs.type_at(0).sty { - self.check_def_id(tyid.did); + Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_) => { + if let Some(resolution) = self.tcx.assoc_map.get(&id) { + let base_def = resolution.base_def; + match base_def { + Def::Struct(..) | Def::Enum(..) | Def::TyAlias(..) => { + self.check_def_id(base_def.def_id()); + } + _ => {} } } } @@ -430,6 +433,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) + | hir::ItemTy(..) | hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) => true, diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index a0043d0a88620..be39dbf650afe 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -247,8 +247,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir::TyPath(None, ref path) => { // if this path references a trait, then this will resolve to // a trait ref, which introduces a binding scope. - match self.def_map.get(&ty.id).map(|d| (d.base_def, d.depth)) { - Some((Def::Trait(..), 0)) => { + match self.def_map.get(&ty.id).cloned() { + Some(Def::Trait(..)) => { self.with(LateScope(&[], self.scope), |_, this| { this.visit_path(path, ty.id); }); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 20855c46b6800..6006b3108cd39 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -14,7 +14,7 @@ use dep_graph::{DepGraph, DepTrackingMap}; use session::Session; use middle; use hir::TraitMap; -use hir::def::DefMap; +use hir::def::{AssocMap, DefMap}; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use hir::map as ast_map; use hir::map::{DefKey, DefPathData, DisambiguatedDefPathData}; @@ -379,11 +379,14 @@ pub struct GlobalCtxt<'tcx> { pub sess: &'tcx Session, - /// Map from path id to the results from resolve; generated - /// initially by resolve and updated during typeck in some cases - /// (e.g., UFCS paths) + /// Map from path id to definition; generated + /// initially by resolve and updated during typeck for + /// associated items pub def_map: RefCell, + /// Map from path id to partial resolution for associated items + pub assoc_map: AssocMap, + /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. pub trait_map: TraitMap, @@ -769,6 +772,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn create_and_enter(s: &'tcx Session, arenas: &'tcx CtxtArenas<'tcx>, def_map: DefMap, + assoc_map: AssocMap, trait_map: TraitMap, named_region_map: resolve_lifetime::NamedRegionMap, map: ast_map::Map<'tcx>, @@ -798,6 +802,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { variance_computed: Cell::new(false), sess: s, def_map: RefCell::new(def_map), + assoc_map: assoc_map, trait_map: trait_map, tables: RefCell::new(Tables::empty()), impl_trait_refs: RefCell::new(DepTrackingMap::new(dep_graph.clone())), diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e94e93158c47a..06347c919a3ca 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2259,18 +2259,24 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns a path resolution for node id if it exists, panics otherwise. pub fn expect_resolution(self, id: NodeId) -> PathResolution { - *self.def_map.borrow().get(&id).expect("no def-map entry for node id") + if let Some(def) = self.def_map.borrow().get(&id) { + return PathResolution::new(*def); + } + if let Some(resolution) = self.assoc_map.get(&id) { + return *resolution; + } + panic!("no def-map entry for node id"); } /// Returns a fully resolved definition for node id if it exists, panics otherwise. pub fn expect_def(self, id: NodeId) -> Def { - self.expect_resolution(id).full_def() + *self.def_map.borrow().get(&id).expect("no def-map entry for node id") } /// Returns a fully resolved definition for node id if it exists, or none if no - /// definition exists, panics on partial resolutions to catch errors. + /// definition exists or only a partial resolution exists. pub fn expect_def_or_none(self, id: NodeId) -> Option { - self.def_map.borrow().get(&id).map(|resolution| resolution.full_def()) + self.def_map.borrow().get(&id).cloned() } // Returns `ty::VariantDef` if `def` refers to a struct, diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index b594fe9853a43..40859ffecf1c4 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -19,7 +19,7 @@ use rustc::hir::map as ast_map; use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::cstore::InlinedItem; use rustc::traits; -use rustc::hir::def::{Def, CtorKind, PathResolution}; +use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; use rustc::hir::pat_util::def_to_path; use rustc::ty::{self, Ty, TyCtxt}; @@ -284,7 +284,7 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir::ExprCall(ref callee, ref args) => { let def = tcx.expect_def(callee.id); if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) { - entry.insert(PathResolution::new(def)); + entry.insert(def); } let path = match def { Def::StructCtor(def_id, CtorKind::Fn) | diff --git a/src/librustc_data_structures/graph/tests.rs b/src/librustc_data_structures/graph/tests.rs index a87410e6e1c8c..bdefc39a61a85 100644 --- a/src/librustc_data_structures/graph/tests.rs +++ b/src/librustc_data_structures/graph/tests.rs @@ -11,8 +11,6 @@ use graph::*; use std::fmt::Debug; -type TestNode = Node<&'static str>; -type TestEdge = Edge<&'static str>; type TestGraph = Graph<&'static str, &'static str>; fn create_graph() -> TestGraph { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 228119e6cc7da..578e2558f34ea 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -10,7 +10,7 @@ use rustc::hir; use rustc::hir::{map as hir_map, FreevarMap, TraitMap}; -use rustc::hir::def::DefMap; +use rustc::hir::def::{AssocMap, DefMap}; use rustc::hir::lowering::lower_crate; use rustc_data_structures::blake2b::Blake2bHasher; use rustc_data_structures::fmt_wrap::FmtWrap; @@ -64,6 +64,7 @@ use derive_registrar; #[derive(Clone)] pub struct Resolutions { pub def_map: DefMap, + pub assoc_map: AssocMap, pub freevars: FreevarMap, pub trait_map: TraitMap, pub maybe_unused_trait_imports: NodeSet, @@ -790,6 +791,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session, }, resolutions: Resolutions { def_map: resolver.def_map, + assoc_map: resolver.assoc_map, freevars: resolver.freevars, trait_map: resolver.trait_map, maybe_unused_trait_imports: resolver.maybe_unused_trait_imports, @@ -866,6 +868,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, TyCtxt::create_and_enter(sess, arenas, resolutions.def_map, + resolutions.assoc_map, resolutions.trait_map, named_region_map, hir_map, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index a4f0e29038477..8d5a7942cf4ae 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -137,6 +137,7 @@ fn test_env(source_string: &str, TyCtxt::create_and_enter(&sess, &arenas, resolutions.def_map, + resolutions.assoc_map, resolutions.trait_map, named_region_map.unwrap(), ast_map, diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 4bad264ac8749..1baf4931d5719 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -802,7 +802,12 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { if let Some(def) = self.tcx.def_map.borrow().get(&id) { debug!("hash_resolve: id={:?} def={:?} st={:?}", id, def, self.st); - self.hash_partial_def(def); + self.hash_def(*def); + } + + if let Some(partial_def) = self.tcx.assoc_map.get(&id) { + debug!("hash_resolve: id={:?} partial_def={:?} st={:?}", id, partial_def, self.st); + self.hash_partial_def(partial_def); } if let Some(traits) = self.tcx.trait_map.get(&id) { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index e2fa535bb44a0..b884c55ac224a 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -18,7 +18,7 @@ use schema::*; use rustc::middle::cstore::{InlinedItem, InlinedItemRef}; use rustc::middle::const_qualif::ConstQualif; -use rustc::hir::def::{self, Def}; +use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt, Ty}; @@ -141,7 +141,7 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata, for (id, entry) in ast.side_tables.decode((cdata, tcx, id_ranges)) { match entry { TableEntry::Def(def) => { - tcx.def_map.borrow_mut().insert(id, def::PathResolution::new(def)); + tcx.def_map.borrow_mut().insert(id, def); } TableEntry::NodeType(ty) => { tcx.tables.borrow_mut().node_types.insert(id, ty); diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index 5f76f865c4aca..0ae3a87557c53 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -251,7 +251,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_expr(&mut self, e: &'ast hir::Expr) { match e.node { hir::ExprPath(..) => { - match self.def_map.get(&e.id).map(|d| d.base_def) { + match self.def_map.get(&e.id).cloned() { Some(Def::Static(def_id, _)) | Some(Def::AssociatedConst(def_id)) | Some(Def::Const(def_id)) => { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c72ba7bb68766..62a293ec3a98b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1089,6 +1089,7 @@ pub struct Resolver<'a> { primitive_type_table: PrimitiveTypeTable, pub def_map: DefMap, + pub assoc_map: AssocMap, pub freevars: FreevarMap, freevars_seen: NodeMap>, pub export_map: ExportMap, @@ -1223,12 +1224,12 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { } } - fn get_resolution(&mut self, id: NodeId) -> Option { + fn get_resolution(&mut self, id: NodeId) -> Option { self.def_map.get(&id).cloned() } fn record_resolution(&mut self, id: NodeId, def: Def) { - self.def_map.insert(id, PathResolution::new(def)); + self.def_map.insert(id, def); } fn definitions(&mut self) -> &mut Definitions { @@ -1306,6 +1307,7 @@ impl<'a> Resolver<'a> { primitive_type_table: PrimitiveTypeTable::new(), def_map: NodeMap(), + assoc_map: NodeMap(), freevars: NodeMap(), freevars_seen: NodeMap(), export_map: NodeMap(), @@ -2141,7 +2143,7 @@ impl<'a> Resolver<'a> { pat.walk(&mut |pat| { if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node { if sub_pat.is_some() || match self.def_map.get(&pat.id) { - Some(&PathResolution { base_def: Def::Local(..), .. }) => true, + Some(&Def::Local(..)) => true, _ => false, } { let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode }; @@ -2849,9 +2851,9 @@ impl<'a> Resolver<'a> { if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) { // Look for a field with the same name in the current self_type. - if let Some(resolution) = self.def_map.get(&node_id) { - match resolution.base_def { - Def::Struct(did) | Def::Union(did) if resolution.depth == 0 => { + if let Some(def) = self.def_map.get(&node_id) { + match *def { + Def::Struct(did) | Def::Union(did) => { if let Some(field_names) = self.field_names.get(&did) { if field_names.iter().any(|&field_name| name == field_name) { return Field; @@ -3327,8 +3329,20 @@ impl<'a> Resolver<'a> { fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) { debug!("(recording def) recording {:?} for {}", resolution, node_id); - if let Some(prev_res) = self.def_map.insert(node_id, resolution) { - panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution); + + if resolution.depth != 0 { + // partial resolution + if let Some(prev_res) = self.assoc_map.insert(node_id, resolution) { + panic!("path resolved multiple times ({:?} before, {:?} now)", + prev_res, + resolution); + } + return; + } + + let def = resolution.base_def; + if let Some(prev_def) = self.def_map.insert(node_id, def) { + panic!("path resolved multiple times ({:?} before, {:?} now)", prev_def, def); } } @@ -3343,10 +3357,10 @@ impl<'a> Resolver<'a> { }; let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier).collect(); - let mut path_resolution = err_path_resolution(); + let mut def = Def::Err; let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, Some(path.span)) { Success(module) => { - path_resolution = PathResolution::new(module.def().unwrap()); + def = module.def().unwrap(); ty::Visibility::Restricted(module.normal_ancestor_id.unwrap()) } Indeterminate => unreachable!(), @@ -3357,7 +3371,7 @@ impl<'a> Resolver<'a> { ty::Visibility::Public } }; - self.def_map.insert(id, path_resolution); + self.def_map.insert(id, def); if !self.is_accessible(vis) { let msg = format!("visibilities can only be restricted to ancestor modules"); self.session.span_err(path.span, &msg); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 47bd1f71084aa..a54f05dac92a1 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -678,7 +678,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() { - this.def_map.entry(directive.id).or_insert(PathResolution::new(binding.def())); + this.def_map.entry(directive.id).or_insert(binding.def()); }); debug!("(resolving single import) successfully resolved import"); @@ -716,8 +716,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // Record the destination of this import if let Some(did) = module.def_id() { - let resolution = PathResolution::new(Def::Mod(did)); - self.def_map.insert(directive.id, resolution); + let def = Def::Mod(did); + self.def_map.insert(directive.id, def); } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c5db8bc8cedc7..a40b5bdf1f15c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -50,7 +50,7 @@ use rustc_const_eval::eval_length; use hir::{self, SelfKind}; -use hir::def::{Def, PathResolution}; +use hir::def::Def; use hir::def_id::DefId; use hir::print as pprust; use middle::resolve_lifetime as rl; @@ -1759,7 +1759,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // Write back the new resolution. if path_res.depth != 0 { - tcx.def_map.borrow_mut().insert(ast_ty.id, PathResolution::new(def)); + tcx.def_map.borrow_mut().insert(ast_ty.id, def); } ty diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 3ffbbd1be8016..58d642482d266 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -219,9 +219,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let hir::ExprCall(ref expr, _) = call_expr.node { let tcx = self.tcx; - if let Some(pr) = tcx.def_map.borrow().get(&expr.id) { - if pr.depth == 0 && pr.base_def != Def::Err { - if let Some(span) = tcx.map.span_if_local(pr.base_def.def_id()) { + if let Some(def) = tcx.def_map.borrow().get(&expr.id).cloned() { + if def != Def::Err { + if let Some(span) = tcx.map.span_if_local(def.def_id()) { err.span_note(span, "defined here"); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bb6b2a3116ba3..3a6dd16d1f38d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -83,7 +83,7 @@ use self::TupleArgumentsFlag::*; use astconv::{AstConv, ast_region_to_region, PathParamMode}; use dep_graph::DepNode; use fmt_macros::{Parser, Piece, Position}; -use hir::def::{Def, CtorKind, PathResolution}; +use hir::def::{Def, CtorKind}; use hir::def_id::{DefId, LOCAL_CRATE}; use hir::pat_util; use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin, @@ -3893,7 +3893,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { true); // Write back the new resolution. if path_res.depth != 0 { - self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def)); + self.tcx.def_map.borrow_mut().insert(node_id, def); } (def, ty) } @@ -3942,7 +3942,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Write back the new resolution. - self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def)); + self.tcx.def_map.borrow_mut().insert(node_id, def); (def, Some(ty), slice::ref_slice(item_segment)) } } diff --git a/src/test/compile-fail/issue-32119.rs b/src/test/compile-fail/issue-32119.rs index 4743b779ef63e..e630a01a59300 100644 --- a/src/test/compile-fail/issue-32119.rs +++ b/src/test/compile-fail/issue-32119.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(rustc_attrs)] +#![allow(dead_code)] pub type T = (); mod foo { pub use super::T; } diff --git a/src/test/compile-fail/lint-dead-code-type-alias.rs b/src/test/compile-fail/lint-dead-code-type-alias.rs new file mode 100644 index 0000000000000..6991fca5fd14f --- /dev/null +++ b/src/test/compile-fail/lint-dead-code-type-alias.rs @@ -0,0 +1,20 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(dead_code)] + +type Used = u8; +type Unused = u8; //~ ERROR: type alias is never used + +fn id(x: Used) -> Used { x } + +fn main() { + id(0); +} diff --git a/src/test/compile-fail/macro-tt-matchers.rs b/src/test/compile-fail/macro-tt-matchers.rs index 945490cefb95a..969f1500717d7 100644 --- a/src/test/compile-fail/macro-tt-matchers.rs +++ b/src/test/compile-fail/macro-tt-matchers.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(rustc_attrs)] +#![allow(dead_code)] macro_rules! foo { ($x:tt) => (type Alias = $x;)