diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 9193f309e37..0c378262dca 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -497,20 +497,6 @@ pub struct GenericParam { } impl GenericParam { - pub fn is_lifetime_param(&self) -> bool { - match self.kind { - GenericParamKind::Lifetime { .. } => true, - _ => false, - } - } - - pub fn is_type_param(&self) -> bool { - match self.kind { - GenericParamKind::Type { .. } => true, - _ => false, - } - } - pub fn name(&self) -> Name { match self.kind { GenericParamKind::Lifetime { name, .. } => name.name(), diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 40cf78edaec..9637b376b0e 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -29,7 +29,7 @@ use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr; -use hir; +use hir::{self, GenericParamKind}; use hir::def_id::LOCAL_CRATE; use hir::intravisit::{Visitor, NestedVisitorMap}; use hir::itemlikevisit::ItemLikeVisitor; @@ -38,7 +38,13 @@ // Returns true if the given set of generics implies that the item it's // associated with must be inlined. fn generics_require_inlining(generics: &hir::Generics) -> bool { - generics.params.iter().any(|param| param.is_type_param()) + for param in &generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => {} + GenericParamKind::Type { .. } => return true, + } + } + false } // Returns true if the given item must be inlined because it may be diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index c65a0e6d172..dfa205e6a34 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -532,21 +532,21 @@ fn visit_item(&mut self, item: &'tcx hir::Item) { } else { 0 }; - let mut next_early_index = index; + let mut type_count = 0; let lifetimes = generics.params.iter().filter_map(|param| { match param.kind { GenericParamKind::Lifetime { .. } => { Some(Region::early(&self.tcx.hir, &mut index, param)) } GenericParamKind::Type { .. } => { - next_early_index += 1; + type_count += 1; None } } }).collect(); let scope = Scope::Binder { lifetimes, - next_early_index, + next_early_index: index + type_count, abstract_type_parent: true, track_lifetime_uses, s: ROOT_SCOPE, @@ -698,7 +698,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) { let mut elision = None; let mut lifetimes = FxHashMap(); - let mut next_early_index = index; + let mut type_count = 0; for param in &generics.params { match param.kind { GenericParamKind::Lifetime { .. } => { @@ -712,10 +712,11 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) { } } GenericParamKind::Type { .. } => { - next_early_index += 1; + type_count += 1; } } } + let next_early_index = index + type_count; if let Some(elision_region) = elision { let scope = Scope::Elision { @@ -773,7 +774,7 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { let generics = &trait_item.generics; let mut index = self.next_early_index(); debug!("visit_ty: index = {}", index); - let mut next_early_index = index; + let mut type_count = 0; let lifetimes = generics.params .iter() .filter_map(|param| { @@ -782,7 +783,7 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { Some(Region::early(&self.tcx.hir, &mut index, param)) } GenericParamKind::Type { .. } => { - next_early_index += 1; + type_count += 1; None } } @@ -791,7 +792,7 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { let scope = Scope::Binder { lifetimes, - next_early_index, + next_early_index: index + type_count, s: self.scope, track_lifetime_uses: true, abstract_type_parent: true, @@ -896,7 +897,6 @@ fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl) { } fn visit_generics(&mut self, generics: &'tcx hir::Generics) { - check_mixed_explicit_and_in_band_defs( self.tcx, &generics.params.iter().filter_map(|param| { @@ -925,21 +925,21 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) { ref bound_generic_params, .. }) => { - if bound_generic_params.iter().any(|p| p.is_lifetime_param()) { + let lifetimes: FxHashMap<_, _> = bound_generic_params.iter() + .filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => { + Some(Region::late(&self.tcx.hir, param)) + } + _ => None, + } + }) + .collect(); + if !lifetimes.is_empty() { self.trait_ref_hack = true; let next_early_index = self.next_early_index(); let scope = Scope::Binder { - lifetimes: bound_generic_params - .iter() - .filter_map(|param| { - match param.kind { - GenericParamKind::Lifetime { .. } => { - Some(Region::late(&self.tcx.hir, param)) - } - _ => None, - } - }) - .collect(), + lifetimes, s: self.scope, next_early_index, track_lifetime_uses: true, @@ -990,7 +990,12 @@ fn visit_poly_trait_ref( || trait_ref .bound_generic_params .iter() - .any(|p| p.is_lifetime_param()) + .any(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => true, + _ => false, + } + }) { if self.trait_ref_hack { span_err!( @@ -1259,10 +1264,15 @@ fn compute_object_lifetime_defaults( let mut j = 0; generics.params.iter().find(|param| { match param.kind { - GenericParamKind::Lifetime { .. } => j += 1, + GenericParamKind::Lifetime { .. } => { + if i == j { + return true; + } + j += 1; + } _ => {} } - i == j + false }).unwrap() .name() .to_string() @@ -1530,25 +1540,23 @@ fn visit_early_late( } } - let mut next_early_index = index; - let lifetimes = generics.params - .iter() - .filter_map(|param| { - match param.kind { - GenericParamKind::Lifetime { .. } => { - if self.map.late_bound.contains(¶m.id) { - Some(Region::late(&self.tcx.hir, param)) - } else { - Some(Region::early(&self.tcx.hir, &mut index, param)) - } - } - GenericParamKind::Type { .. } => { - next_early_index += 1; - None + let mut type_count = 0; + let lifetimes = generics.params.iter().filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => { + if self.map.late_bound.contains(¶m.id) { + Some(Region::late(&self.tcx.hir, param)) + } else { + Some(Region::early(&self.tcx.hir, &mut index, param)) } } - }) - .collect(); + GenericParamKind::Type { .. } => { + type_count += 1; + None + } + } + }).collect(); + let next_early_index = index + type_count; let scope = Scope::Binder { lifetimes, diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 2abe361233f..2149e654281 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -810,51 +810,55 @@ fn get_lints(&self) -> LintArray { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { - if let hir::ItemEnum(ref enum_definition, ref gens) = it.node { - if gens.params.iter().all(|param| param.is_lifetime_param()) { - // sizes only make sense for non-generic types - let item_def_id = cx.tcx.hir.local_def_id(it.id); - let t = cx.tcx.type_of(item_def_id); - let ty = cx.tcx.erase_regions(&t); - let layout = cx.layout_of(ty).unwrap_or_else(|e| { - bug!("failed to get layout for `{}`: {}", t, e) - }); + if let hir::ItemEnum(ref enum_definition, ref generics) = it.node { + for param in &generics.params { + match param.kind { + hir::GenericParamKind::Lifetime { .. } => {}, + hir::GenericParamKind::Type { .. } => return, + } + } + // Sizes only make sense for non-generic types. + let item_def_id = cx.tcx.hir.local_def_id(it.id); + let t = cx.tcx.type_of(item_def_id); + let ty = cx.tcx.erase_regions(&t); + let layout = cx.layout_of(ty).unwrap_or_else(|e| { + bug!("failed to get layout for `{}`: {}", t, e) + }); - if let layout::Variants::Tagged { ref variants, ref tag, .. } = layout.variants { - let discr_size = tag.value.size(cx.tcx).bytes(); + if let layout::Variants::Tagged { ref variants, ref tag, .. } = layout.variants { + let discr_size = tag.value.size(cx.tcx).bytes(); - debug!("enum `{}` is {} bytes large with layout:\n{:#?}", - t, layout.size.bytes(), layout); + debug!("enum `{}` is {} bytes large with layout:\n{:#?}", + t, layout.size.bytes(), layout); - let (largest, slargest, largest_index) = enum_definition.variants - .iter() - .zip(variants) - .map(|(variant, variant_layout)| { - // Subtract the size of the enum discriminant - let bytes = variant_layout.size.bytes() - .saturating_sub(discr_size); + let (largest, slargest, largest_index) = enum_definition.variants + .iter() + .zip(variants) + .map(|(variant, variant_layout)| { + // Subtract the size of the enum discriminant. + let bytes = variant_layout.size.bytes() + .saturating_sub(discr_size); - debug!("- variant `{}` is {} bytes large", variant.node.name, bytes); - bytes - }) - .enumerate() - .fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l { - (size, l, idx) - } else if size > s { - (l, size, li) - } else { - (l, s, li) - }); + debug!("- variant `{}` is {} bytes large", variant.node.name, bytes); + bytes + }) + .enumerate() + .fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l { + (size, l, idx) + } else if size > s { + (l, size, li) + } else { + (l, s, li) + }); - // we only warn if the largest variant is at least thrice as large as - // the second-largest. - if largest > slargest * 3 && slargest > 0 { - cx.span_lint(VARIANT_SIZE_DIFFERENCES, - enum_definition.variants[largest_index].span, - &format!("enum variant is more than three times larger \ - ({} bytes) than the next largest", - largest)); - } + // We only warn if the largest variant is at least thrice as large as + // the second-largest. + if largest > slargest * 3 && slargest > 0 { + cx.span_lint(VARIANT_SIZE_DIFFERENCES, + enum_definition.variants[largest_index].span, + &format!("enum variant is more than three times larger \ + ({} bytes) than the next largest", + largest)); } } }