});
if item_lowered {
- let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
+ let item_generics = match self.lctx.items.get(&item.id).unwrap().node {
hir::Item_::ItemImpl(_, _, _, ref generics, ..)
| hir::Item_::ItemTrait(_, _, ref generics, ..) => {
generics.params.clone()
_ => HirVec::new(),
};
- self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
+ self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| {
let this = &mut ItemLowerer { lctx: this };
if let ItemKind::Impl(_, _, _, _, ref opt_trait_ref, _, _) = item.node {
this.with_trait_impl_ref(opt_trait_ref, |this| {
}
impl LifetimeDefOrigin {
- fn from_is_in_band(is_in_band: bool) -> Self {
- if is_in_band {
- LifetimeDefOrigin::InBand
- } else {
- LifetimeDefOrigin::Explicit
+ fn from_param(param: &GenericParam) -> Self {
+ match param.kind {
+ GenericParamKind::Lifetime { in_band } => {
+ if in_band {
+ LifetimeDefOrigin::InBand
+ } else {
+ LifetimeDefOrigin::Explicit
+ }
+ }
+ _ => bug!("expected a lifetime param"),
}
}
}
Free(DefId, /* lifetime decl */ DefId),
}
-fn new_region(hir_map: &Map, param: &GenericParam) -> (DefId, LifetimeDefOrigin) {
- let def_id = hir_map.local_def_id(param.id);
- let origin = match param.kind {
- GenericParamKind::Lifetime { in_band, .. } => {
- LifetimeDefOrigin::from_is_in_band(in_band)
- }
- _ => bug!("expected a lifetime param"),
- };
- (def_id, origin)
-}
-
impl Region {
fn early(hir_map: &Map, index: &mut u32, param: &GenericParam) -> (ParamName, Region) {
let i = *index;
*index += 1;
- let (def_id, origin) = new_region(hir_map, param);
+ let def_id = hir_map.local_def_id(param.id);
+ let origin = LifetimeDefOrigin::from_param(param);
debug!("Region::early: index={} def_id={:?}", i, def_id);
(param.name, Region::EarlyBound(i, def_id, origin))
}
fn late(hir_map: &Map, param: &GenericParam) -> (ParamName, Region) {
let depth = ty::INNERMOST;
- let (def_id, origin) = new_region(hir_map, param);
+ let def_id = hir_map.local_def_id(param.id);
+ let origin = LifetimeDefOrigin::from_param(param);
debug!(
"Region::late: param={:?} depth={:?} def_id={:?} origin={:?}",
param,
Set1::One(Region::Static)
} else {
generics.params.iter().filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { in_band } => {
- Some((param.id, hir::LifetimeName::Param(param.name), in_band))
+ GenericParamKind::Lifetime { .. } => {
+ Some((
+ param.id,
+ hir::LifetimeName::Param(param.name),
+ LifetimeDefOrigin::from_param(param),
+ ))
}
_ => None,
})
.enumerate()
.find(|&(_, (_, lt_name, _))| lt_name == name)
- .map_or(Set1::Many, |(i, (id, _, in_band))| {
+ .map_or(Set1::Many, |(i, (id, _, origin))| {
let def_id = tcx.hir.local_def_id(id);
- let origin = LifetimeDefOrigin::from_is_in_band(in_band);
Set1::One(Region::EarlyBound(i as u32, def_id, origin))
})
}
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();
-
- 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);
-
- 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));
+ match cx.layout_of(ty) {
+ Ok(layout) => {
+ let variants = &layout.variants;
+ if let layout::Variants::Tagged { ref variants, ref tag, .. } = variants {
+ let discr_size = tag.value.size(cx.tcx).bytes();
+
+ 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);
+
+ 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));
+ }
+ }
+ }
+ Err(ty::layout::LayoutError::Unknown(_)) => return,
+ Err(err @ ty::layout::LayoutError::SizeOverflow(_)) => {
+ bug!("failed to get layout for `{}`: {}", t, err);
}
}
}
let mut function_type_rib = Rib::new(rib_kind);
let mut seen_bindings = FxHashMap();
generics.params.iter().for_each(|param| match param.kind {
- GenericParamKind::Type { .. } => {
- let ident = param.ident.modern();
- debug!("with_type_parameter_rib: {}", param.id);
-
- if seen_bindings.contains_key(&ident) {
- let span = seen_bindings.get(&ident).unwrap();
- let err = ResolutionError::NameAlreadyUsedInTypeParameterList(
- ident.name,
- span,
- );
- resolve_error(self, param.ident.span, err);
- }
- seen_bindings.entry(ident).or_insert(param.ident.span);
-
- // Plain insert (no renaming).
- let def = Def::TyParam(self.definitions.local_def_id(param.id));
- function_type_rib.bindings.insert(ident, def);
- self.record_def(param.id, PathResolution::new(def));
+ GenericParamKind::Lifetime { .. } => {}
+ GenericParamKind::Type { .. } => {
+ let ident = param.ident.modern();
+ debug!("with_type_parameter_rib: {}", param.id);
+
+ if seen_bindings.contains_key(&ident) {
+ let span = seen_bindings.get(&ident).unwrap();
+ let err = ResolutionError::NameAlreadyUsedInTypeParameterList(
+ ident.name,
+ span,
+ );
+ resolve_error(self, param.ident.span, err);
}
- _ => {}
+ seen_bindings.entry(ident).or_insert(param.ident.span);
+
+ // Plain insert (no renaming).
+ let def = Def::TyParam(self.definitions.local_def_id(param.id));
+ function_type_rib.bindings.insert(ident, def);
+ self.record_def(param.id, PathResolution::new(def));
+ }
});
self.ribs[TypeNS].push(function_type_rib);
}
self_ty: Ty<'tcx>)
-> ty::TraitRef<'tcx>
{
- self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
+ self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
let trait_def_id = self.trait_def_id(trait_ref);
self.ast_path_to_mono_trait_ref(trait_ref.path.span,
debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
- self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
+ self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
let (substs, assoc_bindings) =
self.create_substs_for_ast_trait_ref(trait_ref.path.span,
debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
- self.prohibit_type_params(slice::from_ref(item_segment));
+ self.prohibit_generics(slice::from_ref(item_segment));
// Find the type of the associated item, and the trait where the associated
// item is declared.
let tcx = self.tcx();
let trait_def_id = tcx.parent_def_id(item_def_id).unwrap();
- self.prohibit_type_params(slice::from_ref(item_segment));
+ self.prohibit_generics(slice::from_ref(item_segment));
let self_ty = if let Some(ty) = opt_self_ty {
ty
self.normalize_ty(span, tcx.mk_projection(item_def_id, trait_ref.substs))
}
- pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
+ pub fn prohibit_generics(&self, segments: &[hir::PathSegment]) {
for segment in segments {
segment.with_generic_args(|generic_args| {
let (mut err_for_lt, mut err_for_ty) = (false, false);
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) |
Def::Union(did) | Def::TyForeign(did) => {
assert_eq!(opt_self_ty, None);
- self.prohibit_type_params(path.segments.split_last().unwrap().1);
+ self.prohibit_generics(path.segments.split_last().unwrap().1);
self.ast_path_to_ty(span, did, path.segments.last().unwrap())
}
Def::Variant(did) if permit_variants => {
// Convert "variant type" as if it were a real type.
// The resulting `Ty` is type of the variant's enum for now.
assert_eq!(opt_self_ty, None);
- self.prohibit_type_params(path.segments.split_last().unwrap().1);
+ self.prohibit_generics(path.segments.split_last().unwrap().1);
self.ast_path_to_ty(span,
tcx.parent_def_id(did).unwrap(),
path.segments.last().unwrap())
}
Def::TyParam(did) => {
assert_eq!(opt_self_ty, None);
- self.prohibit_type_params(&path.segments);
+ self.prohibit_generics(&path.segments);
let node_id = tcx.hir.as_local_node_id(did).unwrap();
let item_id = tcx.hir.get_parent_node(node_id);
// Self in impl (we know the concrete type).
assert_eq!(opt_self_ty, None);
- self.prohibit_type_params(&path.segments);
+ self.prohibit_generics(&path.segments);
tcx.at(span).type_of(def_id)
}
Def::SelfTy(Some(_), None) => {
// Self in trait.
assert_eq!(opt_self_ty, None);
- self.prohibit_type_params(&path.segments);
+ self.prohibit_generics(&path.segments);
tcx.mk_self_type()
}
Def::AssociatedTy(def_id) => {
- self.prohibit_type_params(&path.segments[..path.segments.len()-2]);
+ self.prohibit_generics(&path.segments[..path.segments.len()-2]);
self.qpath_to_ty(span,
opt_self_ty,
def_id,
}
Def::PrimTy(prim_ty) => {
assert_eq!(opt_self_ty, None);
- self.prohibit_type_params(&path.segments);
+ self.prohibit_generics(&path.segments);
match prim_ty {
hir::TyBool => tcx.types.bool,
hir::TyChar => tcx.types.char,
// errors if type parameters are provided in an inappropriate place.
let poly_segments = type_segment.is_some() as usize +
fn_segment.is_some() as usize;
- AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
+ AstConv::prohibit_generics(self, &segments[..segments.len() - poly_segments]);
match def {
Def::Local(nid) | Def::Upvar(nid, ..) => {
}
fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- item: &hir::Item,
- ast_generics: &hir::Generics)
+ item: &hir::Item,
+ hir_generics: &hir::Generics)
{
let item_def_id = tcx.hir.local_def_id(item.id);
let ty = tcx.type_of(item_def_id);
continue;
}
- let param = &ast_generics.params[index];
+ let param = &hir_generics.params[index];
report_bivariance(tcx, param.span, param.name.name());
}
}
for param in &generics.params {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {}
- hir::GenericParamKind::Type { ref default, .. } if default.is_some() => {
+ hir::GenericParamKind::Type { default: Some(_), .. } => {
let def_id = self.tcx.hir.local_def_id(param.id);
self.tcx.type_of(def_id);
}