From c1cfd58cbdb84f834b8907dc5e1c7242c451225d Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Mon, 15 Aug 2016 01:07:09 +0300 Subject: [PATCH] rustc: remove SelfSpace from ParamSpace. --- src/librustc/hir/def.rs | 5 +- src/librustc/middle/dead.rs | 2 +- src/librustc/traits/coherence.rs | 6 +- src/librustc/traits/error_reporting.rs | 4 +- src/librustc/traits/object_safety.rs | 9 +- src/librustc/ty/context.rs | 2 +- src/librustc/ty/error.rs | 3 +- src/librustc/ty/flags.rs | 4 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/sty.rs | 14 +++- src/librustc/ty/subst.rs | 78 ++++++----------- src/librustc/util/ppaux.rs | 67 +++++++-------- .../borrowck/mir/elaborate_drops.rs | 6 +- src/librustc_metadata/astencode.rs | 2 +- src/librustc_metadata/tydecode.rs | 6 +- src/librustc_resolve/lib.rs | 32 ++----- src/librustc_save_analysis/lib.rs | 2 +- src/librustc_trans/partitioning.rs | 2 +- src/librustc_typeck/astconv.rs | 52 ++++++++---- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 6 +- src/librustc_typeck/check/method/probe.rs | 8 +- src/librustc_typeck/check/mod.rs | 27 ++++-- src/librustc_typeck/check/wfcheck.rs | 45 +++------- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/collect.rs | 83 +++++++------------ src/librustc_typeck/variance/constraints.rs | 8 +- src/librustc_typeck/variance/solve.rs | 10 +-- src/librustc_typeck/variance/terms.rs | 12 +-- src/librustdoc/clean/mod.rs | 38 +++++---- src/test/compile-fail/issue-26548.rs | 4 +- src/test/compile-fail/issue-26812.rs | 4 +- .../compile-fail/variance-associated-types.rs | 4 +- .../compile-fail/variance-object-types.rs | 2 +- .../compile-fail/variance-region-bounds.rs | 4 +- .../compile-fail/variance-regions-direct.rs | 14 ++-- .../compile-fail/variance-regions-indirect.rs | 10 +-- .../compile-fail/variance-trait-bounds.rs | 18 ++-- .../variance-trait-object-bound.rs | 2 +- .../compile-fail/variance-types-bounds.rs | 20 ++--- src/test/compile-fail/variance-types.rs | 12 +-- 41 files changed, 276 insertions(+), 357 deletions(-) diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 218681efb7d..d15d51aed09 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -9,7 +9,6 @@ // except according to those terms. use hir::def_id::DefId; -use ty::subst::ParamSpace; use util::nodemap::NodeMap; use syntax::ast; use hir; @@ -31,7 +30,7 @@ pub enum Def { AssociatedTy(DefId /* trait */, DefId), Trait(DefId), PrimTy(hir::PrimTy), - TyParam(ParamSpace, u32, DefId, ast::Name), + TyParam(DefId), Upvar(DefId, // def id of closed over local ast::NodeId, // node id of closed over local usize, // index in the freevars list of the closure @@ -122,7 +121,7 @@ impl Def { match *self { Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) | Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) | - Def::TyParam(_, _, id, _) | Def::Struct(id) | Def::Trait(id) | + Def::TyParam(id) | Def::Struct(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) | Def::Local(id, _) | Def::Upvar(id, _, _, _) => { id diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 7412b5fc804..20e281816b8 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_) if self.tcx.trait_of_item(def.def_id()).is_some() => { if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) { - match substs.substs.types.get(subst::SelfSpace, 0).sty { + match substs.substs.types.get(subst::TypeSpace, 0).sty { TyEnum(tyid, _) | TyStruct(tyid, _) => { self.check_def_id(tyid.did) } diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index f1701d60fd0..a5a415dd27c 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -14,7 +14,6 @@ use super::{SelectionContext, Obligation, ObligationCause}; use middle::cstore::LOCAL_CRATE; use hir::def_id::DefId; -use ty::subst::TypeSpace; use ty::{self, Ty, TyCtxt}; use infer::{InferCtxt, TypeOrigin}; use syntax_pos::DUMMY_SP; @@ -160,12 +159,9 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt, // First, create an ordered iterator over all the type parameters to the trait, with the self // type appearing first. - let input_tys = Some(trait_ref.self_ty()); - let input_tys = input_tys.iter().chain(trait_ref.substs.types.get_slice(TypeSpace)); - // Find the first input type that either references a type parameter OR // some local type. - for input_ty in input_tys { + for input_ty in trait_ref.input_types() { if ty_is_local(tcx, input_ty, infer_is_local) { debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index e67c0ba8053..77c1137c6c3 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -232,8 +232,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Ok(..) = self.can_equate(&trait_self_ty, &impl_self_ty) { self_match_impls.push(def_id); - if trait_ref.substs.types.get_slice(TypeSpace).iter() - .zip(impl_trait_ref.substs.types.get_slice(TypeSpace)) + if trait_ref.substs.types.get_slice(TypeSpace)[1..].iter() + .zip(&impl_trait_ref.substs.types.get_slice(TypeSpace)[1..]) .all(|(u,v)| self.fuzzy_match_tys(u, v)) { fuzzy_match_impls.push(def_id); diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index ecfa7930d02..11cf759859c 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -20,7 +20,7 @@ use super::elaborate_predicates; use hir::def_id::DefId; -use ty::subst::{self, SelfSpace, TypeSpace}; +use ty::subst; use traits; use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; use std::rc::Rc; @@ -146,10 +146,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match predicate { ty::Predicate::Trait(ref data) => { // In the case of a trait predicate, we can skip the "self" type. - data.0.trait_ref.substs.types.get_slice(TypeSpace) - .iter() - .cloned() - .any(|t| t.has_self_ty()) + data.0.trait_ref.input_types()[1..].iter().any(|t| t.has_self_ty()) } ty::Predicate::Projection(..) | ty::Predicate::WellFormed(..) | @@ -325,7 +322,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty.maybe_walk(|ty| { match ty.sty { ty::TyParam(ref param_ty) => { - if param_ty.space == SelfSpace { + if param_ty.is_self() { error = true; } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 9356b408a51..c2daa81ca7d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1353,7 +1353,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn mk_self_type(self) -> Ty<'tcx> { - self.mk_param(subst::SelfSpace, 0, keywords::SelfType.name()) + self.mk_param(subst::TypeSpace, 0, keywords::SelfType.name()) } pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 933746ebc2a..17f9b6c2599 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -9,7 +9,6 @@ // except according to those terms. use hir::def_id::DefId; -use ty::subst; use infer::type_variable; use ty::{self, BoundRegion, Region, Ty, TyCtxt}; @@ -258,7 +257,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::TyInfer(ty::FreshFloatTy(_)) => "skolemized floating-point type".to_string(), ty::TyProjection(_) => "associated type".to_string(), ty::TyParam(ref p) => { - if p.space == subst::SelfSpace { + if p.is_self() { "Self".to_string() } else { "type parameter".to_string() diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 312b09cd27d..900e1841fb5 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ty::subst::{self, Substs}; +use ty::subst::Substs; use ty::{self, Ty, TypeFlags, TypeFoldable}; pub struct FlagComputation { @@ -77,7 +77,7 @@ impl FlagComputation { &ty::TyParam(ref p) => { self.add_flags(TypeFlags::HAS_LOCAL_NAMES); - if p.space == subst::SelfSpace { + if p.is_self() { self.add_flags(TypeFlags::HAS_SELF); } else { self.add_flags(TypeFlags::HAS_PARAMS); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 36784e40064..96537904d36 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1225,7 +1225,7 @@ impl<'tcx> TraitRef<'tcx> { } pub fn self_ty(&self) -> Ty<'tcx> { - *self.substs.types.get(subst::SelfSpace, 0) + *self.substs.types.get(subst::TypeSpace, 0) } pub fn input_types(&self) -> &[Ty<'tcx>] { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index f31b844f04f..8786e2d16d2 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -305,7 +305,7 @@ pub struct TraitObject<'tcx> { /// /// This would be represented by a trait-reference where the def-id is the /// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the -/// `SelfSpace` and `U` as parameter 0 in the `TypeSpace`. +/// `TypeSpace` and `U` as parameter 1 in the `TypeSpace`. /// /// Trait references also appear in object types like `Foo`, but in /// that case the `Self` parameter is absent from the substitutions. @@ -512,7 +512,7 @@ impl<'a, 'gcx, 'tcx> ParamTy { } pub fn for_self() -> ParamTy { - ParamTy::new(subst::SelfSpace, 0, keywords::SelfType.name()) + ParamTy::new(subst::TypeSpace, 0, keywords::SelfType.name()) } pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy { @@ -524,7 +524,13 @@ impl<'a, 'gcx, 'tcx> ParamTy { } pub fn is_self(&self) -> bool { - self.space == subst::SelfSpace && self.idx == 0 + if self.name == keywords::SelfType.name() { + assert_eq!(self.space, subst::TypeSpace); + assert_eq!(self.idx, 0); + true + } else { + false + } } } @@ -954,7 +960,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_self(&self) -> bool { match self.sty { - TyParam(ref p) => p.space == subst::SelfSpace, + TyParam(ref p) => p.is_self(), _ => false } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 00537f9d6c5..2f95baa5625 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -47,8 +47,8 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { r: Vec) -> &'tcx Substs<'tcx> { - Substs::new(tcx, VecPerParamSpace::new(vec![], vec![], t), - VecPerParamSpace::new(vec![], vec![], r)) + Substs::new(tcx, VecPerParamSpace::new(vec![], t), + VecPerParamSpace::new(vec![], r)) } pub fn new_type(tcx: TyCtxt<'a, 'gcx, 'tcx>, @@ -56,18 +56,19 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { r: Vec) -> &'tcx Substs<'tcx> { - Substs::new(tcx, VecPerParamSpace::new(vec![], t, vec![]), - VecPerParamSpace::new(vec![], r, vec![])) + Substs::new(tcx, VecPerParamSpace::new(t, vec![]), + VecPerParamSpace::new(r, vec![])) } pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>, - t: Vec>, + mut t: Vec>, r: Vec, s: Ty<'tcx>) -> &'tcx Substs<'tcx> { - Substs::new(tcx, VecPerParamSpace::new(vec![s], t, vec![]), - VecPerParamSpace::new(vec![], r, vec![])) + t.insert(0, s); + Substs::new(tcx, VecPerParamSpace::new(t, vec![]), + VecPerParamSpace::new(r, vec![])) } pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> { @@ -90,12 +91,10 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { let defs = tcx.lookup_generics(def_id); let mut substs = Substs { types: VecPerParamSpace { - self_limit: 0, type_limit: 0, content: Vec::with_capacity(defs.types.content.len()) }, regions: VecPerParamSpace { - self_limit: 0, type_limit: 0, content: Vec::with_capacity(defs.regions.content.len()) } @@ -104,7 +103,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { for &space in &ParamSpace::all() { for def in defs.regions.get_slice(space) { assert_eq!(def.space, space); - assert!(space != SelfSpace); let region = mk_region(def, &substs); substs.regions.content.push(region); @@ -120,11 +118,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { let ty = mk_type(def, &substs); substs.types.content.push(ty); - if space == SelfSpace { - substs.types.self_limit += 1; - } - - if space <= TypeSpace { + if space == TypeSpace { substs.types.type_limit += 1; } } @@ -155,7 +149,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { target_substs: &Substs<'tcx>) -> &'tcx Substs<'tcx> { let defs = tcx.lookup_generics(source_ancestor); - assert_eq!(self.types.len(SelfSpace), defs.types.len(SelfSpace)); assert_eq!(self.types.len(TypeSpace), defs.types.len(TypeSpace)); assert_eq!(target_substs.types.len(FnSpace), 0); assert_eq!(defs.types.len(FnSpace), 0); @@ -195,29 +188,26 @@ impl<'tcx> Decodable for &'tcx Substs<'tcx> { #[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Hash, RustcEncodable, RustcDecodable, Debug)] pub enum ParamSpace { - SelfSpace, // Self parameter on a trait TypeSpace, // Type parameters attached to a type definition, trait, or impl FnSpace, // Type parameters attached to a method or fn } impl ParamSpace { - pub fn all() -> [ParamSpace; 3] { - [SelfSpace, TypeSpace, FnSpace] + pub fn all() -> [ParamSpace; 2] { + [TypeSpace, FnSpace] } pub fn to_uint(self) -> usize { match self { - SelfSpace => 0, - TypeSpace => 1, - FnSpace => 2, + TypeSpace => 0, + FnSpace => 1, } } pub fn from_uint(u: usize) -> ParamSpace { match u { - 0 => SelfSpace, - 1 => TypeSpace, - 2 => FnSpace, + 0 => TypeSpace, + 1 => FnSpace, _ => bug!("Invalid ParamSpace: {}", u) } } @@ -235,18 +225,15 @@ pub struct VecPerParamSpace { // Here is how the representation corresponds to the abstraction // i.e. the "abstraction function" AF: // - // AF(self) = (self.content[..self.self_limit], - // self.content[self.self_limit..self.type_limit], + // AF(self) = (self.content[..self.type_limit], // self.content[self.type_limit..]) - self_limit: usize, type_limit: usize, content: Vec, } impl fmt::Debug for VecPerParamSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "[{:?};{:?};{:?}]", - self.get_slice(SelfSpace), + write!(f, "[{:?};{:?}]", self.get_slice(TypeSpace), self.get_slice(FnSpace)) } @@ -255,43 +242,34 @@ impl fmt::Debug for VecPerParamSpace { impl VecPerParamSpace { fn limits(&self, space: ParamSpace) -> (usize, usize) { match space { - SelfSpace => (0, self.self_limit), - TypeSpace => (self.self_limit, self.type_limit), + TypeSpace => (0, self.type_limit), FnSpace => (self.type_limit, self.content.len()), } } pub fn empty() -> VecPerParamSpace { VecPerParamSpace { - self_limit: 0, type_limit: 0, content: Vec::new() } } - /// `s` is the self space. /// `t` is the type space. /// `f` is the fn space. - pub fn new(s: Vec, t: Vec, f: Vec) -> VecPerParamSpace { - let self_limit = s.len(); - let type_limit = self_limit + t.len(); + pub fn new(t: Vec, f: Vec) -> VecPerParamSpace { + let type_limit = t.len(); - let mut content = s; - content.extend(t); + let mut content = t; content.extend(f); VecPerParamSpace { - self_limit: self_limit, type_limit: type_limit, content: content, } } - fn new_internal(content: Vec, self_limit: usize, type_limit: usize) - -> VecPerParamSpace - { + fn new_internal(content: Vec, type_limit: usize) -> VecPerParamSpace { VecPerParamSpace { - self_limit: self_limit, type_limit: type_limit, content: content, } @@ -336,18 +314,14 @@ impl VecPerParamSpace { pub fn map(&self, pred: P) -> VecPerParamSpace where P: FnMut(&T) -> U { let result = self.as_full_slice().iter().map(pred).collect(); - VecPerParamSpace::new_internal(result, - self.self_limit, - self.type_limit) + VecPerParamSpace::new_internal(result, self.type_limit) } pub fn map_enumerated(&self, pred: P) -> VecPerParamSpace where P: FnMut((ParamSpace, usize, &T)) -> U, { let result = self.iter_enumerated().map(pred).collect(); - VecPerParamSpace::new_internal(result, - self.self_limit, - self.type_limit) + VecPerParamSpace::new_internal(result, self.type_limit) } } @@ -639,8 +613,6 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> { -> ty::ExistentialTraitRef<'tcx> { let Substs { mut types, regions } = trait_ref.substs.clone(); - assert_eq!(types.self_limit, 1); - types.self_limit = 0; types.type_limit -= 1; types.content.remove(0); @@ -665,8 +637,6 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> { self.map_bound(|trait_ref| { let Substs { mut types, regions } = trait_ref.substs.clone(); - assert_eq!(types.self_limit, 0); - types.self_limit = 1; types.type_limit += 1; types.content.insert(0, self_ty); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index cdbd3070523..800ad865208 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -62,35 +62,36 @@ pub enum Ns { Value } -fn number_of_supplied_defaults<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - substs: &subst::Substs, - space: subst::ParamSpace, - generics: &ty::Generics<'tcx>) - -> usize -{ - let ty_params = generics.types.get_slice(space); - let tps = substs.types.get_slice(space); - if ty_params.last().map_or(false, |def| def.default.is_some()) { - let substs = tcx.lift(&substs); - ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| { - substs.and_then(|substs| def.default.subst(tcx, substs)) - == Some(actual) - }).count() - } else { - 0 - } -} - pub fn parameterized(f: &mut fmt::Formatter, substs: &subst::Substs, did: DefId, ns: Ns, projections: &[ty::ProjectionPredicate]) -> fmt::Result { - let (fn_trait_kind, verbose, item_name, is_in_trait) = ty::tls::with(|tcx| { - let is_in_trait = ns == Ns::Value && tcx.trait_of_item(did).is_some(); - if is_in_trait { - write!(f, "<{} as ", substs.types.get(subst::SelfSpace, 0))?; + let mut verbose = false; + let mut num_supplied_defaults = 0; + let mut has_self = false; + let (fn_trait_kind, item_name) = ty::tls::with(|tcx| { + verbose = tcx.sess.verbose(); + let generics = tcx.lookup_generics(did); + if !verbose { + let ty_params = generics.types.get_slice(subst::TypeSpace); + if ty_params.last().map_or(false, |def| def.default.is_some()) { + if let Some(substs) = tcx.lift(&substs) { + let tps = substs.types.get_slice(subst::TypeSpace); + for (def, actual) in ty_params.iter().zip(tps).rev() { + if def.default.subst(tcx, substs) != Some(actual) { + break; + } + num_supplied_defaults += 1; + } + } + } + } + + has_self = generics.has_self; + if ns == Ns::Value && has_self { + write!(f, "<{} as ", substs.types.get(subst::TypeSpace, 0))?; } let (did, item_name) = if ns == Ns::Value { @@ -107,15 +108,12 @@ pub fn parameterized(f: &mut fmt::Formatter, (did, None) }; write!(f, "{}", tcx.item_path_str(did))?; - Ok((tcx.lang_items.fn_trait_kind(did), - tcx.sess.verbose(), - item_name, - is_in_trait)) + Ok((tcx.lang_items.fn_trait_kind(did), item_name)) })?; if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { let projection_ty = projections[0].ty; - if let TyTuple(ref args) = substs.types.get(subst::TypeSpace, 0).sty { + if let TyTuple(ref args) = substs.types.get(subst::TypeSpace, 1).sty { return fn_sig(f, args, false, projection_ty); } } @@ -160,18 +158,9 @@ pub fn parameterized(f: &mut fmt::Formatter, print_regions(f, "<", substs.regions.get_slice(subst::TypeSpace))?; - let num_supplied_defaults = if verbose { - 0 - } else { - ty::tls::with(|tcx| { - let generics = tcx.lookup_generics(did); - number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics) - }) - }; - let tps = substs.types.get_slice(subst::TypeSpace); - for &ty in &tps[..tps.len() - num_supplied_defaults] { + for &ty in &tps[has_self as usize..tps.len() - num_supplied_defaults] { start_or_continue(f, "<", ", ")?; write!(f, "{}", ty)?; } @@ -189,7 +178,7 @@ pub fn parameterized(f: &mut fmt::Formatter, if ns == Ns::Value { empty.set(true); - if is_in_trait { + if has_self { write!(f, ">")?; } diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index df91ec2b98d..9f300b5b29b 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -16,7 +16,7 @@ use super::{drop_flag_effects_for_location, on_all_children_bits}; use super::{DropFlagState, MoveDataParamEnv}; use super::patch::MirPatch; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::subst::{Subst, Substs, VecPerParamSpace}; +use rustc::ty::subst::{Subst, Substs}; use rustc::mir::repr::*; use rustc::mir::transform::{Pass, MirPass, MirSource}; use rustc::middle::const_val::ConstVal; @@ -859,9 +859,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let unit_temp = Lvalue::Temp(self.patch.new_temp(tcx.mk_nil())); let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem) .unwrap_or_else(|e| tcx.sess.fatal(&e)); - let substs = Substs::new(tcx, - VecPerParamSpace::new(vec![], vec![], vec![ty]), - VecPerParamSpace::new(vec![], vec![], vec![])); + let substs = Substs::new_fn(tcx, vec![ty], vec![]); let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs); self.patch.new_block(BasicBlockData { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 1b00eee76f6..1ef48e6d656 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -413,7 +413,7 @@ impl tr for Def { Def::AssociatedTy(trait_did, did) => Def::AssociatedTy(trait_did.tr(dcx), did.tr(dcx)), Def::PrimTy(p) => Def::PrimTy(p), - Def::TyParam(s, index, def_id, n) => Def::TyParam(s, index, def_id.tr(dcx), n), + Def::TyParam(did) => Def::TyParam(did.tr(dcx)), Def::Upvar(_, nid1, index, nid2) => { let nid1 = dcx.tr_id(nid1); let nid2 = dcx.tr_id(nid2); diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs index 3f0fa9073aa..82d050a1de9 100644 --- a/src/librustc_metadata/tydecode.rs +++ b/src/librustc_metadata/tydecode.rs @@ -131,15 +131,15 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { fn parse_vec_per_param_space(&mut self, mut f: F) -> VecPerParamSpace where F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T, { - let (mut a, mut b, mut c) = (vec![], vec![], vec![]); - for r in &mut [&mut a, &mut b, &mut c] { + let (mut a, mut b) = (vec![], vec![]); + for r in &mut [&mut a, &mut b] { assert_eq!(self.next(), '['); while self.peek() != ']' { r.push(f(self)); } assert_eq!(self.next(), ']'); } - VecPerParamSpace::new(a, b, c) + VecPerParamSpace::new(a, b) } pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 962509be324..65e14eee4bc 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -49,7 +49,6 @@ use rustc::lint; use rustc::hir::def::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::ty; -use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace}; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet}; @@ -557,7 +556,7 @@ impl<'a> Visitor for Resolver<'a> { fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { let type_parameters = match foreign_item.node { ForeignItemKind::Fn(_, ref generics) => { - HasTypeParameters(generics, FnSpace, ItemRibKind) + HasTypeParameters(generics, ItemRibKind) } ForeignItemKind::Static(..) => NoTypeParameters, }; @@ -625,10 +624,6 @@ enum TypeParameters<'a, 'b> { HasTypeParameters(// Type parameters. &'b Generics, - // Identifies the things that these parameters - // were declared on (type, fn, etc) - ParamSpace, - // The kind of the rib used for type parameters. RibKind<'a>), } @@ -1613,12 +1608,9 @@ impl<'a> Resolver<'a> { match item.node { ItemKind::Enum(_, ref generics) | ItemKind::Ty(_, ref generics) | - ItemKind::Struct(_, ref generics) => { - self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind), - |this| visit::walk_item(this, item)); - } + ItemKind::Struct(_, ref generics) | ItemKind::Fn(_, _, _, _, ref generics, _) => { - self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind), + self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| visit::walk_item(this, item)); } @@ -1634,10 +1626,7 @@ impl<'a> Resolver<'a> { ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => { // Create a new rib for the trait-wide type parameters. - self.with_type_parameter_rib(HasTypeParameters(generics, - TypeSpace, - ItemRibKind), - |this| { + self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { let local_def_id = this.definitions.local_def_id(item.id); this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| { this.visit_generics(generics); @@ -1660,7 +1649,6 @@ impl<'a> Resolver<'a> { TraitItemKind::Method(ref sig, _) => { let type_parameters = HasTypeParameters(&sig.generics, - FnSpace, MethodRibKind(!sig.decl.has_self())); this.with_type_parameter_rib(type_parameters, |this| { visit::walk_trait_item(this, trait_item) @@ -1729,10 +1717,10 @@ impl<'a> Resolver<'a> { where F: FnOnce(&mut Resolver) { match type_parameters { - HasTypeParameters(generics, space, rib_kind) => { + HasTypeParameters(generics, rib_kind) => { let mut function_type_rib = Rib::new(rib_kind); let mut seen_bindings = HashSet::new(); - for (index, type_parameter) in generics.ty_params.iter().enumerate() { + for type_parameter in &generics.ty_params { let name = type_parameter.ident.name; debug!("with_type_parameter_rib: {}", type_parameter.id); @@ -1745,7 +1733,7 @@ impl<'a> Resolver<'a> { // plain insert (no renaming) let def_id = self.definitions.local_def_id(type_parameter.id); - let def = Def::TyParam(space, index as u32, def_id, name); + let def = Def::TyParam(def_id); function_type_rib.bindings.insert(ast::Ident::with_empty_ctxt(name), def); self.record_def(type_parameter.id, PathResolution::new(def)); } @@ -1917,10 +1905,7 @@ impl<'a> Resolver<'a> { item_id: NodeId, impl_items: &[ImplItem]) { // If applicable, create a rib for the type parameters. - self.with_type_parameter_rib(HasTypeParameters(generics, - TypeSpace, - ItemRibKind), - |this| { + self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| { // Resolve the type parameters. this.visit_generics(generics); @@ -1953,7 +1938,6 @@ impl<'a> Resolver<'a> { // specific type parameters. let type_parameters = HasTypeParameters(&sig.generics, - FnSpace, MethodRibKind(!sig.decl.has_self())); this.with_type_parameter_rib(type_parameters, |this| { visit::walk_impl_item(this, impl_item); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 6c9cf1a5625..db535e22f19 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -490,7 +490,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Def::Enum(def_id) | Def::TyAlias(def_id) | Def::Trait(def_id) | - Def::TyParam(_, _, def_id, _) => { + Def::TyParam(def_id) => { Some(Data::TypeRefData(TypeRefData { span: sub_span.unwrap(), ref_id: Some(def_id), diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index f24ab0f6557..1e90f273301 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -488,7 +488,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // DefId, we use the location of the impl after all. if tcx.trait_of_item(instance.def).is_some() { - let self_ty = *instance.substs.types.get(subst::SelfSpace, 0); + let self_ty = *instance.substs.types.get(subst::TypeSpace, 0); // This is an implementation of a trait method. return characteristic_def_id_of_type(self_ty).or(Some(instance.def)); } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5655c7c8e72..109cfd2abf6 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -55,7 +55,7 @@ use hir::def_id::DefId; use hir::print as pprust; use middle::resolve_lifetime as rl; use rustc::lint; -use rustc::ty::subst::{TypeSpace, SelfSpace, Subst, Substs}; +use rustc::ty::subst::{TypeSpace, Subst, Substs}; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::wf::object_region_bounds; @@ -455,6 +455,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // Check the number of type parameters supplied by the user. if let Some(num_provided) = num_types_provided { let ty_param_defs = decl_generics.types.get_slice(TypeSpace); + let ty_param_defs = &ty_param_defs[self_ty.is_some() as usize..]; check_type_argument_count(tcx, span, num_provided, ty_param_defs); } @@ -476,13 +477,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { assert_eq!(def.space, TypeSpace); regions[def.index as usize] }, |def, substs| { - assert!(def.space == SelfSpace || def.space == TypeSpace); + assert!(def.space == TypeSpace); let i = def.index as usize; - if def.space == SelfSpace { - // Self, which must have been provided. - assert_eq!(i, 0); - self_ty.expect("Self type parameter missing") - } else if num_types_provided.map_or(false, |n| i < n) { + + // Handle Self first, so we can adjust the index to match the AST. + if let (0, Some(ty)) = (i, self_ty) { + return ty; + } + + let i = i - self_ty.is_some() as usize; + if num_types_provided.map_or(false, |n| i < n) { // A provided type parameter. match *parameters { hir::AngleBracketedParameters(ref data) => { @@ -1325,8 +1329,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Err(ErrorReported) => return (tcx.types.err, Def::Err), } } - (&ty::TyParam(_), Def::TyParam(_, _, param_did, param_name)) => { + (&ty::TyParam(_), Def::TyParam(param_did)) => { let param_node_id = tcx.map.as_local_node_id(param_did).unwrap(); + let param_name = tcx.type_parameter_def(param_node_id).name; match self.find_bound_for_assoc_item(param_node_id, param_name, assoc_name, @@ -1336,10 +1341,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } _ => { - self.report_ambiguous_associated_type(span, - &ty.to_string(), - "Trait", - &assoc_name.as_str()); + // Don't print TyErr to the user. + if !ty.references_error() { + self.report_ambiguous_associated_type(span, + &ty.to_string(), + "Trait", + &assoc_name.as_str()); + } return (tcx.types.err, Def::Err); } }; @@ -1477,9 +1485,25 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { did, base_segments.last().unwrap()) } - Def::TyParam(space, index, _, name) => { + Def::TyParam(did) => { tcx.prohibit_type_params(base_segments); - tcx.mk_param(space, index, name) + + let node_id = tcx.map.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 + } } Def::SelfTy(_, Some(impl_id)) => { // Self in impl (we know the concrete type). diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 8a007293e64..087549a2f1c 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -204,7 +204,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return None; } - let arg_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 0); + let arg_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 1); let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty); debug!("deduce_sig_from_projection: arg_param_ty {:?}", arg_param_ty); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index e5107af6ca0..a9e08461fd2 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -183,7 +183,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let trait_def = self.tcx.lookup_trait_def(trait_def_id); if let Some(ref input_types) = opt_input_types { - assert_eq!(trait_def.generics.types.len(subst::TypeSpace), input_types.len()); + assert_eq!(trait_def.generics.types.len(subst::TypeSpace) - 1, input_types.len()); } assert_eq!(trait_def.generics.types.len(subst::FnSpace), 0); assert!(trait_def.generics.regions.is_empty()); @@ -192,10 +192,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| { self.region_var_for_def(span, def) }, |def, substs| { - if def.space == subst::SelfSpace { + if def.index == 0 { self_ty } else if let Some(ref input_types) = opt_input_types { - input_types[def.index as usize] + input_types[def.index as usize - 1] } else { self.type_var_for_def(span, def, substs) } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 448ea243655..044de179917 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -522,10 +522,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { trait_ref.substs.types.len(subst::TypeSpace)); assert_eq!(m.generics.regions.len(subst::TypeSpace), trait_ref.substs.regions.len(subst::TypeSpace)); - assert_eq!(m.generics.types.len(subst::SelfSpace), - trait_ref.substs.types.len(subst::SelfSpace)); - assert_eq!(m.generics.regions.len(subst::SelfSpace), - trait_ref.substs.regions.len(subst::SelfSpace)); } // Because this trait derives from a where-clause, it @@ -755,11 +751,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| { self.region_var_for_def(self.span, def) }, |def, substs| { - if def.space == subst::SelfSpace { - assert_eq!(def.index, 0); + if def.index == 0 { step.self_ty } else { - assert_eq!(def.space, subst::TypeSpace); self.type_var_for_def(self.span, def, substs) } }); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 700fb2ecf42..ae3378f41f9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4225,7 +4225,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| { let i = def.index as usize; let segment = match def.space { - subst::SelfSpace => None, subst::TypeSpace => type_segment, subst::FnSpace => fn_segment }; @@ -4241,9 +4240,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.region_var_for_def(span, def) } }, |def, substs| { - let i = def.index as usize; + let mut i = def.index as usize; let segment = match def.space { - subst::SelfSpace => None, subst::TypeSpace => type_segment, subst::FnSpace => fn_segment }; @@ -4252,18 +4250,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(&hir::ParenthesizedParameters(_)) => bug!(), None => &[] }; + + // Handle Self first, so we can adjust the index to match the AST. + if scheme.generics.has_self && def.space == subst::TypeSpace { + if i == 0 { + return opt_self_ty.unwrap_or_else(|| { + self.type_var_for_def(span, def, substs) + }); + } + i -= 1; + } + let can_omit = def.space != subst::TypeSpace || !require_type_space; let default = if can_omit && types.len() == 0 { def.default } else { None }; - - if def.space == subst::SelfSpace && opt_self_ty.is_some() { - // Self, which has been provided. - assert_eq!(i, 0); - opt_self_ty.unwrap() - } else if let Some(ast_ty) = types.get(i) { + if let Some(ast_ty) = types.get(i) { // A provided type parameter. self.to_ty(ast_ty) } else if let Some(default) = default { @@ -4371,6 +4375,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Check provided type parameters. let type_defs = generics.types.get_slice(space); + let type_defs = if space == subst::TypeSpace { + &type_defs[generics.has_self as usize..] + } else { + type_defs + }; let required_len = type_defs.iter() .take_while(|d| d.default.is_none()) .count(); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 678c102a4de..f2076895f08 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -14,13 +14,12 @@ use CrateCtxt; use hir::def_id::DefId; use middle::region::{CodeExtent}; use rustc::infer::TypeOrigin; -use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace}; +use rustc::ty::subst; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt}; use std::collections::HashSet; use syntax::ast; -use syntax::parse::token::keywords; use syntax_pos::Span; use errors::DiagnosticBuilder; @@ -461,7 +460,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { variances.types .iter_enumerated() .filter(|&(_, _, &variance)| variance != ty::Bivariant) - .map(|(space, index, _)| self.param_ty(ast_generics, space, index)) + .map(|(_, index, _)| self.param_ty(ast_generics, index)) .map(|p| Parameter::Type(p)) .collect(); @@ -470,52 +469,34 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { &mut constrained_parameters); for (space, index, _) in variances.types.iter_enumerated() { - let param_ty = self.param_ty(ast_generics, space, index); + assert_eq!(space, subst::TypeSpace); + + let param_ty = self.param_ty(ast_generics, index); if constrained_parameters.contains(&Parameter::Type(param_ty)) { continue; } - let span = self.ty_param_span(ast_generics, item, space, index); + let span = ast_generics.ty_params[index].span; self.report_bivariance(span, param_ty.name); } for (space, index, &variance) in variances.regions.iter_enumerated() { + assert_eq!(space, subst::TypeSpace); + if variance != ty::Bivariant { continue; } - assert_eq!(space, TypeSpace); let span = ast_generics.lifetimes[index].lifetime.span; let name = ast_generics.lifetimes[index].lifetime.name; self.report_bivariance(span, name); } } - fn param_ty(&self, - ast_generics: &hir::Generics, - space: ParamSpace, - index: usize) - -> ty::ParamTy - { - let name = match space { - TypeSpace => ast_generics.ty_params[index].name, - SelfSpace => keywords::SelfType.name(), - FnSpace => bug!("Fn space occupied?"), - }; - - ty::ParamTy { space: space, idx: index as u32, name: name } - } - - fn ty_param_span(&self, - ast_generics: &hir::Generics, - item: &hir::Item, - space: ParamSpace, - index: usize) - -> Span - { - match space { - TypeSpace => ast_generics.ty_params[index].span, - SelfSpace => item.span, - FnSpace => span_bug!(item.span, "Fn space occupied?"), + fn param_ty(&self, ast_generics: &hir::Generics, index: usize) -> ty::ParamTy { + ty::ParamTy { + space: subst::TypeSpace, + idx: index as u32, + name: ast_generics.ty_params[index].name } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 485e744bf91..17a84e98e61 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -386,7 +386,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { let source = tcx.lookup_item_type(impl_did).ty; let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap(); - let target = *trait_ref.substs.types.get(subst::TypeSpace, 0); + let target = *trait_ref.substs.types.get(subst::TypeSpace, 1); debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)", source, target); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 77723ea9733..8eef384f2cf 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem; use middle::const_val::ConstVal; use rustc_const_eval::EvalHint::UncheckedExprHint; use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err}; -use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace}; +use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace, VecPerParamSpace}; use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer}; use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme}; use rustc::ty::{VariantKind}; @@ -85,7 +85,6 @@ use std::rc::Rc; use syntax::{abi, ast, attr}; use syntax::parse::token::keywords; -use syntax::ptr::P; use syntax_pos::Span; use rustc::hir::{self, intravisit, map as hir_map, print as pprust}; @@ -546,7 +545,7 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let path_res = tcx.expect_resolution(ast_ty.id); match path_res.base_def { Def::SelfTy(Some(def_id), None) | - Def::TyParam(_, _, def_id, _) if path_res.depth == 0 => { + Def::TyParam(def_id) if path_res.depth == 0 => { def_id == tcx.map.local_def_id(param_id) } _ => false @@ -1333,7 +1332,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) // add in the explicit where-clauses let mut trait_predicates = - ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates); + ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates, true); let assoc_predicates = predicates_for_associated_types(ccx, generics, @@ -1430,7 +1429,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let parent = ccx.tcx.map.get_parent(param_id); let def = ty::TypeParameterDef { - space: SelfSpace, + space: TypeSpace, index: 0, name: keywords::SelfType.name(), def_id: tcx.map.local_def_id(param_id), @@ -1477,27 +1476,25 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }).collect(); // Now create the real type parameters. - let types = ast_generics.ty_params.iter().enumerate().map(|(i, _)| { - get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32, allow_defaults) + let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| { + let i = opt_self.is_some() as u32 + i as u32; + get_or_create_type_parameter_def(ccx, ast_generics, space, i, p, allow_defaults) }).collect(); let has_self = base_generics.has_self || opt_self.is_some(); let (regions, types) = match space { - SelfSpace => bug!(), TypeSpace => { assert_eq!(base_generics.regions.as_full_slice().len(), 0); assert_eq!(base_generics.types.as_full_slice().len(), 0); - (VecPerParamSpace::new(vec![], regions, vec![]), - VecPerParamSpace::new(opt_self.into_iter().collect(), types, vec![])) + (VecPerParamSpace::new(regions, vec![]), + VecPerParamSpace::new(opt_self.into_iter().chain(types).collect(), vec![])) } FnSpace => { assert_eq!(base_generics.regions.len(FnSpace), 0); assert_eq!(base_generics.types.len(FnSpace), 0); - (VecPerParamSpace::new(base_generics.regions.get_slice(SelfSpace).to_vec(), - base_generics.regions.get_slice(TypeSpace).to_vec(), + (VecPerParamSpace::new(base_generics.regions.get_slice(TypeSpace).to_vec(), regions), - VecPerParamSpace::new(base_generics.types.get_slice(SelfSpace).to_vec(), - base_generics.types.get_slice(TypeSpace).to_vec(), + VecPerParamSpace::new(base_generics.types.get_slice(TypeSpace).to_vec(), types)) } }; @@ -1674,7 +1671,7 @@ fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, generics: &hir::Generics) -> ty::GenericPredicates<'tcx> { - ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty()) + ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty(), false) } fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, @@ -1682,7 +1679,7 @@ fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, base_predicates: &ty::GenericPredicates<'tcx>) -> ty::GenericPredicates<'tcx> { - ty_generic_predicates(ccx, FnSpace, generics, base_predicates) + ty_generic_predicates(ccx, FnSpace, generics, base_predicates, false) } // Add the Sized bound, unless the type parameter is marked as `?Sized`. @@ -1752,7 +1749,8 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx, 'hir>( fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, space: ParamSpace, ast_generics: &hir::Generics, - base_predicates: &ty::GenericPredicates<'tcx>) + base_predicates: &ty::GenericPredicates<'tcx>, + has_self: bool) -> ty::GenericPredicates<'tcx> { let tcx = ccx.tcx; @@ -1761,7 +1759,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, // Collect the predicates that were written inline by the user on each // type parameter (e.g., ``). for (index, param) in ast_generics.ty_params.iter().enumerate() { - let index = index as u32; + let index = has_self as u32 + index as u32; let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx); let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)), param_ty, @@ -1850,50 +1848,22 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, result } -fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - path: &P, - space: ParamSpace, - index: u32) - -> Ty<'tcx> -{ - let ty = AstConv::ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path); - - for leaf_ty in ty.walk() { - if let ty::TyParam(p) = leaf_ty.sty { - if p.space == space && p.idx >= index { - struct_span_err!(ccx.tcx.sess, path.span, E0128, - "type parameters with a default cannot use \ - forward declared identifiers") - .span_label(path.span, &format!("defaulted type parameters \ - cannot be forward declared")) - .emit(); - - return ccx.tcx.types.err - } - } - } - - ty -} - fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ast_generics: &hir::Generics, space: ParamSpace, index: u32, + param: &hir::TyParam, allow_defaults: bool) -> ty::TypeParameterDef<'tcx> { - let param = &ast_generics.ty_params[index as usize]; - 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| convert_default_type_parameter(ccx, def, space, index) - ); + let default = + param.default.as_ref().map(|def| ccx.icx(&()).to_ty(&ExplicitRscope, def)); let object_lifetime_default = compute_object_lifetime_default(ccx, param.id, @@ -1922,6 +1892,10 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, object_lifetime_default: object_lifetime_default, }; + 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: {:?}, {:?}", @@ -2153,7 +2127,7 @@ pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, /// Checks that all the type parameters on an impl fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - ast_generics: &hir::Generics, + generics: &hir::Generics, impl_predicates: &mut ty::GenericPredicates<'tcx>, impl_def_id: DefId) { @@ -2173,12 +2147,11 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, impl_trait_ref, &mut input_parameters); - for (index, ty_param) in ast_generics.ty_params.iter().enumerate() { - let param_ty = ty::ParamTy { space: TypeSpace, - idx: index as u32, - name: ty_param.name }; + let ty_generics = generics_of_def_id(ccx, impl_def_id); + for (ty_param, param) in ty_generics.types.as_full_slice().iter().zip(&generics.ty_params) { + let param_ty = ty::ParamTy::for_def(ty_param); if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) { - report_unused_parameter(ccx, ty_param.span, "type", ¶m_ty.to_string()); + report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string()); } } } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 8c9b4beb79d..2b88689ff12 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -361,9 +361,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // All type parameters on enums and structs should be // in the TypeSpace. - assert!(item_type.generics.types.is_empty_in(subst::SelfSpace)); assert!(item_type.generics.types.is_empty_in(subst::FnSpace)); - assert!(item_type.generics.regions.is_empty_in(subst::SelfSpace)); assert!(item_type.generics.regions.is_empty_in(subst::FnSpace)); self.add_constraints_from_substs( @@ -394,14 +392,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::TyTrait(ref data) => { - let poly_trait_ref = - data.principal.with_self_ty(self.tcx(), self.tcx().types.err); - // The type `Foo` is contravariant w/r/t `'a`: let contra = self.contravariant(variance); self.add_constraints_from_region(generics, data.region_bound, contra); - // Ignore the SelfSpace, it is erased. + let poly_trait_ref = + data.principal.with_self_ty(self.tcx(), self.tcx().types.err); self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance); for projection in &data.projection_bounds { diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs index 22edf219dff..9048d892b09 100644 --- a/src/librustc_typeck/variance/solve.rs +++ b/src/librustc_typeck/variance/solve.rs @@ -110,8 +110,8 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { while index < num_inferred { let item_id = inferred_infos[index].item_id; - let (mut rs, mut rt, mut rf) = (vec![], vec![], vec![]); - let (mut ts, mut tt, mut tf) = (vec![], vec![], vec![]); + let (mut rt, mut rf) = (vec![], vec![]); + let (mut tt, mut tf) = (vec![], vec![]); while index < num_inferred && inferred_infos[index].item_id == item_id { let info = &inferred_infos[index]; @@ -121,7 +121,6 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { match info.kind { TypeParam => { let types = match info.space { - subst::SelfSpace => &mut ts, subst::TypeSpace => &mut tt, subst::FnSpace => &mut tf }; @@ -130,7 +129,6 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { } RegionParam => { let regions = match info.space { - subst::SelfSpace => &mut rs, subst::TypeSpace => &mut rt, subst::FnSpace => &mut rf }; @@ -143,8 +141,8 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { } let item_variances = ty::ItemVariances { - regions: subst::VecPerParamSpace::new(rs, rt, rf), - types: subst::VecPerParamSpace::new(ts, tt, tf) + regions: subst::VecPerParamSpace::new(rt, rf), + types: subst::VecPerParamSpace::new(tt, tf) }; debug!("item_id={} item_variances={:?}", diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index 72f8d9cb23b..9dc38bb195c 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -21,7 +21,7 @@ use arena::TypedArena; use dep_graph::DepTrackingMapConfig; -use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace}; +use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace}; use rustc::ty::{self, TyCtxt}; use rustc::ty::maps::ItemVariances; use std::fmt; @@ -164,16 +164,16 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { let inferreds_on_entry = self.num_inferred(); - if has_self { - self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id); - } - for (i, p) in generics.lifetimes.iter().enumerate() { let id = p.lifetime.id; self.add_inferred(item_id, RegionParam, TypeSpace, i, id); } + if has_self { + self.add_inferred(item_id, TypeParam, TypeSpace, 0, item_id); + } for (i, p) in generics.ty_params.iter().enumerate() { + let i = has_self as usize + i; self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id); } @@ -233,7 +233,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { -> ty::Variance { match space { - SelfSpace | FnSpace => { + FnSpace => { ty::Bivariant } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f8a3a0af697..6fae7ddc24a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -41,7 +41,7 @@ use rustc::hir::def::Def; use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::hir::fold::Folder; use rustc::hir::print as pprust; -use rustc::ty::subst::{self, ParamSpace, Substs, VecPerParamSpace}; +use rustc::ty::subst::{self, Substs, VecPerParamSpace}; use rustc::ty; use rustc::middle::stability; @@ -630,13 +630,14 @@ impl Clean for hir::TyParamBound { } } -fn external_path_params(cx: &DocContext, trait_did: Option, +fn external_path_params(cx: &DocContext, trait_did: Option, has_self: bool, bindings: Vec, substs: &Substs) -> PathParameters { let lifetimes = substs.regions.get_slice(subst::TypeSpace) .iter() .filter_map(|v| v.clean(cx)) .collect(); - let types = substs.types.get_slice(subst::TypeSpace).to_vec(); + let types = substs.types.get_slice(subst::TypeSpace); + let types = types[has_self as usize..].to_vec(); match (trait_did, cx.tcx_opt()) { // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C @@ -675,13 +676,13 @@ fn external_path_params(cx: &DocContext, trait_did: Option, // trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar // from Fn<(A, B,), C> to Fn(A, B) -> C -fn external_path(cx: &DocContext, name: &str, trait_did: Option, +fn external_path(cx: &DocContext, name: &str, trait_did: Option, has_self: bool, bindings: Vec, substs: &Substs) -> Path { Path { global: false, segments: vec![PathSegment { name: name.to_string(), - params: external_path_params(cx, trait_did, bindings, substs) + params: external_path_params(cx, trait_did, has_self, bindings, substs) }], } } @@ -696,16 +697,16 @@ impl Clean for ty::BuiltinBound { let (did, path) = match *self { ty::BoundSend => (tcx.lang_items.send_trait().unwrap(), - external_path(cx, "Send", None, vec![], empty)), + external_path(cx, "Send", None, false, vec![], empty)), ty::BoundSized => (tcx.lang_items.sized_trait().unwrap(), - external_path(cx, "Sized", None, vec![], empty)), + external_path(cx, "Sized", None, false, vec![], empty)), ty::BoundCopy => (tcx.lang_items.copy_trait().unwrap(), - external_path(cx, "Copy", None, vec![], empty)), + external_path(cx, "Copy", None, false, vec![], empty)), ty::BoundSync => (tcx.lang_items.sync_trait().unwrap(), - external_path(cx, "Sync", None, vec![], empty)), + external_path(cx, "Sync", None, false, vec![], empty)), }; inline::record_extern_fqn(cx, did, TypeTrait); TraitBound(PolyTrait { @@ -728,14 +729,14 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { }; inline::record_extern_fqn(cx, self.def_id, TypeTrait); let path = external_path(cx, &tcx.item_name(self.def_id).as_str(), - Some(self.def_id), vec![], self.substs); + Some(self.def_id), true, vec![], self.substs); debug!("ty::TraitRef\n substs.types(TypeSpace): {:?}\n", - self.substs.types.get_slice(ParamSpace::TypeSpace)); + &self.input_types()[1..]); // collect any late bound regions let mut late_bounds = vec![]; - for &ty_s in self.substs.types.get_slice(ParamSpace::TypeSpace) { + for &ty_s in &self.input_types()[1..] { if let ty::TyTuple(ts) = ty_s.sty { for &ty_s in ts { if let ty::TyRef(ref reg, _) = ty_s.sty { @@ -982,8 +983,13 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, // Bounds in the type_params and lifetimes fields are repeated in the // predicates field (see rustc_typeck::collect::ty_generics), so remove // them. - let stripped_typarams = gens.types.get_slice(space).iter().map(|tp| { - tp.clean(cx) + let stripped_typarams = gens.types.get_slice(space).iter().filter_map(|tp| { + if tp.name == keywords::SelfType.name() { + assert_eq!(tp.index, 0); + None + } else { + Some(tp.clean(cx)) + } }).collect::>(); let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| { let mut srp = rp.clone(); @@ -1820,7 +1826,7 @@ impl<'tcx> Clean for ty::Ty<'tcx> { }; inline::record_extern_fqn(cx, did, kind); let path = external_path(cx, &cx.tcx().item_name(did).as_str(), - None, vec![], substs); + None, false, vec![], substs); ResolvedPath { path: path, typarams: None, @@ -1847,7 +1853,7 @@ impl<'tcx> Clean for ty::Ty<'tcx> { } let path = external_path(cx, &cx.tcx().item_name(did).as_str(), - Some(did), bindings, obj.principal.0.substs); + Some(did), false, bindings, obj.principal.0.substs); ResolvedPath { path: path, typarams: Some(typarams), diff --git a/src/test/compile-fail/issue-26548.rs b/src/test/compile-fail/issue-26548.rs index b6d5e5458ff..2591d7bcbae 100644 --- a/src/test/compile-fail/issue-26548.rs +++ b/src/test/compile-fail/issue-26548.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: overflow representing the type `S` +// error-pattern: overflow representing the type -#![feature(rustc_attrs)] trait Mirror { type It: ?Sized; } impl Mirror for T { type It = Self; } struct S(Option<::It>); -#[rustc_no_mir] // FIXME #27840 MIR tries to represent `std::option::Option` first. fn main() { let _s = S(None); } diff --git a/src/test/compile-fail/issue-26812.rs b/src/test/compile-fail/issue-26812.rs index 060a66846d3..1dd00881078 100644 --- a/src/test/compile-fail/issue-26812.rs +++ b/src/test/compile-fail/issue-26812.rs @@ -10,5 +10,7 @@ #![feature(default_type_parameter_fallback)] -fn avg(_: T) {} //~ ERROR associated type `Item` not found for `T` +fn avg(_: T) {} +//~^ ERROR type parameters with a default cannot use forward declared identifiers + fn main() {} diff --git a/src/test/compile-fail/variance-associated-types.rs b/src/test/compile-fail/variance-associated-types.rs index a3456b0628b..9aa4d29c4ec 100644 --- a/src/test/compile-fail/variance-associated-types.rs +++ b/src/test/compile-fail/variance-associated-types.rs @@ -20,12 +20,12 @@ trait Trait<'a> { } #[rustc_variance] -struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[];[+];[]], regions=[[];[-];[]]) +struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[+];[]], regions=[[-];[]]) field: (T, &'a ()) } #[rustc_variance] -struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[];[o];[]], regions=[[];[o];[]]) +struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[o];[]], regions=[[o];[]]) field: >::Type } diff --git a/src/test/compile-fail/variance-object-types.rs b/src/test/compile-fail/variance-object-types.rs index ffd829c38d3..3c8b27f965a 100644 --- a/src/test/compile-fail/variance-object-types.rs +++ b/src/test/compile-fail/variance-object-types.rs @@ -18,7 +18,7 @@ use std::cell::Cell; // For better or worse, associated types are invariant, and hence we // get an invariant result for `'a`. #[rustc_variance] -struct Foo<'a> { //~ ERROR regions=[[];[o];[]] +struct Foo<'a> { //~ ERROR regions=[[o];[]] x: Box &'a i32 + 'static> } diff --git a/src/test/compile-fail/variance-region-bounds.rs b/src/test/compile-fail/variance-region-bounds.rs index 6dd791f2558..ae5a8674f44 100644 --- a/src/test/compile-fail/variance-region-bounds.rs +++ b/src/test/compile-fail/variance-region-bounds.rs @@ -13,11 +13,11 @@ #![feature(rustc_attrs)] #[rustc_variance] -trait Foo: 'static { //~ ERROR types=[[o];[];[]] +trait Foo: 'static { //~ ERROR types=[[o];[]] } #[rustc_variance] -trait Bar { //~ ERROR types=[[o];[o];[]] +trait Bar { //~ ERROR types=[[o, o];[]] fn do_it(&self) where T: 'static; } diff --git a/src/test/compile-fail/variance-regions-direct.rs b/src/test/compile-fail/variance-regions-direct.rs index 0c712d3fa03..93d3d277314 100644 --- a/src/test/compile-fail/variance-regions-direct.rs +++ b/src/test/compile-fail/variance-regions-direct.rs @@ -16,7 +16,7 @@ // Regions that just appear in normal spots are contravariant: #[rustc_variance] -struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[];[-, -, -];[]] +struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[]] x: &'a isize, y: &'b [isize], c: &'c str @@ -25,7 +25,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[];[-, -, -];[]] // Those same annotations in function arguments become covariant: #[rustc_variance] -struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[];[+, +, +];[]] +struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[]] x: extern "Rust" fn(&'a isize), y: extern "Rust" fn(&'b [isize]), c: extern "Rust" fn(&'c str), @@ -34,7 +34,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[];[+, +, +];[]] // Mutability induces invariance: #[rustc_variance] -struct Test4<'a, 'b:'a> { //~ ERROR regions=[[];[-, o];[]] +struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[]] x: &'a mut &'b isize, } @@ -42,7 +42,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR regions=[[];[-, o];[]] // contravariant context: #[rustc_variance] -struct Test5<'a, 'b:'a> { //~ ERROR regions=[[];[+, o];[]] +struct Test5<'a, 'b:'a> { //~ ERROR regions=[[+, o];[]] x: extern "Rust" fn(&'a mut &'b isize), } @@ -52,14 +52,14 @@ struct Test5<'a, 'b:'a> { //~ ERROR regions=[[];[+, o];[]] // argument list occurs in an invariant context. #[rustc_variance] -struct Test6<'a, 'b:'a> { //~ ERROR regions=[[];[-, o];[]] +struct Test6<'a, 'b:'a> { //~ ERROR regions=[[-, o];[]] x: &'a mut extern "Rust" fn(&'b isize), } // No uses at all is bivariant: #[rustc_variance] -struct Test7<'a> { //~ ERROR regions=[[];[*];[]] +struct Test7<'a> { //~ ERROR regions=[[*];[]] //~^ ERROR parameter `'a` is never used x: isize } @@ -67,7 +67,7 @@ struct Test7<'a> { //~ ERROR regions=[[];[*];[]] // Try enums too. #[rustc_variance] -enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[[];[+, -, o];[]] +enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[]] Test8A(extern "Rust" fn(&'a isize)), Test8B(&'b [isize]), Test8C(&'b mut &'c str), diff --git a/src/test/compile-fail/variance-regions-indirect.rs b/src/test/compile-fail/variance-regions-indirect.rs index 9bdb05e188d..eeb981b707e 100644 --- a/src/test/compile-fail/variance-regions-indirect.rs +++ b/src/test/compile-fail/variance-regions-indirect.rs @@ -15,7 +15,7 @@ #![feature(rustc_attrs)] #[rustc_variance] -enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[];[+, -, o, *];[]] +enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[]] //~^ ERROR parameter `'d` is never used Test8A(extern "Rust" fn(&'a isize)), Test8B(&'b [isize]), @@ -23,25 +23,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[];[+, -, o, *];[]] } #[rustc_variance] -struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[];[*, o, -, +];[]] +struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[]] //~^ ERROR parameter `'w` is never used f: Base<'z, 'y, 'x, 'w> } #[rustc_variance] // Combine - and + to yield o -struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[];[o, o, *];[]] +struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[]] //~^ ERROR parameter `'c` is never used f: Base<'a, 'a, 'b, 'c> } #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) -struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[];[o, -, *];[]] +struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[]] //~^ ERROR parameter `'c` is never used f: Base<'a, 'b, 'a, 'c> } #[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here) -struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[[];[+, -, o];[]] +struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[]] f: Base<'a, 'b, 'c, 'a> } diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs index 528be50c0b8..860dd6deefd 100644 --- a/src/test/compile-fail/variance-trait-bounds.rs +++ b/src/test/compile-fail/variance-trait-bounds.rs @@ -15,48 +15,48 @@ // influence variance. #[rustc_variance] -trait Getter { //~ ERROR types=[[o];[o];[]] +trait Getter { //~ ERROR types=[[o, o];[]] fn get(&self) -> T; } #[rustc_variance] -trait Setter { //~ ERROR types=[[o];[o];[]] +trait Setter { //~ ERROR types=[[o, o];[]] fn get(&self, T); } #[rustc_variance] -struct TestStruct> { //~ ERROR types=[[];[+, +];[]] +struct TestStruct> { //~ ERROR types=[[+, +];[]] t: T, u: U } #[rustc_variance] -enum TestEnum> {//~ ERROR types=[[];[*, +];[]] +enum TestEnum> {//~ ERROR types=[[*, +];[]] //~^ ERROR parameter `U` is never used Foo(T) } #[rustc_variance] -trait TestTrait> { //~ ERROR types=[[o];[o, o];[]] +trait TestTrait> { //~ ERROR types=[[o, o, o];[]] fn getter(&self, u: U) -> T; } #[rustc_variance] -trait TestTrait2 : Getter { //~ ERROR types=[[o];[o];[]] +trait TestTrait2 : Getter { //~ ERROR types=[[o, o];[]] } #[rustc_variance] -trait TestTrait3 { //~ ERROR types=[[o];[o];[]] +trait TestTrait3 { //~ ERROR types=[[o, o];[]] fn getter>(&self); } #[rustc_variance] -struct TestContraStruct> { //~ ERROR types=[[];[*, +];[]] +struct TestContraStruct> { //~ ERROR types=[[*, +];[]] //~^ ERROR parameter `U` is never used t: T } #[rustc_variance] -struct TestBox+Setter> { //~ ERROR types=[[];[*, +];[]] +struct TestBox+Setter> { //~ ERROR types=[[*, +];[]] //~^ ERROR parameter `U` is never used t: T } diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs index b5854020498..b37007a6d34 100644 --- a/src/test/compile-fail/variance-trait-object-bound.rs +++ b/src/test/compile-fail/variance-trait-object-bound.rs @@ -21,7 +21,7 @@ use std::mem; trait T { fn foo(&self); } #[rustc_variance] -struct TOption<'a> { //~ ERROR regions=[[];[-];[]] +struct TOption<'a> { //~ ERROR regions=[[-];[]] v: Option>, } diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs index d110c402d3b..8eb96814fa8 100644 --- a/src/test/compile-fail/variance-types-bounds.rs +++ b/src/test/compile-fail/variance-types-bounds.rs @@ -14,46 +14,46 @@ #![feature(rustc_attrs)] #[rustc_variance] -struct TestImm { //~ ERROR types=[[];[+, +];[]] +struct TestImm { //~ ERROR types=[[+, +];[]] x: A, y: B, } #[rustc_variance] -struct TestMut { //~ ERROR types=[[];[+, o];[]] +struct TestMut { //~ ERROR types=[[+, o];[]] x: A, y: &'static mut B, } #[rustc_variance] -struct TestIndirect { //~ ERROR types=[[];[+, o];[]] +struct TestIndirect { //~ ERROR types=[[+, o];[]] m: TestMut } #[rustc_variance] -struct TestIndirect2 { //~ ERROR types=[[];[o, o];[]] +struct TestIndirect2 { //~ ERROR types=[[o, o];[]] n: TestMut, m: TestMut } #[rustc_variance] -trait Getter { //~ ERROR types=[[o];[o];[]] +trait Getter { //~ ERROR types=[[o, o];[]] fn get(&self) -> A; } #[rustc_variance] -trait Setter { //~ ERROR types=[[o];[o];[]] +trait Setter { //~ ERROR types=[[o, o];[]] fn set(&mut self, a: A); } #[rustc_variance] -trait GetterSetter { //~ ERROR types=[[o];[o];[]] +trait GetterSetter { //~ ERROR types=[[o, o];[]] fn get(&self) -> A; fn set(&mut self, a: A); } #[rustc_variance] -trait GetterInTypeBound { //~ ERROR types=[[o];[o];[]] +trait GetterInTypeBound { //~ ERROR types=[[o, o];[]] // Here, the use of `A` in the method bound *does* affect // variance. Think of it as if the method requested a dictionary // for `T:Getter`. Since this dictionary is an input, it is @@ -63,12 +63,12 @@ trait GetterInTypeBound { //~ ERROR types=[[o];[o];[]] } #[rustc_variance] -trait SetterInTypeBound { //~ ERROR types=[[o];[o];[]] +trait SetterInTypeBound { //~ ERROR types=[[o, o];[]] fn do_it>(&self); } #[rustc_variance] -struct TestObject { //~ ERROR types=[[];[o, o];[]] +struct TestObject { //~ ERROR types=[[o, o];[]] n: Box+Send>, m: Box+Send>, } diff --git a/src/test/compile-fail/variance-types.rs b/src/test/compile-fail/variance-types.rs index 8c1a544334c..791b56caea0 100644 --- a/src/test/compile-fail/variance-types.rs +++ b/src/test/compile-fail/variance-types.rs @@ -17,32 +17,32 @@ use std::cell::Cell; // not considered bivariant. #[rustc_variance] -struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[];[o, o];[]], regions=[[];[-];[]] +struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[]], regions=[[-];[]] t: &'a mut (A,B) } #[rustc_variance] -struct InvariantCell { //~ ERROR types=[[];[o];[]] +struct InvariantCell { //~ ERROR types=[[o];[]] t: Cell } #[rustc_variance] -struct InvariantIndirect { //~ ERROR types=[[];[o];[]] +struct InvariantIndirect { //~ ERROR types=[[o];[]] t: InvariantCell } #[rustc_variance] -struct Covariant { //~ ERROR types=[[];[+];[]] +struct Covariant { //~ ERROR types=[[+];[]] t: A, u: fn() -> A } #[rustc_variance] -struct Contravariant { //~ ERROR types=[[];[-];[]] +struct Contravariant { //~ ERROR types=[[-];[]] t: fn(A) } #[rustc_variance] -enum Enum { //~ ERROR types=[[];[+, -, o];[]] +enum Enum { //~ ERROR types=[[+, -, o];[]] Foo(Covariant), Bar(Contravariant), Zed(Covariant,Contravariant)