提交 991efa42 编写于 作者: V varkor

Address various comments

上级 91712bc6
......@@ -379,7 +379,7 @@ fn visit_item(&mut self, item: &'lcx Item) {
});
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()
......@@ -387,7 +387,7 @@ fn visit_item(&mut self, item: &'lcx Item) {
_ => 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| {
......
......@@ -49,11 +49,16 @@ pub enum LifetimeDefOrigin {
}
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"),
}
}
}
......@@ -82,29 +87,20 @@ pub enum Region {
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,
......@@ -1300,16 +1296,19 @@ fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::ParamBound]) {
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))
})
}
......
......@@ -821,43 +821,50 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
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);
}
}
}
......
......@@ -2208,26 +2208,26 @@ fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<
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);
}
......
......@@ -379,7 +379,7 @@ pub fn instantiate_mono_trait_ref(&self,
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,
......@@ -413,7 +413,7 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self,
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,
......@@ -891,7 +891,7 @@ pub fn associated_path_def_to_ty(&self,
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.
......@@ -968,7 +968,7 @@ fn qpath_to_ty(&self,
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
......@@ -993,7 +993,7 @@ fn qpath_to_ty(&self,
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);
......@@ -1053,21 +1053,21 @@ pub fn def_to_ty(&self,
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);
......@@ -1080,18 +1080,18 @@ pub fn def_to_ty(&self,
// 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,
......@@ -1100,7 +1100,7 @@ pub fn def_to_ty(&self,
}
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,
......
......@@ -4782,7 +4782,7 @@ pub fn instantiate_value_path(&self,
// 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, ..) => {
......
......@@ -602,8 +602,8 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
}
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);
......@@ -631,7 +631,7 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
continue;
}
let param = &ast_generics.params[index];
let param = &hir_generics.params[index];
report_bivariance(tcx, param.span, param.name.name());
}
}
......
......@@ -117,7 +117,7 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册