Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Great Generics Generalisation: HIR Followup #51880

Merged
merged 41 commits into from
Aug 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
11adc13
Address minor comments
varkor Jun 22, 2018
651215e
Replace for_each with for
varkor Jun 22, 2018
2317abd
Fix quadratic loop in confirm.rs
varkor Jun 22, 2018
d1a82af
Refactor mod/check (part i)
varkor Jun 25, 2018
5fe9aeb
Refactor mod/check (part ii)
varkor Jun 26, 2018
96379e1
Refactor mod/check (part iii)
varkor Jun 26, 2018
e812b55
Refactor mod/check (part iv)
varkor Jun 26, 2018
c9941a8
Refactor mod/check (part v)
varkor Jun 26, 2018
88d5b2f
Refactor mod/check (part vi)
varkor Jun 28, 2018
3357702
Replace generics_require_inlining with generics.requires_monomorphiza…
varkor Jun 28, 2018
734ce4a
Fix tidy check
varkor Jun 28, 2018
d5e24dc
Fix integer overflow
varkor Jul 2, 2018
d8ba103
Fix param_idx calculation
varkor Jul 3, 2018
b6eef18
Supress consecutive errors
varkor Jul 3, 2018
84edc0a
Move lifetime calculation outside loop
varkor Jul 3, 2018
35ddd46
Refactor confirm.rs
varkor Jul 3, 2018
340a7fc
Refactor astconv.rs
varkor Jul 3, 2018
e02642d
Fix confirm.rs
varkor Jul 3, 2018
9cfe92c
"Fix" annoying test
varkor Jul 3, 2018
9bb40b0
Make prohibit_generics take IntoIterators
varkor Jul 23, 2018
db94efa
Refactor mod/check (part vii)
varkor Jul 23, 2018
5f2588f
Fix behaviour in error condition
varkor Jul 23, 2018
08d49a6
Refactor mod/check (part viii)
varkor Jul 24, 2018
5d07db4
Refactor confirm.rs (part ii)
varkor Jul 24, 2018
b524991
Refactor astconv.rs (part ii)
varkor Jul 24, 2018
ccef306
Revert broken test
varkor Jul 24, 2018
e79bc41
Consolidate into create_substs_for_generic_args
varkor Jul 24, 2018
6a96cf1
Clean match statement
varkor Aug 2, 2018
9d3d4b1
Refactor lock-step
varkor Aug 7, 2018
7c9f7c2
Args first, then params
varkor Aug 7, 2018
a14bc71
Add Default for GenericParamCount
varkor Aug 7, 2018
49c4573
Refactor generic argument count check in astconv
varkor Aug 7, 2018
68b0e7d
Refactor generic argument count check in method/confirm.rs
varkor Aug 7, 2018
04d33bb
Refactor generic argument count check in check/mod.rs
varkor Aug 7, 2018
03c4628
Avoid clone and update documentation
varkor Aug 8, 2018
4722744
Fix some remaining tests
varkor Aug 8, 2018
25b6267
Taking a peek
varkor Aug 19, 2018
b5c2470
Update new ui tests
varkor Aug 19, 2018
ae81fc6
Fix ICE
varkor Aug 19, 2018
aa3b5c5
Fix diagnostic regression
varkor Aug 20, 2018
ee9bd0f
Add a test for skipping all arguments versus just one
varkor Aug 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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