Skip to content

Commit

Permalink
Auto merge of #51880 - varkor:generics-hir-generalisation-followup, r…
Browse files Browse the repository at this point in the history
…=eddyb

The Great Generics Generalisation: HIR Followup

Addresses the final comments in #48149.

r? @eddyb, but there are a few things I have yet to clean up. Making the PR now to more easily see when things break.

cc @yodaldevoid
  • Loading branch information
bors committed Aug 20, 2018
2 parents bf1e461 + ee9bd0f commit 1558ae7
Show file tree
Hide file tree
Showing 57 changed files with 973 additions and 801 deletions.
29 changes: 25 additions & 4 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,13 @@ impl GenericArg {
GenericArg::Type(t) => t.span,
}
}

pub fn id(&self) -> NodeId {
match self {
GenericArg::Lifetime(l) => l.id,
GenericArg::Type(t) => t.id,
}
}
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
Expand Down Expand Up @@ -445,6 +452,22 @@ impl GenericArgs {
}
bug!("GenericArgs::inputs: not a `Fn(T) -> U`");
}

pub fn own_counts(&self) -> GenericParamCount {
// We could cache this as a property of `GenericParamCount`, but
// the aim is to refactor this away entirely eventually and the
// presence of this method will be a constant reminder.
let mut own_counts: GenericParamCount = Default::default();

for arg in &self.args {
match arg {
GenericArg::Lifetime(_) => own_counts.lifetimes += 1,
GenericArg::Type(_) => own_counts.types += 1,
};
}

own_counts
}
}

/// A modifier on a bound, currently this is only used for `?Sized`, where the
Expand Down Expand Up @@ -503,6 +526,7 @@ pub struct GenericParam {
pub kind: GenericParamKind,
}

#[derive(Default)]
pub struct GenericParamCount {
pub lifetimes: usize,
pub types: usize,
Expand Down Expand Up @@ -533,10 +557,7 @@ impl Generics {
// We could cache this as a property of `GenericParamCount`, but
// the aim is to refactor this away entirely eventually and the
// presence of this method will be a constant reminder.
let mut own_counts = GenericParamCount {
lifetimes: 0,
types: 0,
};
let mut own_counts: GenericParamCount = Default::default();

for param in &self.params {
match param.kind {
Expand Down
23 changes: 5 additions & 18 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use hir::map as hir_map;
use hir::def::Def;
use hir::def_id::{DefId, CrateNum};
use rustc_data_structures::sync::Lrc;
use ty::{self, TyCtxt, GenericParamDefKind};
use ty::{self, TyCtxt};
use ty::query::Providers;
use middle::privacy;
use session::config;
Expand All @@ -34,18 +34,6 @@ use hir::intravisit::{Visitor, NestedVisitorMap};
use hir::itemlikevisit::ItemLikeVisitor;
use hir::intravisit;

// Returns true if the given set of generics implies that the item it's
// associated with must be inlined.
fn generics_require_inlining(generics: &ty::Generics) -> bool {
for param in &generics.params {
match param.kind {
GenericParamDefKind::Lifetime { .. } => {}
GenericParamDefKind::Type { .. } => return true,
}
}
false
}

// Returns true if the given item must be inlined because it may be
// monomorphized or it was marked with `#[inline]`. This will only return
// true for functions.
Expand All @@ -60,7 +48,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
hir::ItemKind::Impl(..) |
hir::ItemKind::Fn(..) => {
let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
generics_require_inlining(generics)
generics.requires_monomorphization(tcx)
}
_ => false,
}
Expand All @@ -71,7 +59,7 @@ fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_src: DefId) -> bool {
let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id.owner_def_id());
let generics = tcx.generics_of(tcx.hir.local_def_id(impl_item.id));
if codegen_fn_attrs.requests_inline() || generics_require_inlining(generics) {
if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) {
return true
}
if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) {
Expand Down Expand Up @@ -189,8 +177,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::ImplItemKind::Method(..) => {
let attrs = self.tcx.codegen_fn_attrs(def_id);
let generics = self.tcx.generics_of(def_id);
if generics_require_inlining(&generics) ||
attrs.requests_inline() {
if generics.requires_monomorphization(self.tcx) || attrs.requests_inline() {
true
} else {
let impl_did = self.tcx
Expand All @@ -203,7 +190,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match self.tcx.hir.expect_item(impl_node_id).node {
hir::ItemKind::Impl(..) => {
let generics = self.tcx.generics_of(impl_did);
generics_require_inlining(&generics)
generics.requires_monomorphization(self.tcx)
}
_ => false
}
Expand Down
10 changes: 4 additions & 6 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ impl GenericParamDef {
}
}

#[derive(Default)]
pub struct GenericParamCount {
pub lifetimes: usize,
pub types: usize,
Expand Down Expand Up @@ -913,15 +914,12 @@ impl<'a, 'gcx, 'tcx> Generics {
// We could cache this as a property of `GenericParamCount`, but
// the aim is to refactor this away entirely eventually and the
// presence of this method will be a constant reminder.
let mut own_counts = GenericParamCount {
lifetimes: 0,
types: 0,
};
let mut own_counts: GenericParamCount = Default::default();

for param in &self.params {
match param.kind {
GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
GenericParamDefKind::Type {..} => own_counts.types += 1,
GenericParamDefKind::Type { .. } => own_counts.types += 1,
};
}

Expand All @@ -931,7 +929,7 @@ impl<'a, 'gcx, 'tcx> Generics {
pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
for param in &self.params {
match param.kind {
GenericParamDefKind::Type {..} => return true,
GenericParamDefKind::Type { .. } => return true,
GenericParamDefKind::Lifetime => {}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/librustc/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
mk_kind: &mut F)
where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
{

if let Some(def_id) = defs.parent {
let parent_defs = tcx.generics_of(def_id);
Substs::fill_item(substs, tcx, parent_defs, mk_kind);
Expand Down
5 changes: 1 addition & 4 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,7 @@ impl PrintContext {
let verbose = self.is_verbose;
let mut num_supplied_defaults = 0;
let mut has_self = false;
let mut own_counts = GenericParamCount {
lifetimes: 0,
types: 0,
};
let mut own_counts: GenericParamCount = Default::default();
let mut is_value_path = false;
let fn_trait_kind = ty::tls::with(|tcx| {
// Unfortunately, some kinds of items (e.g., closures) don't have
Expand Down
8 changes: 0 additions & 8 deletions src/librustc_lint/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,14 +819,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
if let hir::ItemKind::Enum(ref enum_definition, _) = it.node {
let item_def_id = cx.tcx.hir.local_def_id(it.id);
let generics = cx.tcx.generics_of(item_def_id);
for param in &generics.params {
match param.kind {
ty::GenericParamDefKind::Lifetime { .. } => {},
ty::GenericParamDefKind::Type { .. } => return,
}
}
// Sizes only make sense for non-generic types.
let t = cx.tcx.type_of(item_def_id);
let ty = cx.tcx.erase_regions(&t);
match cx.layout_of(ty) {
Expand Down
25 changes: 12 additions & 13 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1262,12 +1262,9 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
hir::ItemKind::Const(..) => self.encode_optimized_mir(def_id),
hir::ItemKind::Fn(_, header, ..) => {
let generics = tcx.generics_of(def_id);
let has_types = generics.params.iter().any(|param| match param.kind {
ty::GenericParamDefKind::Type { .. } => true,
_ => false,
});
let needs_inline =
(has_types || tcx.codegen_fn_attrs(def_id).requests_inline()) &&
(generics.requires_monomorphization(tcx) ||
tcx.codegen_fn_attrs(def_id).requests_inline()) &&
!self.metadata_output_only();
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
if needs_inline
Expand Down Expand Up @@ -1683,15 +1680,17 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
}

fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
generics.params.iter().for_each(|param| match param.kind {
hir::GenericParamKind::Lifetime { .. } => {}
hir::GenericParamKind::Type { ref default, .. } => {
let def_id = self.tcx.hir.local_def_id(param.id);
let has_default = Untracked(default.is_some());
let encode_info = IsolatedEncoder::encode_info_for_ty_param;
self.record(def_id, encode_info, (def_id, has_default));
for param in &generics.params {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {}
hir::GenericParamKind::Type { ref default, .. } => {
let def_id = self.tcx.hir.local_def_id(param.id);
let has_default = Untracked(default.is_some());
let encode_info = IsolatedEncoder::encode_info_for_ty_param;
self.record(def_id, encode_info, (def_id, has_default));
}
}
});
}
}

fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,10 +539,9 @@ impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> {
fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
match *generic_args {
GenericArgs::AngleBracketed(ref data) => {
data.args.iter().for_each(|arg| match arg {
GenericArg::Type(ty) => self.visit_ty(ty),
_ => {}
});
for arg in &data.args {
self.visit_generic_arg(arg)
}
for type_binding in &data.bindings {
// Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
// are allowed to contain nested `impl Trait`.
Expand Down
13 changes: 5 additions & 8 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extern crate rustc_typeck;
extern crate syntax_pos;
extern crate rustc_data_structures;

use rustc::hir::{self, GenericParamKind, PatKind};
use rustc::hir::{self, PatKind};
use rustc::hir::def::Def;
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
Expand Down Expand Up @@ -1270,14 +1270,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
}

fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
generics.params.iter().for_each(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { .. } => {
for bound in &param.bounds {
self.check_generic_bound(bound);
}
for param in &generics.params {
for bound in &param.bounds {
self.check_generic_bound(bound);
}
});
}
for predicate in &generics.where_clause.predicates {
match predicate {
&hir::WherePredicate::BoundPredicate(ref bound_pred) => {
Expand Down
51 changes: 27 additions & 24 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,11 +822,12 @@ impl<'a, 'tcx, 'cl> Visitor<'tcx> for Resolver<'a, 'cl> {
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { ref default, .. } => {
if found_default || default.is_some() {
found_default = true;
return Some((Ident::with_empty_ctxt(param.ident.name), Def::Err));
found_default |= default.is_some();
if found_default {
Some((Ident::with_empty_ctxt(param.ident.name), Def::Err))
} else {
None
}
None
}
}));

Expand Down Expand Up @@ -2339,28 +2340,30 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
HasTypeParameters(generics, rib_kind) => {
let mut function_type_rib = Rib::new(rib_kind);
let mut seen_bindings = FxHashMap();
generics.params.iter().for_each(|param| match param.kind {
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);
for param in &generics.params {
match param.kind {
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));
// 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);
}

Expand Down
Loading

0 comments on commit 1558ae7

Please sign in to comment.