From e8d01ea4c76f6f3cb4f71dbff261355f825d12bb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 25 Jan 2017 22:01:11 +0200 Subject: [PATCH] rustc: store type parameter defaults outside of ty::Generics. --- src/librustc/hir/lowering.rs | 2 +- src/librustc/infer/mod.rs | 15 +- src/librustc/middle/cstore.rs | 15 +- src/librustc/middle/resolve_lifetime.rs | 4 +- src/librustc/ty/context.rs | 16 +- src/librustc/ty/error.rs | 8 +- src/librustc/ty/maps.rs | 2 +- src/librustc/ty/mod.rs | 31 ++-- src/librustc/ty/structural_impls.rs | 36 +--- src/librustc/ty/subst.rs | 14 +- src/librustc/util/ppaux.rs | 9 +- src/librustc_metadata/cstore_impl.rs | 18 +- src/librustc_metadata/decoder.rs | 25 +-- src/librustc_metadata/encoder.rs | 61 ++++--- src/librustc_metadata/schema.rs | 17 +- src/librustc_privacy/lib.rs | 12 +- src/librustc_resolve/diagnostics.rs | 27 +++ src/librustc_resolve/lib.rs | 78 +++++++-- src/librustc_trans/debuginfo/mod.rs | 6 +- src/librustc_trans/debuginfo/utils.rs | 8 +- src/librustc_typeck/astconv.rs | 58 +++---- src/librustc_typeck/check/compare_method.rs | 4 +- src/librustc_typeck/check/mod.rs | 18 +- src/librustc_typeck/collect.rs | 157 +++++++++--------- src/librustc_typeck/diagnostics.rs | 27 --- src/librustc_typeck/lib.rs | 25 +++ src/librustc_typeck/variance/constraints.rs | 14 +- src/librustdoc/clean/mod.rs | 10 +- src/libsyntax/visit.rs | 49 +++--- .../cycle-trait-default-type-trait.rs | 1 + .../generic-non-trailing-defaults.rs | 4 +- .../generic-type-params-forward-mention.rs | 2 +- src/test/compile-fail/issue-18183.rs | 4 +- src/test/compile-fail/resolve-self-in-impl.rs | 2 +- 34 files changed, 394 insertions(+), 385 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 8572119e989..82e644d710d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -525,7 +525,7 @@ impl<'a> LoweringContext<'a> { return n; } assert!(!def_id.is_local()); - let (n, _) = self.sess.cstore.item_generics_own_param_counts(def_id); + let n = self.sess.cstore.item_generics(def_id).regions.len(); self.type_def_lifetime_params.insert(def_id, n); n }); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index c3a6a62764d..64256247bb5 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1197,16 +1197,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// as the substitutions for the default, `(T, U)`. pub fn type_var_for_def(&self, span: Span, - def: &ty::TypeParameterDef<'tcx>, + def: &ty::TypeParameterDef, substs: &[Kind<'tcx>]) -> Ty<'tcx> { - let default = def.default.map(|default| { - type_variable::Default { + let default = if def.has_default { + let default = self.tcx.item_type(def.def_id); + Some(type_variable::Default { ty: default.subst_spanned(self.tcx, substs, Some(span)), origin_span: span, - def_id: def.default_def_id - } - }); + def_id: def.def_id + }) + } else { + None + }; let ty_var_id = self.type_variables diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 2d80fc32c46..671da0d1197 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -28,7 +28,6 @@ use hir::map as hir_map; use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData}; use hir::svh::Svh; use middle::lang_items; -use middle::resolve_lifetime::ObjectLifetimeDefault; use ty::{self, Ty, TyCtxt}; use mir::Mir; use session::Session; @@ -182,11 +181,7 @@ pub trait CrateStore<'tcx> { -> ty::GenericPredicates<'tcx>; fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::GenericPredicates<'tcx>; - fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::Generics<'tcx>; - fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize); - fn item_generics_object_lifetime_defaults(&self, def: DefId) - -> Vec; + fn item_generics(&self, def: DefId) -> ty::Generics; fn item_attrs(&self, def_id: DefId) -> Vec; fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef; fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef; @@ -335,13 +330,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { -> ty::GenericPredicates<'tcx> { bug!("item_predicates") } fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") } - fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::Generics<'tcx> { bug!("item_generics") } - fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize) - { bug!("item_generics_own_param_counts") } - fn item_generics_object_lifetime_defaults(&self, def: DefId) - -> Vec - { bug!("item_generics_object_lifetime_defaults") } + fn item_generics(&self, def: DefId) -> ty::Generics { bug!("item_generics") } fn item_attrs(&self, def_id: DefId) -> Vec { bug!("item_attrs") } fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef { bug!("trait_def") } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 9bad98dda83..95cbd738651 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -995,7 +995,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } else { let cstore = &self.sess.cstore; self.xcrate_object_lifetime_defaults.entry(def_id).or_insert_with(|| { - cstore.item_generics_object_lifetime_defaults(def_id) + cstore.item_generics(def_id).types.into_iter().map(|def| { + def.object_lifetime_default + }).collect() }) }; unsubst.iter().map(|set| { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 19bb8a63aa2..2f062e2e5b1 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -64,7 +64,7 @@ pub struct GlobalArenas<'tcx> { layout: TypedArena, // references - generics: TypedArena>, + generics: TypedArena, trait_def: TypedArena, adt_def: TypedArena, mir: TypedArena>>, @@ -467,9 +467,6 @@ pub struct GlobalCtxt<'tcx> { // Cache for the type-contents routine. FIXME -- track deps? pub tc_cache: RefCell, ty::contents::TypeContents>>, - // FIXME no dep tracking, but we should be able to remove this - pub ty_param_defs: RefCell>>, - // FIXME dep tracking -- should be harmless enough pub normalized_cache: RefCell, Ty<'tcx>>>, @@ -646,15 +643,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - pub fn type_parameter_def(self, - node_id: NodeId) - -> ty::TypeParameterDef<'tcx> - { - self.ty_param_defs.borrow().get(&node_id).unwrap().clone() - } - - pub fn alloc_generics(self, generics: ty::Generics<'gcx>) - -> &'gcx ty::Generics<'gcx> { + pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics { self.global_arenas.generics.alloc(generics) } @@ -785,7 +774,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { tc_cache: RefCell::new(FxHashMap()), associated_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())), associated_item_def_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())), - ty_param_defs: RefCell::new(NodeMap()), normalized_cache: RefCell::new(FxHashMap()), inhabitedness_cache: RefCell::new(FxHashMap()), lang_items: lang_items, diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 3ab3fc899e7..44a3aabc056 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -10,7 +10,7 @@ use hir::def_id::DefId; use infer::type_variable; -use ty::{self, BoundRegion, Region, Ty, TyCtxt}; +use ty::{self, BoundRegion, DefIdTree, Region, Ty, TyCtxt}; use std::fmt; use syntax::abi; @@ -287,8 +287,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { db.span_note(span, "a default was defined here..."); } None => { + let item_def_id = self.parent(expected.def_id).unwrap(); db.note(&format!("a default is defined on `{}`", - self.item_path_str(expected.def_id))); + self.item_path_str(item_def_id))); } } @@ -301,8 +302,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { db.span_note(span, "a second default was defined here..."); } None => { + let item_def_id = self.parent(found.def_id).unwrap(); db.note(&format!("a second default is defined on `{}`", - self.item_path_str(found.def_id))); + self.item_path_str(item_def_id))); } } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index d7341d148b7..d2c237d5db6 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -35,7 +35,7 @@ macro_rules! dep_map_ty { dep_map_ty! { AssociatedItems: AssociatedItems(DefId) -> ty::AssociatedItem } dep_map_ty! { Types: ItemSignature(DefId) -> Ty<'tcx> } -dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics<'tcx> } +dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics } dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> } dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> } dep_map_ty! { AssociatedItemDefIds: AssociatedItemDefIds(DefId) -> Rc> } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7937d2ccfe4..1275530b1bd 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -19,9 +19,10 @@ use dep_graph::{self, DepNode}; use hir::{map as hir_map, FreevarMap, TraitMap}; use middle; use hir::def::{Def, CtorKind, ExportMap}; -use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::region::{CodeExtent, ROOT_CODE_EXTENT}; +use middle::resolve_lifetime::ObjectLifetimeDefault; use mir::Mir; use traits; use ty; @@ -33,6 +34,7 @@ use util::nodemap::{NodeSet, NodeMap, FxHashMap}; use serialize::{self, Encodable, Encoder}; use std::borrow::Cow; use std::cell::{Cell, RefCell, Ref}; +use std::collections::BTreeMap; use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::rc::Rc; @@ -585,13 +587,13 @@ pub enum IntVarValue { UintType(ast::UintTy), } -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub struct TypeParameterDef<'tcx> { +#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] +pub struct TypeParameterDef { pub name: Name, pub def_id: DefId, pub index: u32, - pub default_def_id: DefId, // for use in error reporing about defaults - pub default: Option>, + pub has_default: bool, + pub object_lifetime_default: ObjectLifetimeDefault, /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute /// on generic parameter `T`, asserts data behind the parameter @@ -628,16 +630,21 @@ impl RegionParameterDef { /// Information about the formal type/lifetime parameters associated /// with an item or method. Analogous to hir::Generics. #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] -pub struct Generics<'tcx> { +pub struct Generics { pub parent: Option, pub parent_regions: u32, pub parent_types: u32, pub regions: Vec, - pub types: Vec>, + pub types: Vec, + + /// Reverse map to each `TypeParameterDef`'s `index` field, from + /// `def_id.index` (`def_id.krate` is the same as the item's). + pub type_param_to_index: BTreeMap, + pub has_self: bool, } -impl<'tcx> Generics<'tcx> { +impl Generics { pub fn parent_count(&self) -> usize { self.parent_regions as usize + self.parent_types as usize } @@ -651,10 +658,12 @@ impl<'tcx> Generics<'tcx> { } pub fn region_param(&self, param: &EarlyBoundRegion) -> &RegionParameterDef { + assert_eq!(self.parent_count(), 0); &self.regions[param.index as usize - self.has_self as usize] } - pub fn type_param(&self, param: &ParamTy) -> &TypeParameterDef<'tcx> { + pub fn type_param(&self, param: &ParamTy) -> &TypeParameterDef { + assert_eq!(self.parent_count(), 0); &self.types[param.idx as usize - self.has_self as usize - self.regions.len()] } } @@ -2319,10 +2328,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } /// Given the did of an item, returns its generics. - pub fn item_generics(self, did: DefId) -> &'gcx Generics<'gcx> { + pub fn item_generics(self, did: DefId) -> &'gcx Generics { lookup_locally_or_in_crate_store( "generics", did, &self.generics, - || self.alloc_generics(self.sess.cstore.item_generics(self.global_tcx(), did))) + || self.alloc_generics(self.sess.cstore.item_generics(did))) } /// Given the did of an item, returns its full set of predicates. diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index aa74e7cc0d0..a1bf58a12eb 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -353,7 +353,7 @@ macro_rules! CopyImpls { } } -CopyImpls! { (), hir::Unsafety, abi::Abi, ty::RegionParameterDef } +CopyImpls! { (), hir::Unsafety, abi::Abi } impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) { @@ -716,40 +716,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::TypeParameterDef { - name: self.name, - def_id: self.def_id, - index: self.index, - default: self.default.fold_with(folder), - default_def_id: self.default_def_id, - pure_wrt_drop: self.pure_wrt_drop, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.default.visit_with(visitor) - } -} - -impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::Generics { - parent: self.parent, - parent_regions: self.parent_regions, - parent_types: self.parent_types, - regions: self.regions.fold_with(folder), - types: self.types.fold_with(folder), - has_self: self.has_self, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.regions.visit_with(visitor) || self.types.visit_with(visitor) - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { ty::GenericPredicates { diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index c0a529b936b..0a2cc1c30f4 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -184,7 +184,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { mut mk_type: FT) -> &'tcx Substs<'tcx> where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, - FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> { + FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { let defs = tcx.item_generics(def_id); let mut substs = Vec::with_capacity(defs.count()); Substs::fill_item(&mut substs, tcx, defs, &mut mk_region, &mut mk_type); @@ -198,7 +198,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { mut mk_type: FT) -> &'tcx Substs<'tcx> where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, - FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> + FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { let defs = tcx.item_generics(def_id); let mut result = Vec::with_capacity(defs.count()); @@ -209,11 +209,11 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { fn fill_item(substs: &mut Vec>, tcx: TyCtxt<'a, 'gcx, 'tcx>, - defs: &ty::Generics<'tcx>, + defs: &ty::Generics, mk_region: &mut FR, mk_type: &mut FT) where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, - FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> { + FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { if let Some(def_id) = defs.parent { let parent_defs = tcx.item_generics(def_id); @@ -223,11 +223,11 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { } fn fill_single(substs: &mut Vec>, - defs: &ty::Generics<'tcx>, + defs: &ty::Generics, mk_region: &mut FR, mk_type: &mut FT) where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, - FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> { + FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { // Handle Self first, before all regions. let mut types = defs.types.iter(); if defs.parent.is_none() && defs.has_self { @@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { tcx.mk_substs(target_substs.iter().chain(&self[defs.own_count()..]).cloned()) } - pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics<'tcx>) + pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics) -> &'tcx Substs<'tcx> { tcx.mk_substs(self.iter().take(generics.count()).cloned()) } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a45c43235eb..2a5cd7b37ca 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -137,11 +137,14 @@ pub fn parameterized(f: &mut fmt::Formatter, } if !verbose { - if generics.types.last().map_or(false, |def| def.default.is_some()) { + if generics.types.last().map_or(false, |def| def.has_default) { if let Some(substs) = tcx.lift(&substs) { let tps = substs.types().rev().skip(child_types); for (def, actual) in generics.types.iter().rev().zip(tps) { - if def.default.subst(tcx, substs) != Some(actual) { + if !def.has_default { + break; + } + if tcx.item_type(def.def_id).subst(tcx, substs) != actual { break; } num_supplied_defaults += 1; @@ -326,7 +329,7 @@ impl<'tcx> fmt::Display for &'tcx ty::Slice> { } } -impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> { +impl fmt::Debug for ty::TypeParameterDef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "TypeParameterDef({}, {:?}, {})", self.name, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 7b0177bfd23..bd184c5c5e6 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -17,7 +17,6 @@ use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, ExternC use rustc::middle::cstore::{NativeLibrary, LinkMeta, LinkagePreference, LoadedMacro}; use rustc::hir::def::{self, Def}; use rustc::middle::lang_items; -use rustc::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -104,22 +103,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def.krate).get_super_predicates(def.index, tcx) } - fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::Generics<'tcx> - { + fn item_generics(&self, def: DefId) -> ty::Generics { self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_generics(def.index, tcx) - } - - fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize) { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).generics_own_param_counts(def.index) - } - - fn item_generics_object_lifetime_defaults(&self, def: DefId) - -> Vec { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).generics_object_lifetime_defaults(def.index) + self.get_crate_data(def.krate).get_generics(def.index) } fn item_attrs(&self, def_id: DefId) -> Vec diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 53883e50a5b..22fa9411cc1 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -20,7 +20,6 @@ use rustc::middle::cstore::LinkagePreference; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::middle::lang_items; -use rustc::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; @@ -601,30 +600,8 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_generics(&self, - item_id: DefIndex, - tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> ty::Generics<'tcx> { - let g = self.entry(item_id).generics.unwrap().decode(self); - ty::Generics { - parent: g.parent, - parent_regions: g.parent_regions, - parent_types: g.parent_types, - regions: g.regions.decode((self, tcx)).collect(), - types: g.types.decode((self, tcx)).collect(), - has_self: g.has_self, - } - } - - pub fn generics_own_param_counts(&self, item_id: DefIndex) -> (usize, usize) { - let g = self.entry(item_id).generics.unwrap().decode(self); - (g.regions.len, g.types.len) - } - - pub fn generics_object_lifetime_defaults(&self, item_id: DefIndex) - -> Vec { + pub fn get_generics(&self, item_id: DefIndex) -> ty::Generics { self.entry(item_id).generics.unwrap().decode(self) - .object_lifetime_defaults.decode(self).collect() } pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 0f9491aaf15..a643ed59af1 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -423,26 +423,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } - fn encode_generics(&mut self, def_id: DefId) -> Lazy> { + fn encode_generics(&mut self, def_id: DefId) -> Lazy { let tcx = self.tcx; - let g = tcx.item_generics(def_id); - let regions = self.lazy_seq_ref(&g.regions); - let types = self.lazy_seq_ref(&g.types); - let mut object_lifetime_defaults = LazySeq::empty(); - if let Some(id) = tcx.hir.as_local_node_id(def_id) { - if let Some(o) = tcx.named_region_map.object_lifetime_defaults.get(&id) { - object_lifetime_defaults = self.lazy_seq_ref(o); - } - } - self.lazy(&Generics { - parent: g.parent, - parent_regions: g.parent_regions, - parent_types: g.parent_types, - regions: regions, - types: types, - has_self: g.has_self, - object_lifetime_defaults: object_lifetime_defaults, - }) + self.lazy(tcx.item_generics(def_id)) } fn encode_predicates(&mut self, def_id: DefId) -> Lazy> { @@ -1008,6 +991,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { EncodeContext::encode_info_for_foreign_item, (def_id, ni)); } + fn visit_generics(&mut self, generics: &'tcx hir::Generics) { + intravisit::walk_generics(self, generics); + self.index.encode_info_for_generics(generics); + } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { intravisit::walk_ty(self, ty); self.index.encode_info_for_ty(ty); @@ -1019,6 +1006,14 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { } impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { + fn encode_info_for_generics(&mut self, generics: &hir::Generics) { + for ty_param in &generics.ty_params { + let def_id = self.tcx.hir.local_def_id(ty_param.id); + let has_default = Untracked(ty_param.default.is_some()); + self.record(def_id, EncodeContext::encode_info_for_ty_param, (def_id, has_default)); + } + } + fn encode_info_for_ty(&mut self, ty: &hir::Ty) { if let hir::TyImplTrait(_) = ty.node { let def_id = self.tcx.hir.local_def_id(ty.id); @@ -1038,6 +1033,34 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { } impl<'a, 'tcx> EncodeContext<'a, 'tcx> { + fn encode_info_for_ty_param(&mut self, + (def_id, Untracked(has_default)): (DefId, Untracked)) + -> Entry<'tcx> { + let tcx = self.tcx; + Entry { + kind: EntryKind::Type, + visibility: self.lazy(&ty::Visibility::Public), + span: self.lazy(&tcx.def_span(def_id)), + attributes: LazySeq::empty(), + children: LazySeq::empty(), + stability: None, + deprecation: None, + + ty: if has_default { + Some(self.encode_item_type(def_id)) + } else { + None + }, + inherent_impls: LazySeq::empty(), + variances: LazySeq::empty(), + generics: None, + predicates: None, + + ast: None, + mir: None, + } + } + fn encode_info_for_anon_ty(&mut self, def_id: DefId) -> Entry<'tcx> { let tcx = self.tcx; Entry { diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 777af02772e..ee30063fcbd 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -16,7 +16,6 @@ use rustc::hir::def::{self, CtorKind}; use rustc::hir::def_id::{DefIndex, DefId}; use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary}; use rustc::middle::lang_items; -use rustc::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc::mir; use rustc::ty::{self, Ty, ReprOptions}; use rustc_back::PanicStrategy; @@ -212,7 +211,7 @@ pub struct Entry<'tcx> { pub ty: Option>>, pub inherent_impls: LazySeq, pub variances: LazySeq, - pub generics: Option>>, + pub generics: Option>, pub predicates: Option>>, pub ast: Option>>, @@ -246,20 +245,6 @@ pub enum EntryKind<'tcx> { AssociatedConst(AssociatedContainer), } -/// A copy of `ty::Generics` which allows lazy decoding of -/// `regions` and `types` (e.g. knowing the number of type -/// and lifetime parameters before `TyCtxt` is created). -#[derive(RustcEncodable, RustcDecodable)] -pub struct Generics<'tcx> { - pub parent: Option, - pub parent_regions: u32, - pub parent_types: u32, - pub regions: LazySeq, - pub types: LazySeq>, - pub has_self: bool, - pub object_lifetime_defaults: LazySeq, -} - #[derive(RustcEncodable, RustcDecodable)] pub struct ModData { pub reexports: LazySeq, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9dc94745cff..72347f1616e 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -334,7 +334,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> { fn generics(&mut self) -> &mut Self { - self.ev.tcx.item_generics(self.item_def_id).visit_with(self); + for def in &self.ev.tcx.item_generics(self.item_def_id).types { + if def.has_default { + self.ev.tcx.item_type(def.def_id).visit_with(self); + } + } self } @@ -892,7 +896,11 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn generics(&mut self) -> &mut Self { - self.tcx.item_generics(self.item_def_id).visit_with(self); + for def in &self.tcx.item_generics(self.item_def_id).types { + if def.has_default { + self.tcx.item_type(def.def_id).visit_with(self); + } + } self } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 2fada8a9ec2..8f6b1b8971e 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -15,6 +15,33 @@ // use `gq` to wrap paragraphs. Use `:set tw=0` to disable. register_long_diagnostics! { +E0128: r##" +Type parameter defaults can only use parameters that occur before them. +Erroneous code example: + +```compile_fail,E0128 +struct Foo { + field1: T, + filed2: U, +} +// error: type parameters with a default cannot use forward declared +// identifiers +``` + +Since type parameters are evaluated in-order, you may be able to fix this issue +by doing: + +``` +struct Foo { + field1: T, + filed2: U, +} +``` + +Please also verify that this wasn't because of a name-clash and rename the type +parameter if so. +"##, + E0154: r##" ## Note: this error code is no longer emitted by the compiler. diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index eefe83d7da6..0565db28ec5 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -136,6 +136,8 @@ enum ResolutionError<'a> { AttemptToUseNonConstantValueInConstant, /// error E0530: X bindings cannot shadow Ys BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>), + /// error E0128: type parameters with a default cannot use forward declared identifiers + ForwardDeclaredTyParam, } fn resolve_error<'sess, 'a>(resolver: &'sess Resolver, @@ -322,6 +324,14 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, err.span_label(binding.span, msg); err } + ResolutionError::ForwardDeclaredTyParam => { + let mut err = struct_span_err!(resolver.session, span, E0128, + "type parameters with a default cannot use \ + forward declared identifiers"); + err.span_label(span, &format!("defaulted type parameters \ + cannot be forward declared")); + err + } } } @@ -674,6 +684,32 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { self.label_ribs.pop(); self.ribs[ValueNS].pop(); } + fn visit_generics(&mut self, generics: &'tcx Generics) { + // For type parameter defaults, we have to ban access + // to following type parameters, as the Substs can only + // provide previous type parameters as they're built. + let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind); + default_ban_rib.bindings.extend(generics.ty_params.iter() + .skip_while(|p| p.default.is_none()) + .map(|p| (Ident::with_empty_ctxt(p.ident.name), Def::Err))); + + for param in &generics.ty_params { + for bound in ¶m.bounds { + self.visit_ty_param_bound(bound); + } + + if let Some(ref ty) = param.default { + self.ribs[TypeNS].push(default_ban_rib); + self.visit_ty(ty); + default_ban_rib = self.ribs[TypeNS].pop().unwrap(); + } + + // Allow all following defaults to refer to this type parameter. + default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name)); + } + for lt in &generics.lifetimes { self.visit_lifetime_def(lt); } + for p in &generics.where_clause.predicates { self.visit_where_predicate(p); } + } } pub type ErrorMessage = Option<(Span, String)>; @@ -718,6 +754,11 @@ enum RibKind<'a> { // We passed through a `macro_rules!` statement with the given expansion MacroDefinition(Mark), + + // All bindings in this rib are type parameters that can't be used + // from the default of a type parameter because they're not declared + // before said type parameter. Also see the `visit_generics` override. + ForwardTyParamBanRibKind, } /// One local scope. @@ -736,13 +777,6 @@ impl<'a> Rib<'a> { } } -/// A definition along with the index of the rib it was found on -#[derive(Copy, Clone, Debug)] -struct LocalDef { - ribs: Option<(Namespace, usize)>, - def: Def, -} - enum LexicalScopeBinding<'a> { Item(&'a NameBinding<'a>), Def(Def), @@ -1428,7 +1462,7 @@ impl<'a> Resolver<'a> { if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() { // The ident resolves to a type parameter or local variable. return Some(LexicalScopeBinding::Def( - self.adjust_local_def(LocalDef { ribs: Some((ns, i)), def: def }, record_used) + self.adjust_local_def(ns, i, def, record_used) )); } @@ -2527,12 +2561,23 @@ impl<'a> Resolver<'a> { } // Resolve a local definition, potentially adjusting for closures. - fn adjust_local_def(&mut self, local_def: LocalDef, record_used: Option) -> Def { - let ribs = match local_def.ribs { - Some((ns, i)) => &self.ribs[ns][i + 1..], - None => &[] as &[_], - }; - let mut def = local_def.def; + fn adjust_local_def(&mut self, + ns: Namespace, + rib_index: usize, + mut def: Def, + record_used: Option) -> Def { + let ribs = &self.ribs[ns][rib_index + 1..]; + + // An invalid forward use of a type parameter from a previous default. + if let ForwardTyParamBanRibKind = self.ribs[ns][rib_index].kind { + if let Some(span) = record_used { + resolve_error(self, span, + ResolutionError::ForwardDeclaredTyParam); + } + assert_eq!(def, Def::Err); + return Def::Err; + } + match def { Def::Upvar(..) => { span_bug!(record_used.unwrap_or(DUMMY_SP), "unexpected {:?} in bindings", def) @@ -2540,7 +2585,8 @@ impl<'a> Resolver<'a> { Def::Local(def_id) => { for rib in ribs { match rib.kind { - NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) => { + NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) | + ForwardTyParamBanRibKind => { // Nothing to do. Continue. } ClosureRibKind(function_id) => { @@ -2593,7 +2639,7 @@ impl<'a> Resolver<'a> { for rib in ribs { match rib.kind { NormalRibKind | MethodRibKind(_) | ClosureRibKind(..) | - ModuleRibKind(..) | MacroDefinition(..) => { + ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind => { // Nothing to do. Continue. } ItemRibKind => { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index e9b592ec8fd..4a8b0ff4552 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -332,7 +332,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, - generics: &ty::Generics<'tcx>, + generics: &ty::Generics, substs: &Substs<'tcx>, file_metadata: DIFile, name_to_append_suffix_to: &mut String) @@ -382,9 +382,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return create_DIArray(DIB(cx), &template_params[..]); } - fn get_type_parameter_names<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, - generics: &ty::Generics<'tcx>) - -> Vec { + fn get_type_parameter_names(cx: &CrateContext, generics: &ty::Generics) -> Vec { let mut names = generics.parent.map_or(vec![], |def_id| { get_type_parameter_names(cx, cx.tcx().item_generics(def_id)) }); diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs index 15a1c990aad..ceff96a39b2 100644 --- a/src/librustc_trans/debuginfo/utils.rs +++ b/src/librustc_trans/debuginfo/utils.rs @@ -14,6 +14,7 @@ use super::{CrateDebugContext}; use super::namespace::item_namespace; use rustc::hir::def_id::DefId; +use rustc::ty::DefIdTree; use llvm; use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray}; @@ -74,11 +75,8 @@ pub fn DIB(cx: &CrateContext) -> DIBuilderRef { pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId) -> (DIScope, Span) { - let containing_scope = item_namespace(cx, DefId { - krate: def_id.krate, - index: cx.tcx().def_key(def_id).parent - .expect("get_namespace_and_span_for_item: missing parent?") - }); + let containing_scope = item_namespace(cx, cx.tcx().parent(def_id) + .expect("get_namespace_and_span_for_item: missing parent?")); // Try to get some span information, if we have an inlined item. let definition_span = cx.tcx().def_span(def_id); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index ab1897101eb..8f556726f22 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -42,7 +42,7 @@ use std::cell::RefCell; use std::iter; use syntax::{abi, ast}; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::Symbol; use syntax_pos::Span; pub trait AstConv<'gcx, 'tcx> { @@ -53,7 +53,7 @@ pub trait AstConv<'gcx, 'tcx> { /// Returns the generic type and lifetime parameters for an item. fn get_generics(&self, span: Span, id: DefId) - -> Result<&'tcx ty::Generics<'tcx>, ErrorReported>; + -> Result<&'tcx ty::Generics, ErrorReported>; /// Identify the type for an item, like a type alias, fn, or struct. fn get_item_type(&self, span: Span, id: DefId) -> Result, ErrorReported>; @@ -89,7 +89,7 @@ pub trait AstConv<'gcx, 'tcx> { /// Same as ty_infer, but with a known type parameter definition. fn ty_infer_for_def(&self, - _def: &ty::TypeParameterDef<'tcx>, + _def: &ty::TypeParameterDef, _substs: &[Kind<'tcx>], span: Span) -> Ty<'tcx> { self.ty_infer(span) @@ -277,9 +277,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF); - let default_needs_object_self = |p: &ty::TypeParameterDef<'tcx>| { - if let Some(ref default) = p.default { - if is_object && default.has_self_ty() { + let default_needs_object_self = |p: &ty::TypeParameterDef| { + if is_object && p.has_default { + let default = self.get_item_type(span, p.def_id).ok(); + if default.has_self_ty() { // There is no suitable inference default for a type parameter // that references self, in an object type. return true; @@ -327,7 +328,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { self.ty_infer(span) }; ty_var - } else if let Some(default) = def.default { + } else if def.has_default { // No type parameter provided, but a default exists. // If we are converting an object type, then the @@ -346,7 +347,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.types.err } else { // This is a default type parameter. - default.subst_spanned(tcx, substs, Some(span)) + match self.get_item_type(span, def.def_id) { + Ok(ty) => ty.subst_spanned(tcx, substs, Some(span)), + Err(ErrorReported) => tcx.types.err + } } } else { // We've already errored above about the mismatch. @@ -954,19 +958,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Err(ErrorReported) => return (tcx.types.err, Def::Err), } } - (&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => { - let trait_node_id = tcx.hir.as_local_node_id(trait_did).unwrap(); - match self.find_bound_for_assoc_item(trait_node_id, - keywords::SelfType.name(), - assoc_name, - span) { - Ok(bound) => bound, - Err(ErrorReported) => return (tcx.types.err, Def::Err), - } - } + (&ty::TyParam(_), Def::SelfTy(Some(param_did), None)) | (&ty::TyParam(_), Def::TyParam(param_did)) => { let param_node_id = tcx.hir.as_local_node_id(param_did).unwrap(); - let param_name = tcx.type_parameter_def(param_node_id).name; + let param_name = ::ty_param_name(tcx, param_node_id); match self.find_bound_for_assoc_item(param_node_id, param_name, assoc_name, @@ -1063,21 +1058,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.prohibit_type_params(&path.segments); let node_id = tcx.hir.as_local_node_id(did).unwrap(); - let param = tcx.ty_param_defs.borrow().get(&node_id) - .map(ty::ParamTy::for_def); - if let Some(p) = param { - p.to_ty(tcx) - } else { - // Only while computing defaults of earlier type - // parameters can a type parameter be missing its def. - struct_span_err!(tcx.sess, span, E0128, - "type parameters with a default cannot use \ - forward declared identifiers") - .span_label(span, &format!("defaulted type parameters \ - cannot be forward declared")) - .emit(); - tcx.types.err - } + let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id)); + let index = match self.get_generics(span, item_def_id) { + Ok(generics) => { + generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index] + } + Err(ErrorReported) => return tcx.types.err + }; + tcx.mk_param(index, ::ty_param_name(tcx, node_id)) } Def::SelfTy(_, Some(def_id)) => { // Self in impl (we know the concrete type). @@ -1510,7 +1498,7 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize, ty_param_defs: &[ty::TypeParameterDef]) { let accepted = ty_param_defs.len(); - let required = ty_param_defs.iter().take_while(|x| x.default.is_none()) .count(); + let required = ty_param_defs.iter().take_while(|x| !x.has_default).count(); if supplied < required { let expected = if required < accepted { "expected at least" diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index d110c16cf33..bdeb7165356 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -386,8 +386,8 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, impl_m: &ty::AssociatedItem, - trait_generics: &ty::Generics<'tcx>, - impl_generics: &ty::Generics<'tcx>, + trait_generics: &ty::Generics, + impl_generics: &ty::Generics, trait_to_skol_substs: &Substs<'tcx>, impl_to_skol_substs: &Substs<'tcx>) -> Result<(), ErrorReported> { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 14dacb0ca97..60805625b7b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1360,7 +1360,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { } fn get_generics(&self, _: Span, id: DefId) - -> Result<&'tcx ty::Generics<'tcx>, ErrorReported> + -> Result<&'tcx ty::Generics, ErrorReported> { Ok(self.tcx().item_generics(id)) } @@ -1390,14 +1390,17 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { node_id: ast::NodeId) -> Result>, ErrorReported> { - let def = self.tcx.type_parameter_def(node_id); + let tcx = self.tcx; + let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id)); + let generics = tcx.item_generics(item_def_id); + let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index]; let r = self.parameter_environment .caller_bounds .iter() .filter_map(|predicate| { match *predicate { ty::Predicate::Trait(ref data) => { - if data.0.self_ty().is_param(def.index) { + if data.0.self_ty().is_param(index) { Some(data.to_poly_trait_ref()) } else { None @@ -1426,7 +1429,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { } fn ty_infer_for_def(&self, - ty_param_def: &ty::TypeParameterDef<'tcx>, + ty_param_def: &ty::TypeParameterDef, substs: &[Kind<'tcx>], span: Span) -> Ty<'tcx> { self.type_var_for_def(span, ty_param_def, substs) @@ -4423,8 +4426,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(ast_ty) = types.get(i) { // A provided type parameter. self.to_ty(ast_ty) - } else if let (false, Some(default)) = (infer_types, def.default) { + } else if !infer_types && def.has_default { // No type parameter provided, but a default exists. + let default = self.tcx.item_type(def.def_id); default.subst_spanned(self.tcx, substs, Some(span)) } else { // No type parameters were provided, we can infer all. @@ -4537,9 +4541,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &generics.types } }); - let required_len = type_defs.iter() - .take_while(|d| d.default.is_none()) - .count(); + let required_len = type_defs.iter().take_while(|d| !d.has_default).count(); if types.len() > type_defs.len() { let span = types[type_defs.len()].span; let expected_text = count_type_params(type_defs.len()); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 217405a81ec..d168f5d4241 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -62,6 +62,7 @@ use lint; use constrained_type_params as ctp; use middle::lang_items::SizedTraitLangItem; use middle::const_val::ConstVal; +use middle::resolve_lifetime as rl; use rustc_const_eval::EvalHint::UncheckedExprHint; use rustc_const_eval::{ConstContext, report_const_eval_err}; use rustc::ty::subst::Substs; @@ -76,6 +77,7 @@ use CrateCtxt; use rustc_const_math::ConstInt; use std::cell::RefCell; +use std::collections::BTreeMap; use syntax::{abi, ast, attr}; use syntax::symbol::{Symbol, keywords}; @@ -186,6 +188,16 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { intravisit::walk_item(self, item); } + fn visit_generics(&mut self, generics: &'tcx hir::Generics) { + for param in &generics.ty_params { + if param.default.is_some() { + let def_id = self.ccx.tcx.hir.local_def_id(param.id); + type_of_def_id(self.ccx, def_id); + } + } + intravisit::walk_generics(self, generics); + } + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { if let hir::ExprClosure(..) = expr.node { let def_id = self.ccx.tcx.hir.local_def_id(expr.id); @@ -277,11 +289,10 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { tcx.item_path_str(def_id))); } AstConvRequest::GetTypeParameterBounds(id) => { - let def = tcx.type_parameter_def(id); err.note( &format!("the cycle begins when computing the bounds \ for type parameter `{}`...", - def.name)); + ::ty_param_name(tcx, id))); } } @@ -300,11 +311,10 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { tcx.item_path_str(def_id))); } AstConvRequest::GetTypeParameterBounds(id) => { - let def = tcx.type_parameter_def(id); err.note( &format!("...which then requires computing the bounds \ for type parameter `{}`...", - def.name)); + ::ty_param_name(tcx, id))); } } } @@ -324,11 +334,10 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { tcx.item_path_str(def_id))); } AstConvRequest::GetTypeParameterBounds(id) => { - let def = tcx.type_parameter_def(id); err.note( &format!("...which then again requires computing the bounds \ for type parameter `{}`, completing the cycle.", - def.name)); + ::ty_param_name(tcx, id))); } } err.emit(); @@ -385,7 +394,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { } fn get_generics(&self, span: Span, id: DefId) - -> Result<&'tcx ty::Generics<'tcx>, ErrorReported> + -> Result<&'tcx ty::Generics, ErrorReported> { self.ccx.cycle_check(span, AstConvRequest::GetGenerics(id), || { Ok(generics_of_def_id(self.ccx, id)) @@ -531,20 +540,23 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> { node_id: ast::NodeId) -> Vec> { - let def = astconv.tcx().type_parameter_def(node_id); + let tcx = astconv.tcx(); + let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id)); + let generics = tcx.item_generics(item_def_id); + let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index]; let mut results = self.parent.map_or(vec![], |def_id| { - let parent = astconv.tcx().item_predicates(def_id); + let parent = tcx.item_predicates(def_id); parent.get_type_parameter_bounds(astconv, span, node_id) }); results.extend(self.predicates.iter().filter(|predicate| { match **predicate { ty::Predicate::Trait(ref data) => { - data.skip_binder().self_ty().is_param(def.index) + data.skip_binder().self_ty().is_param(index) } ty::Predicate::TypeOutlives(ref data) => { - data.skip_binder().0.is_param(def.index) + data.skip_binder().0.is_param(index) } ty::Predicate::Equate(..) | ty::Predicate::RegionOutlives(..) | @@ -568,7 +580,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> { impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics { fn get_type_parameter_bounds(&self, astconv: &AstConv<'tcx, 'tcx>, - _: Span, + span: Span, node_id: ast::NodeId) -> Vec> { @@ -576,8 +588,15 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics { // written inline like `` or in a where clause like // `where T:Foo`. - let def = astconv.tcx().type_parameter_def(node_id); - let ty = astconv.tcx().mk_param_from_def(&def); + let tcx = astconv.tcx(); + let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id)); + let index = match astconv.get_generics(span, item_def_id) { + Ok(generics) => { + generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index] + } + Err(ErrorReported) => return vec![] + }; + let ty = tcx.mk_param(index, ::ty_param_name(tcx, node_id)); let from_ty_params = self.ty_params @@ -594,7 +613,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics { hir::WherePredicate::BoundPredicate(ref bp) => Some(bp), _ => None }) - .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id)) + .filter(|bp| is_param(tcx, &bp.bounded_ty, node_id)) .flat_map(|bp| bp.bounds.iter()) .flat_map(|b| predicates_from_bound(astconv, ty, b)); @@ -625,7 +644,7 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - struct_generics: &'tcx ty::Generics<'tcx>, + struct_generics: &'tcx ty::Generics, struct_predicates: &ty::GenericPredicates<'tcx>, field: &hir::StructField, ty_f: &'tcx ty::FieldDef) @@ -938,7 +957,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def: &'tcx ty::AdtDef, ty: Ty<'tcx>, - generics: &'tcx ty::Generics<'tcx>, + generics: &'tcx ty::Generics, predicates: ty::GenericPredicates<'tcx>, variants: &[hir::Variant]) { // fill the field types @@ -1325,7 +1344,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: DefId) - -> &'tcx ty::Generics<'tcx> { + -> &'tcx ty::Generics { let tcx = ccx.tcx; let node_id = if let Some(id) = tcx.hir.as_local_node_id(def_id) { id @@ -1402,18 +1421,14 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // the node id for the Self type parameter. let param_id = item.id; - let parent = ccx.tcx.hir.get_parent(param_id); - - let def = ty::TypeParameterDef { + opt_self = Some(ty::TypeParameterDef { index: 0, name: keywords::SelfType.name(), def_id: tcx.hir.local_def_id(param_id), - default_def_id: tcx.hir.local_def_id(parent), - default: None, + has_default: false, + object_lifetime_default: rl::Set1::Empty, pure_wrt_drop: false, - }; - tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone()); - opt_self = Some(def); + }); allow_defaults = true; generics @@ -1459,11 +1474,36 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } }).collect::>(); + let object_lifetime_defaults = + tcx.named_region_map.object_lifetime_defaults.get(&node_id); + // Now create the real type parameters. let type_start = own_start + regions.len() as u32; let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| { - let i = type_start + i as u32; - get_or_create_type_parameter_def(ccx, i, p, allow_defaults) + if p.name == keywords::SelfType.name() { + span_bug!(p.span, "`Self` should not be the name of a regular parameter"); + } + + if !allow_defaults && p.default.is_some() { + if !tcx.sess.features.borrow().default_type_parameter_fallback { + tcx.sess.add_lint( + lint::builtin::INVALID_TYPE_PARAM_DEFAULT, + p.id, + p.span, + format!("defaults for type parameters are only allowed in `struct`, \ + `enum`, `type`, or `trait` definitions.")); + } + } + + ty::TypeParameterDef { + index: type_start + i as u32, + name: p.name, + def_id: tcx.hir.local_def_id(p.id), + has_default: p.default.is_some(), + object_lifetime_default: + object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]), + pure_wrt_drop: p.pure_wrt_drop, + } }); let mut types: Vec<_> = opt_self.into_iter().chain(types).collect(); @@ -1476,19 +1516,25 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, index: type_start + i as u32, name: Symbol::intern(""), def_id: def_id, - default_def_id: parent_def_id.unwrap(), - default: None, + has_default: false, + object_lifetime_default: rl::Set1::Empty, pure_wrt_drop: false, })); }); } + let mut type_param_to_index = BTreeMap::new(); + for param in &types { + type_param_to_index.insert(param.def_id.index, param.index); + } + tcx.alloc_generics(ty::Generics { parent: parent_def_id, parent_regions: parent_regions, parent_types: parent_types, regions: regions, types: types, + type_param_to_index: type_param_to_index, has_self: has_self || parent_has_self }) }) @@ -1576,6 +1622,9 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, |def, _| ccx.tcx.mk_param_from_def(def) )) } + NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => { + ccx.icx(&()).to_ty(ty) + } x => { bug!("unexpected sort of node in type_of_def_id(): {:?}", x); } @@ -1808,54 +1857,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } } -fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, - index: u32, - param: &hir::TyParam, - allow_defaults: bool) - -> ty::TypeParameterDef<'tcx> -{ - let tcx = ccx.tcx; - match tcx.ty_param_defs.borrow().get(¶m.id) { - Some(d) => { return d.clone(); } - None => { } - } - - let default = - param.default.as_ref().map(|def| ccx.icx(&()).to_ty(def)); - - let parent = tcx.hir.get_parent(param.id); - - if !allow_defaults && default.is_some() { - if !tcx.sess.features.borrow().default_type_parameter_fallback { - tcx.sess.add_lint( - lint::builtin::INVALID_TYPE_PARAM_DEFAULT, - param.id, - param.span, - format!("defaults for type parameters are only allowed in `struct`, \ - `enum`, `type`, or `trait` definitions.")); - } - } - - let def = ty::TypeParameterDef { - index: index, - name: param.name, - def_id: ccx.tcx.hir.local_def_id(param.id), - default_def_id: ccx.tcx.hir.local_def_id(parent), - default: default, - pure_wrt_drop: param.pure_wrt_drop, - }; - - if def.name == keywords::SelfType.name() { - span_bug!(param.span, "`Self` should not be the name of a regular parameter"); - } - - tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone()); - - debug!("get_or_create_type_parameter_def: def for type param: {:?}", def); - - def -} - pub enum SizedByDefault { Yes, No, } /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 5bfc3a934af..1ff6944d98d 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1701,33 +1701,6 @@ struct Foo { ``` "##, -E0128: r##" -Type parameter defaults can only use parameters that occur before them. -Erroneous code example: - -```compile_fail,E0128 -struct Foo { - field1: T, - filed2: U, -} -// error: type parameters with a default cannot use forward declared -// identifiers -``` - -Since type parameters are evaluated in-order, you may be able to fix this issue -by doing: - -``` -struct Foo { - field1: T, - filed2: U, -} -``` - -Please also verify that this wasn't because of a name-clash and rename the type -parameter if so. -"##, - E0131: r##" It is not possible to define `main` with type parameters, or even with function parameters. When `main` is present, it must take no arguments and return `()`. diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 0bcf8ab7d6c..03175782c38 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -116,6 +116,7 @@ use util::common::time; use syntax::ast; use syntax::abi::Abi; +use syntax::symbol::keywords; use syntax_pos::Span; use std::iter; @@ -193,6 +194,30 @@ fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }) } +fn ty_param_owner(tcx: TyCtxt, id: ast::NodeId) -> ast::NodeId { + match tcx.hir.get(id) { + hir::map::NodeItem(&hir::Item { node: hir::ItemTrait(..), .. }) => id, + hir::map::NodeTyParam(_) => tcx.hir.get_parent_node(id), + _ => { + bug!("ty_param_owner: {} not a type parameter", + tcx.hir.node_to_string(id)) + } + } +} + +fn ty_param_name(tcx: TyCtxt, id: ast::NodeId) -> ast::Name { + match tcx.hir.get(id) { + hir::map::NodeItem(&hir::Item { node: hir::ItemTrait(..), .. }) => { + keywords::SelfType.name() + } + hir::map::NodeTyParam(tp) => tp.name, + _ => { + bug!("ty_param_name: {} not a type parameter", + tcx.hir.node_to_string(id)) + } + } +} + fn check_main_fn_ty(ccx: &CrateCtxt, main_id: ast::NodeId, main_span: Span) { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 860f6d98370..b22db940798 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -279,7 +279,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } fn add_constraints_from_trait_ref(&mut self, - generics: &ty::Generics<'tcx>, + generics: &ty::Generics, trait_ref: ty::TraitRef<'tcx>, variance: VarianceTermPtr<'a>) { debug!("add_constraints_from_trait_ref: trait_ref={:?} variance={:?}", @@ -305,7 +305,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { /// in a context with the generics defined in `generics` and /// ambient variance `variance` fn add_constraints_from_ty(&mut self, - generics: &ty::Generics<'tcx>, + generics: &ty::Generics, ty: Ty<'tcx>, variance: VarianceTermPtr<'a>) { debug!("add_constraints_from_ty(ty={:?}, variance={:?})", @@ -433,9 +433,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { /// Adds constraints appropriate for a nominal type (enum, struct, /// object, etc) appearing in a context with ambient variance `variance` fn add_constraints_from_substs(&mut self, - generics: &ty::Generics<'tcx>, + generics: &ty::Generics, def_id: DefId, - type_param_defs: &[ty::TypeParameterDef<'tcx>], + type_param_defs: &[ty::TypeParameterDef], region_param_defs: &[ty::RegionParameterDef], substs: &Substs<'tcx>, variance: VarianceTermPtr<'a>) { @@ -465,7 +465,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { /// Adds constraints appropriate for a function with signature /// `sig` appearing in a context with ambient variance `variance` fn add_constraints_from_sig(&mut self, - generics: &ty::Generics<'tcx>, + generics: &ty::Generics, sig: &ty::PolyFnSig<'tcx>, variance: VarianceTermPtr<'a>) { let contra = self.contravariant(variance); @@ -478,7 +478,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { /// Adds constraints appropriate for a region appearing in a /// context with ambient variance `variance` fn add_constraints_from_region(&mut self, - generics: &ty::Generics<'tcx>, + generics: &ty::Generics, region: &'tcx ty::Region, variance: VarianceTermPtr<'a>) { match *region { @@ -518,7 +518,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { /// Adds constraints appropriate for a mutability-type pair /// appearing in a context with ambient variance `variance` fn add_constraints_from_mt(&mut self, - generics: &ty::Generics<'tcx>, + generics: &ty::Generics, mt: &ty::TypeAndMut<'tcx>, variance: VarianceTermPtr<'a>) { match mt.mutbl { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 751ed7d443d..dc09fc2b8d3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -596,14 +596,18 @@ impl Clean for hir::TyParam { } } -impl<'tcx> Clean for ty::TypeParameterDef<'tcx> { +impl<'tcx> Clean for ty::TypeParameterDef { fn clean(&self, cx: &DocContext) -> TyParam { cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx)); TyParam { name: self.name.clean(cx), did: self.def_id, bounds: vec![], // these are filled in from the where-clauses - default: self.default.clean(cx), + default: if self.has_default { + Some(cx.tcx.item_type(self.def_id).clean(cx)) + } else { + None + } } } } @@ -965,7 +969,7 @@ impl Clean for hir::Generics { } } -impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, +impl<'a, 'tcx> Clean for (&'a ty::Generics, &'a ty::GenericPredicates<'tcx>) { fn clean(&self, cx: &DocContext) -> Generics { use self::WherePredicate as WP; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index bfab7a250c6..013632141de 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -68,6 +68,9 @@ pub trait Visitor<'ast>: Sized { fn visit_expr_post(&mut self, _ex: &'ast Expr) { } fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) } fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) } + fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { + walk_where_predicate(self, p) + } fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, s: Span, _: NodeId) { walk_fn(self, fk, fd, s) } @@ -488,28 +491,30 @@ pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics walk_list!(visitor, visit_attribute, &*param.attrs); } walk_list!(visitor, visit_lifetime_def, &generics.lifetimes); - for predicate in &generics.where_clause.predicates { - match *predicate { - WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, - ref bounds, - ref bound_lifetimes, - ..}) => { - visitor.visit_ty(bounded_ty); - walk_list!(visitor, visit_ty_param_bound, bounds); - walk_list!(visitor, visit_lifetime_def, bound_lifetimes); - } - WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, - ref bounds, - ..}) => { - visitor.visit_lifetime(lifetime); - walk_list!(visitor, visit_lifetime, bounds); - } - WherePredicate::EqPredicate(WhereEqPredicate{ref lhs_ty, - ref rhs_ty, - ..}) => { - visitor.visit_ty(lhs_ty); - visitor.visit_ty(rhs_ty); - } + walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates); +} + +pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate) { + match *predicate { + WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, + ref bounds, + ref bound_lifetimes, + ..}) => { + visitor.visit_ty(bounded_ty); + walk_list!(visitor, visit_ty_param_bound, bounds); + walk_list!(visitor, visit_lifetime_def, bound_lifetimes); + } + WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, + ref bounds, + ..}) => { + visitor.visit_lifetime(lifetime); + walk_list!(visitor, visit_lifetime, bounds); + } + WherePredicate::EqPredicate(WhereEqPredicate{ref lhs_ty, + ref rhs_ty, + ..}) => { + visitor.visit_ty(lhs_ty); + visitor.visit_ty(rhs_ty); } } } diff --git a/src/test/compile-fail/cycle-trait-default-type-trait.rs b/src/test/compile-fail/cycle-trait-default-type-trait.rs index e6caeb34a8c..6825572b26c 100644 --- a/src/test/compile-fail/cycle-trait-default-type-trait.rs +++ b/src/test/compile-fail/cycle-trait-default-type-trait.rs @@ -13,6 +13,7 @@ trait Foo> { //~^ ERROR unsupported cyclic reference + //~| ERROR unsupported cyclic reference } fn main() { } diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/compile-fail/generic-non-trailing-defaults.rs index 77e55203263..13b7753082c 100644 --- a/src/test/compile-fail/generic-non-trailing-defaults.rs +++ b/src/test/compile-fail/generic-non-trailing-defaults.rs @@ -10,10 +10,10 @@ struct Heap; -struct Vec; +struct Vec(A, T); //~^ ERROR type parameters with a default must be trailing -struct Foo, C>; +struct Foo, C>(A, B, C); //~^ ERROR type parameters with a default must be trailing //~| ERROR type parameters with a default cannot use forward declared identifiers diff --git a/src/test/compile-fail/generic-type-params-forward-mention.rs b/src/test/compile-fail/generic-type-params-forward-mention.rs index eda1b014fa7..bfa6af0da43 100644 --- a/src/test/compile-fail/generic-type-params-forward-mention.rs +++ b/src/test/compile-fail/generic-type-params-forward-mention.rs @@ -9,7 +9,7 @@ // except according to those terms. // Ensure that we get an error and not an ICE for this problematic case. -struct Foo, U = bool>; +struct Foo, U = bool>(T, U); //~^ ERROR type parameters with a default cannot use forward declared identifiers fn main() { let x: Foo; diff --git a/src/test/compile-fail/issue-18183.rs b/src/test/compile-fail/issue-18183.rs index b3fc3aea148..feab04531b7 100644 --- a/src/test/compile-fail/issue-18183.rs +++ b/src/test/compile-fail/issue-18183.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub struct Foo; //~ ERROR E0128 - //~| NOTE defaulted type parameters cannot be forward declared +pub struct Foo(Bar); //~ ERROR E0128 + //~| NOTE defaulted type parameters cannot be forward declared pub struct Baz(Foo); fn main() {} diff --git a/src/test/compile-fail/resolve-self-in-impl.rs b/src/test/compile-fail/resolve-self-in-impl.rs index 04f98c7ab32..ab9ac039825 100644 --- a/src/test/compile-fail/resolve-self-in-impl.rs +++ b/src/test/compile-fail/resolve-self-in-impl.rs @@ -15,7 +15,7 @@ impl Tr for S {} // OK // FIXME: `Self` cannot be used in bounds because it depends on bounds itself. impl> Tr for S {} //~ ERROR `Self` type is used before it's determined -impl Tr for S {} //~ ERROR `Self` type is used before it's determined +impl Tr for S {} impl Tr for S where Self: Copy {} //~ ERROR `Self` type is used before it's determined impl Tr for S where S: Copy {} //~ ERROR `Self` type is used before it's determined impl Tr for S where Self::Assoc: Copy {} //~ ERROR `Self` type is used before it's determined