diff --git a/src/librustc/infer/bivariate.rs b/src/librustc/infer/bivariate.rs index 125f815feda6f..4acb8b807d594 100644 --- a/src/librustc/infer/bivariate.rs +++ b/src/librustc/infer/bivariate.rs @@ -106,7 +106,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> } } - fn regions(&mut self, a: ty::Region, _: ty::Region) -> RelateResult<'tcx, ty::Region> { + fn regions(&mut self, a: &'tcx ty::Region, _: &'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region> { Ok(a) } diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index b4818f963b3ba..5ce30484ede00 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -329,8 +329,8 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx } } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - match r { + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + match *r { // Never make variables for regions bound within the type itself, // nor for erased regions. ty::ReLateBound(..) | diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index e06f7303acb29..bf247acec5a2d 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -79,7 +79,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> } } - fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> { + fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 1e053d6bfdab2..9169d299e040b 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -99,7 +99,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn note_and_explain_region(self, err: &mut DiagnosticBuilder, prefix: &str, - region: ty::Region, + region: &'tcx ty::Region, suffix: &str) { fn item_scope_tag(item: &hir::Item) -> &'static str { match item.node { @@ -120,7 +120,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { Some(span)) } - let (description, span) = match region { + let (description, span) = match *region { ty::ReScope(scope) => { let new_string; let unknown_scope = || { @@ -405,12 +405,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } fn free_regions_from_same_fn<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - sub: Region, - sup: Region) + sub: &'tcx Region, + sup: &'tcx Region) -> Option { debug!("free_regions_from_same_fn(sub={:?}, sup={:?})", sub, sup); let (scope_id, fr1, fr2) = match (sub, sup) { - (ReFree(fr1), ReFree(fr2)) => { + (&ReFree(fr1), &ReFree(fr2)) => { if fr1.scope != fr2.scope { return None } @@ -602,7 +602,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn report_generic_bound_failure(&self, origin: SubregionOrigin<'tcx>, bound_kind: GenericKind<'tcx>, - sub: Region) + sub: &'tcx Region) { // FIXME: it would be better to report the first error message // with the span of the parameter itself, rather than the span @@ -616,7 +616,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { format!("the associated type `{}`", p), }; - let mut err = match sub { + let mut err = match *sub { ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => { // Does the required lifetime have a nice name we can print? let mut err = struct_span_err!(self.tcx.sess, @@ -667,8 +667,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn report_concrete_failure(&self, origin: SubregionOrigin<'tcx>, - sub: Region, - sup: Region) + sub: &'tcx Region, + sup: &'tcx Region) -> DiagnosticBuilder<'tcx> { match origin { infer::Subtype(trace) => { @@ -939,9 +939,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn report_sub_sup_conflict(&self, var_origin: RegionVariableOrigin, sub_origin: SubregionOrigin<'tcx>, - sub_region: Region, + sub_region: &'tcx Region, sup_origin: SubregionOrigin<'tcx>, - sup_region: Region) { + sup_region: &'tcx Region) { let mut err = self.report_inference_failure(var_origin); self.tcx.note_and_explain_region(&mut err, diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index ecd9759c721b2..beda734ee0d56 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -83,8 +83,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { self.infcx.tcx } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - match r { + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + match *r { ty::ReEarlyBound(..) | ty::ReLateBound(..) => { // leave bound regions alone @@ -99,7 +99,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::ReEmpty | ty::ReErased => { // replace all free regions with 'erased - ty::ReErased + self.tcx().mk_region(ty::ReErased) } } } diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index 5dd85a31a9a20..a5709e1880801 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -57,7 +57,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> lattice::super_lattice_tys(self, a, b) } - fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> { + fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 743d6135fbb5b..90be5e935baf1 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -164,7 +164,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { .map(|(&skol, &(br, ref regions))| { let representative = regions.iter() - .filter(|r| !skol_resolution_map.contains_key(r)) + .filter(|&&r| !skol_resolution_map.contains_key(r)) .cloned() .next() .unwrap_or_else(|| { // [1] @@ -268,9 +268,9 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot, debruijn: ty::DebruijnIndex, new_vars: &[ty::RegionVid], - a_map: &FnvHashMap, - r0: ty::Region) - -> ty::Region { + a_map: &FnvHashMap, + r0: &'tcx ty::Region) + -> &'tcx ty::Region { // Regions that pre-dated the LUB computation stay as they are. if !is_var_in_set(new_vars, r0) { assert!(!r0.is_bound()); @@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { debug!("generalize_region(r0={:?}): \ replacing with {:?}, tainted={:?}", r0, *a_br, tainted); - return ty::ReLateBound(debruijn, *a_br); + return infcx.tcx.mk_region(ty::ReLateBound(debruijn, *a_br)); } } @@ -364,10 +364,12 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot, debruijn: ty::DebruijnIndex, new_vars: &[ty::RegionVid], - a_map: &FnvHashMap, + a_map: &FnvHashMap, a_vars: &[ty::RegionVid], b_vars: &[ty::RegionVid], - r0: ty::Region) -> ty::Region { + r0: &'tcx ty::Region) + -> &'tcx ty::Region { if !is_var_in_set(new_vars, r0) { assert!(!r0.is_bound()); return r0; @@ -419,7 +421,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { if a_r.is_some() && b_r.is_some() && only_new_vars { // Related to exactly one bound variable from each fn: - return rev_lookup(span, a_map, a_r.unwrap()); + return rev_lookup(infcx, span, a_map, a_r.unwrap()); } else if a_r.is_none() && b_r.is_none() { // Not related to bound variables from either fn: assert!(!r0.is_bound()); @@ -430,13 +432,14 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { } } - fn rev_lookup(span: Span, - a_map: &FnvHashMap, - r: ty::Region) -> ty::Region + fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, + span: Span, + a_map: &FnvHashMap, + r: &'tcx ty::Region) -> &'tcx ty::Region { for (a_br, a_r) in a_map { if *a_r == r { - return ty::ReLateBound(ty::DebruijnIndex::new(1), *a_br); + return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), *a_br)); } } span_bug!( @@ -445,19 +448,21 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { r); } - fn fresh_bound_variable(infcx: &InferCtxt, debruijn: ty::DebruijnIndex) -> ty::Region { + fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, + debruijn: ty::DebruijnIndex) + -> &'tcx ty::Region { infcx.region_vars.new_bound(debruijn) } } } fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>, - map: &FnvHashMap) + map: &FnvHashMap) -> Vec { map.iter() - .map(|(_, r)| match *r { + .map(|(_, &r)| match *r { ty::ReVar(r) => { r } - r => { + _ => { span_bug!( fields.trace.origin.span(), "found non-region-vid: {:?}", @@ -467,8 +472,8 @@ fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>, .collect() } -fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool { - match r { +fn is_var_in_set(new_vars: &[ty::RegionVid], r: &ty::Region) -> bool { + match *r { ty::ReVar(ref v) => new_vars.iter().any(|x| x == v), _ => false } @@ -479,13 +484,13 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, mut fldr: F) -> T where T: TypeFoldable<'tcx>, - F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region, + F: FnMut(&'tcx ty::Region, ty::DebruijnIndex) -> &'tcx ty::Region, { tcx.fold_regions(unbound_value, &mut false, |region, current_depth| { // we should only be encountering "escaping" late-bound regions here, // because the ones at the current level should have been replaced // with fresh variables - assert!(match region { + assert!(match *region { ty::ReLateBound(..) => false, _ => true }); @@ -497,9 +502,9 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn tainted_regions(&self, snapshot: &CombinedSnapshot, - r: ty::Region, + r: &'tcx ty::Region, directions: TaintDirections) - -> FnvHashSet { + -> FnvHashSet<&'tcx ty::Region> { self.region_vars.tainted(&snapshot.region_vars_snapshot, r, directions) } @@ -596,7 +601,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn skolemize_late_bound_regions(&self, binder: &ty::Binder, snapshot: &CombinedSnapshot) - -> (T, SkolemizationMap) + -> (T, SkolemizationMap<'tcx>) where T : TypeFoldable<'tcx> { let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| { @@ -619,7 +624,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn leak_check(&self, overly_polymorphic: bool, span: Span, - skol_map: &SkolemizationMap, + skol_map: &SkolemizationMap<'tcx>, snapshot: &CombinedSnapshot) -> RelateResult<'tcx, ()> { @@ -673,7 +678,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { for &tainted_region in &incoming_taints { // Each skolemized should only be relatable to itself // or new variables: - match tainted_region { + match *tainted_region { ty::ReVar(vid) => { if new_vars.contains(&vid) { warnings.extend( @@ -742,7 +747,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// to the depth of the predicate, in this case 1, so that the final /// predicate is `for<'a> &'a int : Clone`. pub fn plug_leaks(&self, - skol_map: SkolemizationMap, + skol_map: SkolemizationMap<'tcx>, snapshot: &CombinedSnapshot, value: &T) -> T where T : TypeFoldable<'tcx> @@ -755,7 +760,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // region back to the `ty::BoundRegion` that it originally // represented. Because `leak_check` passed, we know that // these taint sets are mutually disjoint. - let inv_skol_map: FnvHashMap = + let inv_skol_map: FnvHashMap<&'tcx ty::Region, ty::BoundRegion> = skol_map .iter() .flat_map(|(&skol_br, &skol)| { @@ -794,7 +799,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // (which ought not to escape the snapshot, but we // don't check that) or itself assert!( - match r { + match *r { ty::ReVar(_) => true, ty::ReSkolemized(_, ref br1) => br == br1, _ => false, @@ -802,7 +807,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "leak-check would have us replace {:?} with {:?}", r, br); - ty::ReLateBound(ty::DebruijnIndex::new(current_depth - 1), br.clone()) + self.tcx.mk_region(ty::ReLateBound( + ty::DebruijnIndex::new(current_depth - 1), br.clone())) } } }); @@ -826,7 +832,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// /// Note: popping also occurs implicitly as part of `leak_check`. pub fn pop_skolemized(&self, - skol_map: SkolemizationMap, + skol_map: SkolemizationMap<'tcx>, snapshot: &CombinedSnapshot) { debug!("pop_skolemized({:?})", skol_map); diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index ad1b32ffaeb32..7d352be67d32b 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -57,7 +57,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> lattice::super_lattice_tys(self, a, b) } - fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> { + fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 1b65b5dae0748..9854cd95397b7 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -177,7 +177,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized /// region that each late-bound region was replaced with. -pub type SkolemizationMap = FnvHashMap; +pub type SkolemizationMap<'tcx> = FnvHashMap; /// Why did we require that the two types be related? /// @@ -1123,8 +1123,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn sub_regions(&self, origin: SubregionOrigin<'tcx>, - a: ty::Region, - b: ty::Region) { + a: &'tcx ty::Region, + b: &'tcx ty::Region) { debug!("sub_regions({:?} <: {:?})", a, b); self.region_vars.make_subregion(origin, a, b); } @@ -1147,7 +1147,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn region_outlives_predicate(&self, span: Span, - predicate: &ty::PolyRegionOutlivesPredicate) + predicate: &ty::PolyRegionOutlivesPredicate<'tcx>) -> UnitResult<'tcx> { self.commit_if_ok(|snapshot| { @@ -1190,8 +1190,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .new_key(None) } - pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region { - ty::ReVar(self.region_vars.new_region_var(origin)) + pub fn next_region_var(&self, origin: RegionVariableOrigin) + -> &'tcx ty::Region { + self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin))) } /// Create a region inference variable for the given @@ -1199,7 +1200,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn region_var_for_def(&self, span: Span, def: &ty::RegionParameterDef) - -> ty::Region { + -> &'tcx ty::Region { self.next_region_var(EarlyBoundRegion(span, def.name)) } @@ -1245,7 +1246,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }) } - pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region { + pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> &'tcx ty::Region { self.region_vars.new_bound(debruijn) } @@ -1530,7 +1531,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { span: Span, lbrct: LateBoundRegionConversionTime, value: &ty::Binder) - -> (T, FnvHashMap) + -> (T, FnvHashMap) where T : TypeFoldable<'tcx> { self.tcx.replace_late_bound_regions( @@ -1576,8 +1577,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn verify_generic_bound(&self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, - a: ty::Region, - bound: VerifyBound) { + a: &'tcx ty::Region, + bound: VerifyBound<'tcx>) { debug!("verify_generic_bound({:?}, {:?} <: {:?})", kind, a, @@ -1666,7 +1667,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.region_maps.temporary_scope(rvalue_id) } - pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { + pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option> { self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() } diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs index 905ad7c0faa23..1c64ebc0537ae 100644 --- a/src/librustc/infer/region_inference/graphviz.rs +++ b/src/librustc/infer/region_inference/graphviz.rs @@ -123,7 +123,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, graph_name: String, - map: &'a FnvHashMap>, + map: &'a FnvHashMap, SubregionOrigin<'tcx>>, node_ids: FnvHashMap, } @@ -135,8 +135,8 @@ enum Node { // type Edge = Constraint; #[derive(Clone, PartialEq, Eq, Debug, Copy)] -enum Edge { - Constraint(Constraint), +enum Edge<'tcx> { + Constraint(Constraint<'tcx>), EnclScope(CodeExtent, CodeExtent), } @@ -177,7 +177,7 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { type Node = Node; - type Edge = Edge; + type Edge = Edge<'tcx>; fn graph_id(&self) -> dot::Id { dot::Id::new(&*self.graph_name).unwrap() } @@ -214,11 +214,11 @@ fn constraint_to_nodes(c: &Constraint) -> (Node, Node) { Constraint::ConstrainVarSubVar(rv_1, rv_2) => (Node::RegionVid(rv_1), Node::RegionVid(rv_2)), Constraint::ConstrainRegSubVar(r_1, rv_2) => - (Node::Region(r_1), Node::RegionVid(rv_2)), + (Node::Region(*r_1), Node::RegionVid(rv_2)), Constraint::ConstrainVarSubReg(rv_1, r_2) => - (Node::RegionVid(rv_1), Node::Region(r_2)), + (Node::RegionVid(rv_1), Node::Region(*r_2)), Constraint::ConstrainRegSubReg(r_1, r_2) => - (Node::Region(r_1), Node::Region(r_2)), + (Node::Region(*r_1), Node::Region(*r_2)), } } @@ -234,7 +234,7 @@ fn edge_to_nodes(e: &Edge) -> (Node, Node) { impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { type Node = Node; - type Edge = Edge; + type Edge = Edge<'tcx>; fn nodes(&self) -> dot::Nodes { let mut set = FnvHashSet(); for node in self.node_ids.keys() { @@ -243,26 +243,26 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { debug!("constraint graph has {} nodes", set.len()); set.into_iter().collect() } - fn edges(&self) -> dot::Edges { + fn edges(&self) -> dot::Edges> { debug!("constraint graph has {} edges", self.map.len()); let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect(); self.tcx.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup))); debug!("region graph has {} edges", v.len()); Cow::Owned(v) } - fn source(&self, edge: &Edge) -> Node { + fn source(&self, edge: &Edge<'tcx>) -> Node { let (n1, _) = edge_to_nodes(edge); debug!("edge {:?} has source {:?}", edge, n1); n1 } - fn target(&self, edge: &Edge) -> Node { + fn target(&self, edge: &Edge<'tcx>) -> Node { let (_, n2) = edge_to_nodes(edge); debug!("edge {:?} has target {:?}", edge, n2); n2 } } -pub type ConstraintMap<'tcx> = FnvHashMap>; +pub type ConstraintMap<'tcx> = FnvHashMap, SubregionOrigin<'tcx>>; fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, map: &ConstraintMap<'tcx>, diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index d3b4afa2cee79..b3693ae1e21ad 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -39,22 +39,22 @@ mod graphviz; // A constraint that influences the inference process. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub enum Constraint { +pub enum Constraint<'tcx> { // One region variable is subregion of another ConstrainVarSubVar(RegionVid, RegionVid), // Concrete region is subregion of region variable - ConstrainRegSubVar(Region, RegionVid), + ConstrainRegSubVar(&'tcx Region, RegionVid), // Region variable is subregion of concrete region. This does not // directly affect inference, but instead is checked after // inference is complete. - ConstrainVarSubReg(RegionVid, Region), + ConstrainVarSubReg(RegionVid, &'tcx Region), // A constraint where neither side is a variable. This does not // directly affect inference, but instead is checked after // inference is complete. - ConstrainRegSubReg(Region, Region), + ConstrainRegSubReg(&'tcx Region, &'tcx Region), } // VerifyGenericBound(T, _, R, RS): The parameter type `T` (or @@ -66,8 +66,8 @@ pub enum Constraint { pub struct Verify<'tcx> { kind: GenericKind<'tcx>, origin: SubregionOrigin<'tcx>, - region: Region, - bound: VerifyBound, + region: &'tcx Region, + bound: VerifyBound<'tcx>, } #[derive(Copy, Clone, PartialEq, Eq)] @@ -80,36 +80,36 @@ pub enum GenericKind<'tcx> { // particular region (let's call it `'min`) meets some bound. // The bound is described the by the following grammar: #[derive(Debug)] -pub enum VerifyBound { +pub enum VerifyBound<'tcx> { // B = exists {R} --> some 'r in {R} must outlive 'min // // Put another way, the subject value is known to outlive all // regions in {R}, so if any of those outlives 'min, then the // bound is met. - AnyRegion(Vec), + AnyRegion(Vec<&'tcx Region>), // B = forall {R} --> all 'r in {R} must outlive 'min // // Put another way, the subject value is known to outlive some // region in {R}, so if all of those outlives 'min, then the bound // is met. - AllRegions(Vec), + AllRegions(Vec<&'tcx Region>), // B = exists {B} --> 'min must meet some bound b in {B} - AnyBound(Vec), + AnyBound(Vec>), // B = forall {B} --> 'min must meet all bounds b in {B} - AllBounds(Vec), + AllBounds(Vec>), } #[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub struct TwoRegions { - a: Region, - b: Region, +pub struct TwoRegions<'tcx> { + a: &'tcx Region, + b: &'tcx Region, } #[derive(Copy, Clone, PartialEq)] -pub enum UndoLogEntry { +pub enum UndoLogEntry<'tcx> { /// Pushed when we start a snapshot. OpenSnapshot, @@ -122,7 +122,7 @@ pub enum UndoLogEntry { AddVar(RegionVid), /// We added the given `constraint` - AddConstraint(Constraint), + AddConstraint(Constraint<'tcx>), /// We added the given `verify` AddVerify(usize), @@ -131,7 +131,7 @@ pub enum UndoLogEntry { AddGiven(ty::FreeRegion, ty::RegionVid), /// We added a GLB/LUB "combinaton variable" - AddCombination(CombineMapType, TwoRegions), + AddCombination(CombineMapType, TwoRegions<'tcx>), /// During skolemization, we sometimes purge entries from the undo /// log in a kind of minisnapshot (unlike other snapshots, this @@ -153,13 +153,13 @@ pub enum RegionResolutionError<'tcx> { /// `ConcreteFailure(o, a, b)`: /// /// `o` requires that `a <= b`, but this does not hold - ConcreteFailure(SubregionOrigin<'tcx>, Region, Region), + ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region), /// `GenericBoundFailure(p, s, a) /// /// The parameter/associated-type `p` must be known to outlive the lifetime /// `a` (but none of the known bounds are sufficient). - GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, Region), + GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, &'tcx Region), /// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`: /// @@ -168,9 +168,9 @@ pub enum RegionResolutionError<'tcx> { /// `sub_r <= sup_r` does not hold. SubSupConflict(RegionVariableOrigin, SubregionOrigin<'tcx>, - Region, + &'tcx Region, SubregionOrigin<'tcx>, - Region), + &'tcx Region), /// For subsets of `ConcreteFailure` and `SubSupConflict`, we can derive /// more specific errors message by suggesting to the user where they @@ -182,7 +182,7 @@ pub enum RegionResolutionError<'tcx> { #[derive(Clone, Debug)] pub enum ProcessedErrorOrigin<'tcx> { - ConcreteFailure(SubregionOrigin<'tcx>, Region, Region), + ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region), VariableFailure(RegionVariableOrigin), } @@ -213,7 +213,7 @@ impl SameRegions { } } -pub type CombineMap = FnvHashMap; +pub type CombineMap<'tcx> = FnvHashMap, RegionVid>; pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, @@ -222,7 +222,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // Constraints of the form `A <= B` introduced by the region // checker. Here at least one of `A` and `B` must be a region // variable. - constraints: RefCell>>, + constraints: RefCell, SubregionOrigin<'tcx>>>, // A "verify" is something that we need to verify after inference is // done, but which does not directly affect inference in any way. @@ -250,8 +250,8 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // a bit of a hack but seems to work. givens: RefCell>, - lubs: RefCell, - glbs: RefCell, + lubs: RefCell>, + glbs: RefCell>, skolemization_count: Cell, bound_count: Cell, @@ -264,12 +264,12 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // otherwise we end up adding entries for things like the lower // bound on a variable and so forth, which can never be rolled // back. - undo_log: RefCell>, + undo_log: RefCell>>, unification_table: RefCell>, // This contains the results of inference. It begins as an empty // option and only acquires a value after inference is complete. - values: RefCell>>, + values: RefCell>>>, } pub struct RegionSnapshot { @@ -303,14 +303,14 @@ impl TaintDirections { } } -struct TaintSet { +struct TaintSet<'tcx> { directions: TaintDirections, - regions: FnvHashSet + regions: FnvHashSet<&'tcx ty::Region> } -impl TaintSet { +impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { fn new(directions: TaintDirections, - initial_region: ty::Region) + initial_region: &'tcx ty::Region) -> Self { let mut regions = FnvHashSet(); regions.insert(initial_region); @@ -318,8 +318,9 @@ impl TaintSet { } fn fixed_point(&mut self, - undo_log: &[UndoLogEntry], - verifys: &[Verify]) { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + undo_log: &[UndoLogEntry<'tcx>], + verifys: &[Verify<'tcx>]) { let mut prev_len = 0; while prev_len < self.len() { debug!("tainted: prev_len = {:?} new_len = {:?}", @@ -330,19 +331,21 @@ impl TaintSet { for undo_entry in undo_log { match undo_entry { &AddConstraint(ConstrainVarSubVar(a, b)) => { - self.add_edge(ReVar(a), ReVar(b)); + self.add_edge(tcx.mk_region(ReVar(a)), + tcx.mk_region(ReVar(b))); } &AddConstraint(ConstrainRegSubVar(a, b)) => { - self.add_edge(a, ReVar(b)); + self.add_edge(a, tcx.mk_region(ReVar(b))); } &AddConstraint(ConstrainVarSubReg(a, b)) => { - self.add_edge(ReVar(a), b); + self.add_edge(tcx.mk_region(ReVar(a)), b); } &AddConstraint(ConstrainRegSubReg(a, b)) => { self.add_edge(a, b); } &AddGiven(a, b) => { - self.add_edge(ReFree(a), ReVar(b)); + self.add_edge(tcx.mk_region(ReFree(a)), + tcx.mk_region(ReVar(b))); } &AddVerify(i) => { verifys[i].bound.for_each_region(&mut |b| { @@ -359,7 +362,7 @@ impl TaintSet { } } - fn into_set(self) -> FnvHashSet { + fn into_set(self) -> FnvHashSet<&'tcx ty::Region> { self.regions } @@ -368,8 +371,8 @@ impl TaintSet { } fn add_edge(&mut self, - source: ty::Region, - target: ty::Region) { + source: &'tcx ty::Region, + target: &'tcx ty::Region) { if self.directions.incoming { if self.regions.contains(&target) { self.regions.insert(source); @@ -450,7 +453,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { .rollback_to(snapshot.region_snapshot); } - pub fn rollback_undo_entry(&self, undo_entry: UndoLogEntry) { + pub fn rollback_undo_entry(&self, undo_entry: UndoLogEntry<'tcx>) { match undo_entry { OpenSnapshot => { panic!("Failure to observe stack discipline"); @@ -529,13 +532,14 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// The `snapshot` argument to this function is not really used; /// it's just there to make it explicit which snapshot bounds the /// skolemized region that results. It should always be the top-most snapshot. - pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot) -> Region { + pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot) + -> &'tcx Region { assert!(self.in_snapshot()); assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot); let sc = self.skolemization_count.get(); self.skolemization_count.set(sc + 1); - ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br) + self.tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br)) } /// Removes all the edges to/from the skolemized regions that are @@ -543,7 +547,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// completes to remove all trace of the skolemized regions /// created in that time. pub fn pop_skolemized(&self, - skols: &FnvHashSet, + skols: &FnvHashSet<&'tcx ty::Region>, snapshot: &RegionSnapshot) { debug!("pop_skolemized_regions(skols={:?})", skols); @@ -566,7 +570,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { skols.len()); debug_assert! { skols.iter() - .all(|k| match *k { + .all(|&k| match *k { ty::ReSkolemized(index, _) => index.index >= first_to_pop && index.index < last_to_pop, @@ -597,9 +601,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { self.skolemization_count.set(snapshot.skolemization_count); return; - fn kill_constraint(skols: &FnvHashSet, - undo_entry: &UndoLogEntry) - -> bool { + fn kill_constraint<'tcx>(skols: &FnvHashSet<&'tcx ty::Region>, + undo_entry: &UndoLogEntry<'tcx>) + -> bool { match undo_entry { &AddConstraint(ConstrainVarSubVar(_, _)) => false, @@ -626,7 +630,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } - pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> Region { + pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> &'tcx Region { // Creates a fresh bound variable for use in GLB computations. // See discussion of GLB computation in the large comment at // the top of this file for more details. @@ -652,14 +656,14 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { bug!("rollover in RegionInference new_bound()"); } - ReLateBound(debruijn, BrFresh(sc)) + self.tcx.mk_region(ReLateBound(debruijn, BrFresh(sc))) } fn values_are_none(&self) -> bool { self.values.borrow().is_none() } - fn add_constraint(&self, constraint: Constraint, origin: SubregionOrigin<'tcx>) { + fn add_constraint(&self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) { // cannot add constraints once regions are resolved assert!(self.values_are_none()); @@ -704,20 +708,26 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } } - pub fn make_eqregion(&self, origin: SubregionOrigin<'tcx>, sub: Region, sup: Region) { + pub fn make_eqregion(&self, + origin: SubregionOrigin<'tcx>, + sub: &'tcx Region, + sup: &'tcx Region) { if sub != sup { // Eventually, it would be nice to add direct support for // equating regions. self.make_subregion(origin.clone(), sub, sup); self.make_subregion(origin, sup, sub); - if let (ty::ReVar(sub), ty::ReVar(sup)) = (sub, sup) { + if let (ty::ReVar(sub), ty::ReVar(sup)) = (*sub, *sup) { self.unification_table.borrow_mut().union(sub, sup); } } } - pub fn make_subregion(&self, origin: SubregionOrigin<'tcx>, sub: Region, sup: Region) { + pub fn make_subregion(&self, + origin: SubregionOrigin<'tcx>, + sub: &'tcx Region, + sup: &'tcx Region) { // cannot add constraints once regions are resolved assert!(self.values_are_none()); @@ -727,26 +737,26 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { origin); match (sub, sup) { - (ReEarlyBound(..), _) | - (ReLateBound(..), _) | - (_, ReEarlyBound(..)) | - (_, ReLateBound(..)) => { + (&ReEarlyBound(..), _) | + (&ReLateBound(..), _) | + (_, &ReEarlyBound(..)) | + (_, &ReLateBound(..)) => { span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup); } - (_, ReStatic) => { + (_, &ReStatic) => { // all regions are subregions of static, so we can ignore this } - (ReVar(sub_id), ReVar(sup_id)) => { + (&ReVar(sub_id), &ReVar(sup_id)) => { self.add_constraint(ConstrainVarSubVar(sub_id, sup_id), origin); } - (r, ReVar(sup_id)) => { - self.add_constraint(ConstrainRegSubVar(r, sup_id), origin); + (_, &ReVar(sup_id)) => { + self.add_constraint(ConstrainRegSubVar(sub, sup_id), origin); } - (ReVar(sub_id), r) => { - self.add_constraint(ConstrainVarSubReg(sub_id, r), origin); + (&ReVar(sub_id), _) => { + self.add_constraint(ConstrainVarSubReg(sub_id, sup), origin); } _ => { self.add_constraint(ConstrainRegSubReg(sub, sup), origin); @@ -758,8 +768,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn verify_generic_bound(&self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, - sub: Region, - bound: VerifyBound) { + sub: &'tcx Region, + bound: VerifyBound<'tcx>) { self.add_verify(Verify { kind: kind, origin: origin, @@ -768,29 +778,43 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { }); } - pub fn lub_regions(&self, origin: SubregionOrigin<'tcx>, a: Region, b: Region) -> Region { + pub fn lub_regions(&self, + origin: SubregionOrigin<'tcx>, + a: &'tcx Region, + b: &'tcx Region) + -> &'tcx Region { // cannot add constraints once regions are resolved assert!(self.values_are_none()); debug!("RegionVarBindings: lub_regions({:?}, {:?})", a, b); - if a == ty::ReStatic || b == ty::ReStatic { - ReStatic // nothing lives longer than static - } else if a == b { - a // LUB(a,a) = a - } else { - self.combine_vars(Lub, a, b, origin.clone(), |this, old_r, new_r| { - this.make_subregion(origin.clone(), old_r, new_r) - }) + match (a, b) { + (r @ &ReStatic, _) | (_, r @ &ReStatic) => { + r // nothing lives longer than static + } + + _ if a == b => { + a // LUB(a,a) = a + } + + _ => { + self.combine_vars(Lub, a, b, origin.clone(), |this, old_r, new_r| { + this.make_subregion(origin.clone(), old_r, new_r) + }) + } } } - pub fn glb_regions(&self, origin: SubregionOrigin<'tcx>, a: Region, b: Region) -> Region { + pub fn glb_regions(&self, + origin: SubregionOrigin<'tcx>, + a: &'tcx Region, + b: &'tcx Region) + -> &'tcx Region { // cannot add constraints once regions are resolved assert!(self.values_are_none()); debug!("RegionVarBindings: glb_regions({:?}, {:?})", a, b); match (a, b) { - (ReStatic, r) | (r, ReStatic) => { + (&ReStatic, r) | (r, &ReStatic) => { r // static lives longer than everything else } @@ -806,7 +830,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } } - pub fn resolve_var(&self, rid: RegionVid) -> ty::Region { + pub fn resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region { match *self.values.borrow() { None => { span_bug!((*self.var_origins.borrow())[rid.index as usize].span(), @@ -814,18 +838,19 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { been computed!") } Some(ref values) => { - let r = lookup(values, rid); + let r = lookup(self.tcx, values, rid); debug!("resolve_var({:?}) = {:?}", rid, r); r } } } - pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> ty::Region { - ty::ReVar(self.unification_table.borrow_mut().find_value(rid).min_vid) + pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region { + let vid = self.unification_table.borrow_mut().find_value(rid).min_vid; + self.tcx.mk_region(ty::ReVar(vid)) } - fn combine_map(&self, t: CombineMapType) -> &RefCell { + fn combine_map(&self, t: CombineMapType) -> &RefCell> { match t { Glb => &self.glbs, Lub => &self.lubs, @@ -834,26 +859,26 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn combine_vars(&self, t: CombineMapType, - a: Region, - b: Region, + a: &'tcx Region, + b: &'tcx Region, origin: SubregionOrigin<'tcx>, mut relate: F) - -> Region - where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, Region, Region) + -> &'tcx Region + where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, &'tcx Region, &'tcx Region) { let vars = TwoRegions { a: a, b: b }; if let Some(&c) = self.combine_map(t).borrow().get(&vars) { - return ReVar(c); + return self.tcx.mk_region(ReVar(c)); } let c = self.new_region_var(MiscVariable(origin.span())); self.combine_map(t).borrow_mut().insert(vars, c); if self.in_snapshot() { self.undo_log.borrow_mut().push(AddCombination(t, vars)); } - relate(self, a, ReVar(c)); - relate(self, b, ReVar(c)); + relate(self, a, self.tcx.mk_region(ReVar(c))); + relate(self, b, self.tcx.mk_region(ReVar(c))); debug!("combine_vars() c={:?}", c); - ReVar(c) + self.tcx.mk_region(ReVar(c)) } pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec { @@ -878,9 +903,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// related to other regions. pub fn tainted(&self, mark: &RegionSnapshot, - r0: Region, + r0: &'tcx Region, directions: TaintDirections) - -> FnvHashSet { + -> FnvHashSet<&'tcx ty::Region> { debug!("tainted(mark={:?}, r0={:?}, directions={:?})", mark, r0, directions); @@ -888,7 +913,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // edges and add any new regions we find to result_set. This // is not a terribly efficient implementation. let mut taint_set = TaintSet::new(directions, r0); - taint_set.fixed_point(&self.undo_log.borrow()[mark.length..], + taint_set.fixed_point(self.tcx, + &self.undo_log.borrow()[mark.length..], &self.verifys.borrow()); debug!("tainted: result={:?}", taint_set.regions); return taint_set.into_set(); @@ -910,26 +936,30 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { errors } - fn lub_concrete_regions(&self, free_regions: &FreeRegionMap, a: Region, b: Region) -> Region { + fn lub_concrete_regions(&self, + free_regions: &FreeRegionMap, + a: &'tcx Region, + b: &'tcx Region) + -> &'tcx Region { match (a, b) { - (ReLateBound(..), _) | - (_, ReLateBound(..)) | - (ReEarlyBound(..), _) | - (_, ReEarlyBound(..)) | - (ReErased, _) | - (_, ReErased) => { + (&ReLateBound(..), _) | + (_, &ReLateBound(..)) | + (&ReEarlyBound(..), _) | + (_, &ReEarlyBound(..)) | + (&ReErased, _) | + (_, &ReErased) => { bug!("cannot relate region: LUB({:?}, {:?})", a, b); } - (ReStatic, _) | (_, ReStatic) => { - ReStatic // nothing lives longer than static + (r @ &ReStatic, _) | (_, r @ &ReStatic) => { + r // nothing lives longer than static } - (ReEmpty, r) | (r, ReEmpty) => { + (&ReEmpty, r) | (r, &ReEmpty) => { r // everything lives longer than empty } - (ReVar(v_id), _) | (_, ReVar(v_id)) => { + (&ReVar(v_id), _) | (_, &ReVar(v_id)) => { span_bug!((*self.var_origins.borrow())[v_id.index as usize].span(), "lub_concrete_regions invoked with non-concrete \ regions: {:?}, {:?}", @@ -937,9 +967,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { b); } - (ReFree(ref fr), ReScope(s_id)) | - (ReScope(s_id), ReFree(ref fr)) => { - let f = ReFree(*fr); + (&ReFree(fr), &ReScope(s_id)) | + (&ReScope(s_id), &ReFree(fr)) => { // A "free" region can be interpreted as "some region // at least as big as the block fr.scope_id". So, we can // reasonably compare free regions and scopes: @@ -949,33 +978,34 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // if the free region's scope `fr.scope_id` is bigger than // the scope region `s_id`, then the LUB is the free // region itself: - f + self.tcx.mk_region(ReFree(fr)) } else { // otherwise, we don't know what the free region is, // so we must conservatively say the LUB is static: - ReStatic + self.tcx.mk_region(ReStatic) } } - (ReScope(a_id), ReScope(b_id)) => { + (&ReScope(a_id), &ReScope(b_id)) => { // The region corresponding to an outer block is a // subtype of the region corresponding to an inner // block. - ReScope(self.tcx.region_maps.nearest_common_ancestor(a_id, b_id)) + self.tcx.mk_region(ReScope( + self.tcx.region_maps.nearest_common_ancestor(a_id, b_id))) } - (ReFree(a_fr), ReFree(b_fr)) => { - free_regions.lub_free_regions(a_fr, b_fr) + (&ReFree(a_fr), &ReFree(b_fr)) => { + self.tcx.mk_region(free_regions.lub_free_regions(a_fr, b_fr)) } // For these types, we cannot define any additional // relationship: - (ReSkolemized(..), _) | - (_, ReSkolemized(..)) => { + (&ReSkolemized(..), _) | + (_, &ReSkolemized(..)) => { if a == b { a } else { - ReStatic + self.tcx.mk_region(ReStatic) } } } @@ -985,24 +1015,24 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // ______________________________________________________________________ #[derive(Copy, Clone, Debug)] -pub enum VarValue { - Value(Region), +pub enum VarValue<'tcx> { + Value(&'tcx Region), ErrorValue, } struct RegionAndOrigin<'tcx> { - region: Region, + region: &'tcx Region, origin: SubregionOrigin<'tcx>, } -type RegionGraph = graph::Graph<(), Constraint>; +type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>; impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { fn infer_variable_values(&self, free_regions: &FreeRegionMap, errors: &mut Vec>, subject: ast::NodeId) - -> Vec { + -> Vec> { let mut var_data = self.construct_var_data(); // Dorky hack to cause `dump_constraints` to only get called @@ -1020,9 +1050,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { var_data } - fn construct_var_data(&self) -> Vec { + fn construct_var_data(&self) -> Vec> { (0..self.num_vars() as usize) - .map(|_| Value(ty::ReEmpty)) + .map(|_| Value(self.tcx.mk_region(ty::ReEmpty))) .collect() } @@ -1059,7 +1089,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } } - fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue]) { + fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue<'tcx>]) { self.iterate_until_fixed_point("Expansion", |constraint, origin| { debug!("expansion: constraint={:?} origin={:?}", constraint, origin); @@ -1089,9 +1119,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { fn expand_node(&self, free_regions: &FreeRegionMap, - a_region: Region, + a_region: &'tcx Region, b_vid: RegionVid, - b_data: &mut VarValue) + b_data: &mut VarValue<'tcx>) -> bool { debug!("expand_node({:?}, {:?} == {:?})", a_region, @@ -1099,7 +1129,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { b_data); // Check if this relationship is implied by a given. - match a_region { + match *a_region { ty::ReFree(fr) => { if self.givens.borrow().contains(&(fr, b_vid)) { debug!("given"); @@ -1136,7 +1166,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// and check that they are satisfied. fn collect_errors(&self, free_regions: &FreeRegionMap, - var_data: &mut Vec, + var_data: &mut Vec>, errors: &mut Vec>) { let constraints = self.constraints.borrow(); for (constraint, origin) in constraints.iter() { @@ -1192,7 +1222,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { for verify in self.verifys.borrow().iter() { debug!("collect_errors: verify={:?}", verify); - let sub = normalize(var_data, verify.region); + let sub = normalize(self.tcx, var_data, verify.region); if verify.bound.is_met(self.tcx, free_regions, var_data, sub) { continue; } @@ -1213,8 +1243,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// and create a `RegionResolutionError` for each of them. fn collect_var_errors(&self, free_regions: &FreeRegionMap, - var_data: &[VarValue], - graph: &RegionGraph, + var_data: &[VarValue<'tcx>], + graph: &RegionGraph<'tcx>, errors: &mut Vec>) { debug!("collect_var_errors"); @@ -1271,7 +1301,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } } - fn construct_graph(&self) -> RegionGraph { + fn construct_graph(&self) -> RegionGraph<'tcx> { let num_vars = self.num_vars(); let constraints = self.constraints.borrow(); @@ -1315,7 +1345,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { fn collect_error_for_expanding_node(&self, free_regions: &FreeRegionMap, - graph: &RegionGraph, + graph: &RegionGraph<'tcx>, dup_vec: &mut [u32], node_idx: RegionVid, errors: &mut Vec>) { @@ -1339,9 +1369,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // the user will more likely get a specific suggestion. fn free_regions_first(a: &RegionAndOrigin, b: &RegionAndOrigin) -> Ordering { match (a.region, b.region) { - (ReFree(..), ReFree(..)) => Equal, - (ReFree(..), _) => Less, - (_, ReFree(..)) => Greater, + (&ReFree(..), &ReFree(..)) => Equal, + (&ReFree(..), _) => Less, + (_, &ReFree(..)) => Greater, (_, _) => Equal, } } @@ -1378,7 +1408,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn collect_concrete_regions(&self, - graph: &RegionGraph, + graph: &RegionGraph<'tcx>, orig_node_idx: RegionVid, dir: Direction, dup_vec: &mut [u32]) @@ -1423,7 +1453,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { fn process_edges<'a, 'gcx, 'tcx>(this: &RegionVarBindings<'a, 'gcx, 'tcx>, state: &mut WalkState<'tcx>, - graph: &RegionGraph, + graph: &RegionGraph<'tcx>, source_vid: RegionVid, dir: Direction) { debug!("process_edges(source_vid={:?}, dir={:?})", source_vid, dir); @@ -1460,7 +1490,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn iterate_until_fixed_point(&self, tag: &str, mut body: F) - where F: FnMut(&Constraint, &SubregionOrigin<'tcx>) -> bool + where F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> bool { let mut iteration = 0; let mut changed = true; @@ -1481,17 +1511,23 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } -fn normalize(values: &Vec, r: ty::Region) -> ty::Region { - match r { - ty::ReVar(rid) => lookup(values, rid), +fn normalize<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + values: &Vec>, + r: &'tcx ty::Region) + -> &'tcx ty::Region { + match *r { + ty::ReVar(rid) => lookup(tcx, values, rid), _ => r, } } -fn lookup(values: &Vec, rid: ty::RegionVid) -> ty::Region { +fn lookup<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + values: &Vec>, + rid: ty::RegionVid) + -> &'tcx ty::Region { match values[rid.index as usize] { Value(r) => r, - ErrorValue => ReStatic, // Previously reported error. + ErrorValue => tcx.mk_region(ReStatic), // Previously reported error. } } @@ -1535,8 +1571,8 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> { } } -impl<'a, 'gcx, 'tcx> VerifyBound { - fn for_each_region(&self, f: &mut FnMut(ty::Region)) { +impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { + fn for_each_region(&self, f: &mut FnMut(&'tcx ty::Region)) { match self { &VerifyBound::AnyRegion(ref rs) | &VerifyBound::AllRegions(ref rs) => for &r in rs { @@ -1552,7 +1588,7 @@ impl<'a, 'gcx, 'tcx> VerifyBound { pub fn must_hold(&self) -> bool { match self { - &VerifyBound::AnyRegion(ref bs) => bs.contains(&ty::ReStatic), + &VerifyBound::AnyRegion(ref bs) => bs.contains(&&ty::ReStatic), &VerifyBound::AllRegions(ref bs) => bs.is_empty(), &VerifyBound::AnyBound(ref bs) => bs.iter().any(|b| b.must_hold()), &VerifyBound::AllBounds(ref bs) => bs.iter().all(|b| b.must_hold()), @@ -1562,13 +1598,13 @@ impl<'a, 'gcx, 'tcx> VerifyBound { pub fn cannot_hold(&self) -> bool { match self { &VerifyBound::AnyRegion(ref bs) => bs.is_empty(), - &VerifyBound::AllRegions(ref bs) => bs.contains(&ty::ReEmpty), + &VerifyBound::AllRegions(ref bs) => bs.contains(&&ty::ReEmpty), &VerifyBound::AnyBound(ref bs) => bs.iter().all(|b| b.cannot_hold()), &VerifyBound::AllBounds(ref bs) => bs.iter().any(|b| b.cannot_hold()), } } - pub fn or(self, vb: VerifyBound) -> VerifyBound { + pub fn or(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> { if self.must_hold() || vb.cannot_hold() { self } else if self.cannot_hold() || vb.must_hold() { @@ -1578,7 +1614,7 @@ impl<'a, 'gcx, 'tcx> VerifyBound { } } - pub fn and(self, vb: VerifyBound) -> VerifyBound { + pub fn and(self, vb: VerifyBound<'tcx>) -> VerifyBound<'tcx> { if self.must_hold() && vb.must_hold() { self } else if self.cannot_hold() && vb.cannot_hold() { @@ -1590,18 +1626,18 @@ impl<'a, 'gcx, 'tcx> VerifyBound { fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, free_regions: &FreeRegionMap, - var_values: &Vec, - min: ty::Region) + var_values: &Vec>, + min: &'tcx ty::Region) -> bool { match self { &VerifyBound::AnyRegion(ref rs) => rs.iter() - .map(|&r| normalize(var_values, r)) + .map(|&r| normalize(tcx, var_values, r)) .any(|r| free_regions.is_subregion_of(tcx, min, r)), &VerifyBound::AllRegions(ref rs) => rs.iter() - .map(|&r| normalize(var_values, r)) + .map(|&r| normalize(tcx, var_values, r)) .all(|r| free_regions.is_subregion_of(tcx, min, r)), &VerifyBound::AnyBound(ref bs) => diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 5f550b427e21a..357a03a2ffd7c 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -72,10 +72,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv } } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - match r { - ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid), - _ => r, + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + match *r { + ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid), + _ => r, } } } @@ -138,10 +138,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx> } } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - match r { - ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid), - _ => r, + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + match *r { + ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid), + _ => r, } } } diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index 2f7f5254727db..159de2faced57 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -107,7 +107,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> } } - fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> { + fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region> { debug!("{}.regions({:?}, {:?}) self.cause={:?}", self.tag(), a, b, self.fields.cause); // FIXME -- we have more fine-grained information available diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 48ea953cc1e8b..1e4b2e9116fd2 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -27,6 +27,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(collections)] +#![feature(conservative_impl_trait)] #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(enumset)] diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 92e1b0681cc7e..b33bc520fe216 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -149,7 +149,7 @@ pub trait CrateStore<'tcx> { fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind; fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx>; - fn item_variances(&self, def: DefId) -> ty::ItemVariances; + fn item_variances(&self, def: DefId) -> Vec; fn repr_attrs(&self, def: DefId) -> Vec; fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Ty<'tcx>; @@ -198,7 +198,6 @@ pub trait CrateStore<'tcx> { fn is_default_impl(&self, impl_did: DefId) -> bool; fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool; fn is_foreign_item(&self, did: DefId) -> bool; - fn is_static_method(&self, did: DefId) -> bool; fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool; fn is_typedef(&self, did: DefId) -> bool; @@ -329,7 +328,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind { bug!("closure_kind") } fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> { bug!("closure_ty") } - fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") } + fn item_variances(&self, def: DefId) -> Vec { bug!("item_variances") } fn repr_attrs(&self, def: DefId) -> Vec { bug!("repr_attrs") } fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Ty<'tcx> { bug!("item_type") } @@ -391,7 +390,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool { bug!("is_extern_item") } fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") } - fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") } fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false } fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 2a8594c59a837..37366f38974a4 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[0].sty { + match substs.substs.type_at(0).sty { TyEnum(tyid, _) | TyStruct(tyid, _) => { self.check_def_id(tyid.did) } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 87463055a276a..798702e6fd657 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -76,7 +76,7 @@ pub trait Delegate<'tcx> { borrow_id: ast::NodeId, borrow_span: Span, cmt: mc::cmt<'tcx>, - loan_region: ty::Region, + loan_region: &'tcx ty::Region, bk: ty::BorrowKind, loan_cause: LoanCause); @@ -301,11 +301,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { for arg in &decl.inputs { let arg_ty = return_if_err!(self.mc.infcx.node_ty(arg.pat.id)); - let fn_body_scope = self.tcx().region_maps.node_extent(body.id); + let fn_body_scope_r = self.tcx().node_scope_region(body.id); let arg_cmt = self.mc.cat_rvalue( arg.id, arg.pat.span, - ty::ReScope(fn_body_scope), // Args live only as long as the fn body. + fn_body_scope_r, // Args live only as long as the fn body. arg_ty); self.walk_irrefutable_pat(arg_cmt, &arg.pat); @@ -352,7 +352,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn borrow_expr(&mut self, expr: &hir::Expr, - r: ty::Region, + r: &'tcx ty::Region, bk: ty::BorrowKind, cause: LoanCause) { debug!("borrow_expr(expr={:?}, r={:?}, bk={:?})", @@ -431,7 +431,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { hir::ExprMatch(ref discr, ref arms, _) => { let discr_cmt = return_if_err!(self.mc.cat_expr(&discr)); - self.borrow_expr(&discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant); + let r = self.tcx().mk_region(ty::ReEmpty); + self.borrow_expr(&discr, r, ty::ImmBorrow, MatchDiscriminant); // treatment of the discriminant is handled while walking the arms. for arm in arms { @@ -449,7 +450,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: let expr_ty = return_if_err!(self.mc.infcx.node_ty(expr.id)); - if let ty::TyRef(&r, _) = expr_ty.sty { + if let ty::TyRef(r, _) = expr_ty.sty { let bk = ty::BorrowKind::from_mutbl(m); self.borrow_expr(&base, r, bk, AddrOf); } @@ -557,7 +558,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { let callee_ty = return_if_err!(self.mc.infcx.expr_ty_adjusted(callee)); debug!("walk_callee: callee={:?} callee_ty={:?}", callee, callee_ty); - let call_scope = self.tcx().region_maps.node_extent(call.id); match callee_ty.sty { ty::TyFnDef(..) | ty::TyFnPtr(_) => { self.consume_expr(callee); @@ -578,14 +578,16 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { }; match overloaded_call_type { FnMutOverloadedCall => { + let call_scope_r = self.tcx().node_scope_region(call.id); self.borrow_expr(callee, - ty::ReScope(call_scope), + call_scope_r, ty::MutBorrow, ClosureInvocation); } FnOverloadedCall => { + let call_scope_r = self.tcx().node_scope_region(call.id); self.borrow_expr(callee, - ty::ReScope(call_scope), + call_scope_r, ty::ImmBorrow, ClosureInvocation); } @@ -761,7 +763,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { }; let bk = ty::BorrowKind::from_mutbl(m); self.delegate.borrow(expr.id, expr.span, cmt, - *r, bk, AutoRef); + r, bk, AutoRef); } } } @@ -822,7 +824,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { self.delegate.borrow(expr.id, expr.span, cmt_base, - *r, + r, ty::BorrowKind::from_mutbl(m), AutoRef); } @@ -835,7 +837,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // Converting from a &T to *T (or &mut T to *mut T) is // treated as borrowing it for the enclosing temporary // scope. - let r = ty::ReScope(self.tcx().region_maps.node_extent(expr.id)); + let r = self.tcx().node_scope_region(expr.id); self.delegate.borrow(expr.id, expr.span, @@ -890,7 +892,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // methods are implicitly autoref'd which sadly does not use // adjustments, so we must hardcode the borrow here. - let r = ty::ReScope(self.tcx().region_maps.node_extent(expr.id)); + let r = self.tcx().node_scope_region(expr.id); let bk = ty::ImmBorrow; for &arg in &rhs { @@ -979,7 +981,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // It is also a borrow or copy/move of the value being matched. match bmode { hir::BindByRef(m) => { - if let ty::TyRef(&r, _) = pat_ty.sty { + if let ty::TyRef(r, _) = pat_ty.sty { let bk = ty::BorrowKind::from_mutbl(m); delegate.borrow(pat.id, pat.span, cmt_pat, r, bk, RefBinding); } diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index e4ce89767139a..8193d062631c1 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -37,7 +37,7 @@ impl FreeRegionMap { for implied_bound in implied_bounds { debug!("implied bound: {:?}", implied_bound); match *implied_bound { - ImpliedBound::RegionSubRegion(ty::ReFree(free_a), ty::ReFree(free_b)) => { + ImpliedBound::RegionSubRegion(&ty::ReFree(free_a), &ty::ReFree(free_b)) => { self.relate_free_regions(free_a, free_b); } ImpliedBound::RegionSubRegion(..) | @@ -65,9 +65,9 @@ impl FreeRegionMap { } ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => { match (r_a, r_b) { - (ty::ReStatic, ty::ReFree(_)) => {}, - (ty::ReFree(fr_a), ty::ReStatic) => self.relate_to_static(fr_a), - (ty::ReFree(fr_a), ty::ReFree(fr_b)) => { + (&ty::ReStatic, &ty::ReFree(_)) => {}, + (&ty::ReFree(fr_a), &ty::ReStatic) => self.relate_to_static(fr_a), + (&ty::ReFree(fr_a), &ty::ReFree(fr_b)) => { // Record that `'a:'b`. Or, put another way, `'b <= 'a`. self.relate_free_regions(fr_b, fr_a); } @@ -122,26 +122,26 @@ impl FreeRegionMap { /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. pub fn is_subregion_of(&self, tcx: TyCtxt, - sub_region: ty::Region, - super_region: ty::Region) + sub_region: &ty::Region, + super_region: &ty::Region) -> bool { let result = sub_region == super_region || { match (sub_region, super_region) { - (ty::ReEmpty, _) | - (_, ty::ReStatic) => + (&ty::ReEmpty, _) | + (_, &ty::ReStatic) => true, - (ty::ReScope(sub_scope), ty::ReScope(super_scope)) => + (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => tcx.region_maps.is_subscope_of(sub_scope, super_scope), - (ty::ReScope(sub_scope), ty::ReFree(fr)) => + (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => tcx.region_maps.is_subscope_of(sub_scope, fr.scope) || self.is_static(fr), - (ty::ReFree(sub_fr), ty::ReFree(super_fr)) => + (&ty::ReFree(sub_fr), &ty::ReFree(super_fr)) => self.sub_free_region(sub_fr, super_fr), - (ty::ReStatic, ty::ReFree(sup_fr)) => + (&ty::ReStatic, &ty::ReFree(sup_fr)) => self.is_static(sup_fr), _ => diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 676e456dcea94..a74bdb02044de 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -90,11 +90,11 @@ use std::rc::Rc; #[derive(Clone, PartialEq)] pub enum Categorization<'tcx> { - Rvalue(ty::Region), // temporary val, argument is its scope + Rvalue(&'tcx ty::Region), // temporary val, argument is its scope StaticItem, Upvar(Upvar), // upvar referenced by closure env Local(ast::NodeId), // local variable - Deref(cmt<'tcx>, usize, PointerKind), // deref of a ptr + Deref(cmt<'tcx>, usize, PointerKind<'tcx>), // deref of a ptr Interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc Downcast(cmt<'tcx>, DefId), // selects a particular enum variant (*1) @@ -110,18 +110,18 @@ pub struct Upvar { // different kinds of pointers: #[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub enum PointerKind { +pub enum PointerKind<'tcx> { /// `Box` Unique, /// `&T` - BorrowedPtr(ty::BorrowKind, ty::Region), + BorrowedPtr(ty::BorrowKind, &'tcx ty::Region), /// `*T` UnsafePtr(hir::Mutability), /// Implicit deref of the `&T` that results from an overloaded index `[]`. - Implicit(ty::BorrowKind, ty::Region), + Implicit(ty::BorrowKind, &'tcx ty::Region), } // We use the term "interior" to mean "something reachable from the @@ -198,8 +198,8 @@ pub type cmt<'tcx> = Rc>; // We pun on *T to mean both actual deref of a ptr as well // as accessing of components: #[derive(Copy, Clone)] -pub enum deref_kind { - deref_ptr(PointerKind), +pub enum deref_kind<'tcx> { + deref_ptr(PointerKind<'tcx>), deref_interior(InteriorKind), } @@ -216,7 +216,7 @@ fn deref_kind(t: Ty, context: DerefKindContext) -> McResult { ty::TyRef(r, mt) => { let kind = ty::BorrowKind::from_mutbl(mt.mutbl); - Ok(deref_ptr(BorrowedPtr(kind, *r))) + Ok(deref_ptr(BorrowedPtr(kind, r))) } ty::TyRawPtr(ref mt) => { @@ -767,13 +767,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { }; // Region of environment pointer - let env_region = ty::ReFree(ty::FreeRegion { + let env_region = self.tcx().mk_region(ty::ReFree(ty::FreeRegion { // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. scope: self.tcx().region_maps.item_extent(fn_body_id), bound_region: ty::BrEnv - }); + })); let env_ptr = BorrowedPtr(env_borrow_kind, env_region); @@ -817,11 +817,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { /// Returns the lifetime of a temporary created by expr with id `id`. /// This could be `'static` if `id` is part of a constant expression. - pub fn temporary_scope(&self, id: ast::NodeId) -> ty::Region { - match self.infcx.temporary_scope(id) { + pub fn temporary_scope(&self, id: ast::NodeId) -> &'tcx ty::Region { + self.tcx().mk_region(match self.infcx.temporary_scope(id) { Some(scope) => ty::ReScope(scope), None => ty::ReStatic - } + }) } pub fn cat_rvalue_node(&self, @@ -845,7 +845,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let re = if qualif.intersects(ConstQualif::NON_STATIC_BORROWS) { self.temporary_scope(id) } else { - ty::ReStatic + self.tcx().mk_region(ty::ReStatic) }; let ret = self.cat_rvalue(id, span, re, expr_ty); debug!("cat_rvalue_node ret {:?}", ret); @@ -855,7 +855,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { pub fn cat_rvalue(&self, cmt_id: ast::NodeId, span: Span, - temp_scope: ty::Region, + temp_scope: &'tcx ty::Region, expr_ty: Ty<'tcx>) -> cmt<'tcx> { let ret = Rc::new(cmt_ { id:cmt_id, @@ -1480,7 +1480,7 @@ pub fn ptr_sigil(ptr: PointerKind) -> &'static str { } } -impl fmt::Debug for PointerKind { +impl<'tcx> fmt::Debug for PointerKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Unique => write!(f, "Box"), diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8369a6c39d54d..ebe4050022153 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -89,9 +89,12 @@ struct LifetimeContext<'a, 'tcx: 'a> { #[derive(PartialEq, Debug)] enum ScopeChain<'a> { - /// EarlyScope(['a, 'b, ...], s) extends s with early-bound - /// lifetimes. - EarlyScope(&'a [hir::LifetimeDef], Scope<'a>), + /// EarlyScope(['a, 'b, ...], start, s) extends s with early-bound + /// lifetimes, with consecutive parameter indices from `start`. + /// That is, 'a has index `start`, 'b has index `start + 1`, etc. + /// Indices before `start` correspond to other generic parameters + /// of a parent item (trait/impl of a method), or `Self` in traits. + EarlyScope(&'a [hir::LifetimeDef], u32, Scope<'a>), /// LateScope(['a, 'b, ...], s) extends s with late-bound /// lifetimes introduced by the declaration binder_id. LateScope(&'a [hir::LifetimeDef], Scope<'a>), @@ -157,7 +160,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> { hir::ItemImpl(_, _, ref generics, _, _, _) => { // These kinds of items have only early bound lifetime parameters. let lifetimes = &generics.lifetimes; - this.with(EarlyScope(lifetimes, &ROOT_SCOPE), |old_scope, this| { + let start = if let hir::ItemTrait(..) = item.node { + 1 // Self comes before lifetimes + } else { + 0 + }; + this.with(EarlyScope(lifetimes, start, &ROOT_SCOPE), |old_scope, this| { this.check_lifetime_defs(old_scope, lifetimes); intravisit::walk_item(this, item); }); @@ -461,7 +469,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Block) { FnScope { s, .. } => { scope = s; } RootScope => { return; } - EarlyScope(lifetimes, s) | + EarlyScope(lifetimes, _, s) | LateScope(lifetimes, s) => { for lifetime_def in lifetimes { // FIXME (#24278): non-hygienic comparison @@ -566,8 +574,24 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .cloned() .partition(|l| self.map.late_bound.contains_key(&l.lifetime.id)); + // Find the start of nested early scopes, e.g. in methods. + let mut start = 0; + if let EarlyScope(..) = *self.scope { + let parent = self.hir_map.expect_item(self.hir_map.get_parent(fn_id)); + if let hir::ItemTrait(..) = parent.node { + start += 1; // Self comes first. + } + match parent.node { + hir::ItemTrait(_, ref generics, _, _) | + hir::ItemImpl(_, _, ref generics, _, _, _) => { + start += generics.lifetimes.len() + generics.ty_params.len(); + } + _ => {} + } + } + let this = self; - this.with(EarlyScope(&early, this.scope), move |old_scope, this| { + this.with(EarlyScope(&early, start as u32, this.scope), move |old_scope, this| { this.with(LateScope(&late, this.scope), move |_, this| { this.check_lifetime_defs(old_scope, &generics.lifetimes); walk(this); @@ -597,19 +621,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { break; } - EarlyScope(lifetimes, s) => { + EarlyScope(lifetimes, start, s) => { match search_lifetimes(lifetimes, lifetime_ref) { - Some((mut index, lifetime_def)) => { - // Adjust for nested early scopes, e.g. in methods. - let mut parent = s; - while let EarlyScope(lifetimes, s) = *parent { - index += lifetimes.len() as u32; - parent = s; - } - assert_eq!(*parent, RootScope); - + Some((index, lifetime_def)) => { let decl_id = lifetime_def.id; - let def = DefEarlyBoundRegion(index, decl_id); + let def = DefEarlyBoundRegion(start + index, decl_id); self.insert_lifetime(lifetime_ref, def); return; } @@ -671,7 +687,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { break; } - EarlyScope(lifetimes, s) | + EarlyScope(lifetimes, _, s) | LateScope(lifetimes, s) => { search_result = search_lifetimes(lifetimes, lifetime_ref); if search_result.is_some() { @@ -767,7 +783,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } - EarlyScope(lifetimes, s) | + EarlyScope(lifetimes, _, s) | LateScope(lifetimes, s) => { if let Some((_, lifetime_def)) = search_lifetimes(lifetimes, lifetime) { signal_shadowing_problem( diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index f511d820fac58..059fcfdca8a00 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -911,7 +911,7 @@ pub enum Rvalue<'tcx> { Repeat(Operand<'tcx>, TypedConstVal<'tcx>), /// &x or &mut x - Ref(Region, BorrowKind, Lvalue<'tcx>), + Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>), /// length of a [X] or [X;n] value Len(Lvalue<'tcx>), diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index cf91229f1c713..76e5f8598c1c5 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -145,8 +145,7 @@ impl<'tcx> Rvalue<'tcx> { } &Rvalue::Ref(reg, bk, ref lv) => { let lv_ty = lv.ty(mir, tcx).to_ty(tcx); - Some(tcx.mk_ref( - tcx.mk_region(reg), + Some(tcx.mk_ref(reg, ty::TypeAndMut { ty: lv_ty, mutbl: bk.to_mutbl_lossy() diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index ead8de86dbae4..f608185157a4e 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -724,7 +724,7 @@ make_mir_visitor!(Visitor,); make_mir_visitor!(MutVisitor,mut); #[derive(Copy, Clone, Debug)] -pub enum LvalueContext { +pub enum LvalueContext<'tcx> { // Appears as LHS of an assignment Store, @@ -738,7 +738,7 @@ pub enum LvalueContext { Inspect, // Being borrowed - Borrow { region: Region, kind: BorrowKind }, + Borrow { region: &'tcx Region, kind: BorrowKind }, // Being sliced -- this should be same as being borrowed, probably Slice { from_start: usize, from_end: usize }, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d6f263fcebeb0..10112e5084557 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[1..].iter() - .zip(&impl_trait_ref.substs.types[1..]) + if trait_ref.substs.types().skip(1) + .zip(impl_trait_ref.substs.types().skip(1)) .all(|(u,v)| self.fuzzy_match_tys(u, v)) { fuzzy_match_impls.push(def_id); @@ -738,8 +738,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::Predicate::Trait(ref data) => { let trait_ref = data.to_poly_trait_ref(); let self_ty = trait_ref.self_ty(); - let all_types = &trait_ref.substs().types; - if all_types.references_error() { + if predicate.references_error() { } else { // Typically, this ambiguity should only happen if // there are unresolved type inference variables diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 837e33b3e7fc2..6598aacc1d3d2 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -93,7 +93,7 @@ pub struct FulfillmentContext<'tcx> { #[derive(Clone)] pub struct RegionObligation<'tcx> { - pub sub_region: ty::Region, + pub sub_region: &'tcx ty::Region, pub sup_type: Ty<'tcx>, pub cause: ObligationCause<'tcx>, } @@ -142,7 +142,7 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> { // Auto trait obligations on `impl Trait`. if tcx.trait_has_default_impl(predicate.def_id()) { let substs = predicate.skip_binder().trait_ref.substs; - if substs.types.len() == 1 && substs.regions.is_empty() { + if substs.types().count() == 1 && substs.regions().next().is_none() { if let ty::TyAnon(..) = predicate.skip_binder().self_ty().sty { return true; } @@ -162,7 +162,7 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> { let concrete_ty = ty_scheme.ty.subst(tcx, substs); let predicate = ty::TraitRef { def_id: self.predicate.def_id(), - substs: Substs::new_trait(tcx, vec![], vec![], concrete_ty) + substs: Substs::new_trait(tcx, concrete_ty, &[]) }.to_predicate(); let original_obligation = Obligation::new(self.cause.clone(), @@ -246,7 +246,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> { pub fn register_region_obligation(&mut self, t_a: Ty<'tcx>, - r_b: ty::Region, + r_b: &'tcx ty::Region, cause: ObligationCause<'tcx>) { register_region_obligation(t_a, r_b, cause, &mut self.region_obligations); @@ -440,8 +440,7 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't { t.skip_binder() // ok b/c this check doesn't care about regions .input_types() - .iter() - .map(|t| selcx.infcx().resolve_type_vars_if_possible(t)) + .map(|t| selcx.infcx().resolve_type_vars_if_possible(&t)) .filter(|t| t.has_infer_types()) .flat_map(|t| t.walk()) .filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false }) @@ -581,7 +580,8 @@ fn process_predicate<'a, 'gcx, 'tcx>( // Otherwise, we have something of the form // `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`. Some(t_a) => { - register_region_obligation(t_a, ty::ReStatic, + let r_static = selcx.tcx().mk_region(ty::ReStatic); + register_region_obligation(t_a, r_static, obligation.cause.clone(), region_obligations); Ok(Some(vec![])) @@ -691,7 +691,7 @@ fn coinductive_obligation<'a,'gcx,'tcx>(selcx: &SelectionContext<'a,'gcx,'tcx>, } fn register_region_obligation<'tcx>(t_a: Ty<'tcx>, - r_b: ty::Region, + r_b: &'tcx ty::Region, cause: ObligationCause<'tcx>, region_obligations: &mut NodeMap>>) { diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 25d2df8fdedb3..219d520046762 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -145,7 +145,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.input_types()[1..].iter().any(|t| t.has_self_ty()) + data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty()) } ty::Predicate::Projection(..) | ty::Predicate::WellFormed(..) | diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9ea738bd326eb..b015de79be5c6 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -36,7 +36,7 @@ use super::util; use hir::def_id::DefId; use infer; use infer::{InferCtxt, InferOk, TypeFreshener, TypeOrigin}; -use ty::subst::{Subst, Substs}; +use ty::subst::{Kind, Subst, Substs}; use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; use traits; use ty::fast_reject; @@ -644,8 +644,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // This suffices to allow chains like `FnMut` implemented in // terms of `Fn` etc, but we could probably make this more // precise still. - let input_types = stack.fresh_trait_ref.0.input_types(); - let unbound_input_types = input_types.iter().any(|ty| ty.is_fresh()); + let unbound_input_types = stack.fresh_trait_ref.input_types().any(|ty| ty.is_fresh()); if unbound_input_types && self.intercrate { debug!("evaluate_stack({:?}) --> unbound argument, intercrate --> ambiguous", stack.fresh_trait_ref); @@ -1064,9 +1063,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match *candidate { Ok(Some(_)) | Err(_) => true, - Ok(None) => { - cache_fresh_trait_pred.0.trait_ref.substs.types.has_infer_types() - } + Ok(None) => cache_fresh_trait_pred.has_infer_types() } } @@ -1250,7 +1247,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &TraitObligation<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>, skol_trait_ref: ty::TraitRef<'tcx>, - skol_map: &infer::SkolemizationMap, + skol_map: &infer::SkolemizationMap<'tcx>, snapshot: &infer::CombinedSnapshot) -> bool { @@ -1603,7 +1600,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return; } }; - let target = obligation.predicate.skip_binder().input_types()[1]; + let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1); debug!("assemble_candidates_for_unsizing(source={:?}, target={:?})", source, target); @@ -1936,7 +1933,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // for `PhantomData`, we pass `T` ty::TyStruct(def, substs) if def.is_phantom_data() => { - substs.types.to_vec() + substs.types().collect() } ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { @@ -1985,7 +1982,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { trait_def_id, recursion_depth, normalized_ty, - vec![]); + &[]); obligations.push(skol_obligation); this.infcx().plug_leaks(skol_map, snapshot, &obligations) }) @@ -2180,12 +2177,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match self_ty.sty { ty::TyTrait(ref data) => { // OK to skip the binder, it is reintroduced below - let input_types = data.principal.skip_binder().input_types(); + let input_types = data.principal.input_types(); let assoc_types = data.projection_bounds.iter() .map(|pb| pb.skip_binder().ty); - let all_types: Vec<_> = input_types.iter().cloned() - .chain(assoc_types) - .collect(); + let all_types: Vec<_> = input_types.chain(assoc_types) + .collect(); // reintroduce the two binding levels we skipped, then flatten into one let all_types = ty::Binder(ty::Binder(all_types)); @@ -2267,7 +2263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { mut substs: Normalized<'tcx, &'tcx Substs<'tcx>>, cause: ObligationCause<'tcx>, recursion_depth: usize, - skol_map: infer::SkolemizationMap, + skol_map: infer::SkolemizationMap<'tcx>, snapshot: &infer::CombinedSnapshot) -> VtableImplData<'tcx, PredicateObligation<'tcx>> { @@ -2476,7 +2472,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // regions here. See the comment there for more details. let source = self.infcx.shallow_resolve( tcx.no_late_bound_regions(&obligation.self_ty()).unwrap()); - let target = obligation.predicate.skip_binder().input_types()[1]; + let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1); let target = self.infcx.shallow_resolve(target); debug!("confirm_builtin_unsize_candidate(source={:?}, target={:?})", @@ -2585,7 +2581,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } else { return Err(Unimplemented); }; - let mut ty_params = BitVector::new(substs_a.types.len()); + let mut ty_params = BitVector::new(substs_a.types().count()); let mut found = false; for ty in field.walk() { if let ty::TyParam(p) = ty.sty { @@ -2601,14 +2597,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // TyError and ensure they do not affect any other fields. // This could be checked after type collection for any struct // with a potentially unsized trailing field. - let types = substs_a.types.iter().enumerate().map(|(i, ty)| { + let params = substs_a.params().iter().enumerate().map(|(i, &k)| { if ty_params.contains(i) { - tcx.types.err + Kind::from(tcx.types.err) } else { - ty + k } - }).collect(); - let substs = Substs::new(tcx, types, substs_a.regions.clone()); + }); + let substs = Substs::new(tcx, params); for &ty in fields.split_last().unwrap().1 { if ty.subst(tcx, substs).references_error() { return Err(Unimplemented); @@ -2621,15 +2617,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // Check that the source structure with the target's // type parameters is a subtype of the target. - let types = substs_a.types.iter().enumerate().map(|(i, ty)| { + let params = substs_a.params().iter().enumerate().map(|(i, &k)| { if ty_params.contains(i) { - substs_b.types[i] + Kind::from(substs_b.type_at(i)) } else { - ty + k } - }).collect(); - let substs = Substs::new(tcx, types, substs_a.regions.clone()); - let new_struct = tcx.mk_struct(def, substs); + }); + let new_struct = tcx.mk_struct(def, Substs::new(tcx, params)); let origin = TypeOrigin::Misc(obligation.cause.span); let InferOk { obligations, .. } = self.infcx.sub_types(false, origin, new_struct, target) @@ -2642,7 +2637,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation.predicate.def_id(), obligation.recursion_depth + 1, inner_source, - vec![inner_target])); + &[inner_target])); } _ => bug!() @@ -2665,7 +2660,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { impl_def_id: DefId, obligation: &TraitObligation<'tcx>, snapshot: &infer::CombinedSnapshot) - -> (Normalized<'tcx, &'tcx Substs<'tcx>>, infer::SkolemizationMap) + -> (Normalized<'tcx, &'tcx Substs<'tcx>>, + infer::SkolemizationMap<'tcx>) { match self.match_impl(impl_def_id, obligation, snapshot) { Ok((substs, skol_map)) => (substs, skol_map), @@ -2682,7 +2678,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &TraitObligation<'tcx>, snapshot: &infer::CombinedSnapshot) -> Result<(Normalized<'tcx, &'tcx Substs<'tcx>>, - infer::SkolemizationMap), ()> + infer::SkolemizationMap<'tcx>), ()> { let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); @@ -2753,9 +2749,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // substitution if we find that any of the input types, when // simplified, do not match. - obligation.predicate.0.input_types().iter() + obligation.predicate.skip_binder().input_types() .zip(impl_trait_ref.input_types()) - .any(|(&obligation_ty, &impl_ty)| { + .any(|(obligation_ty, impl_ty)| { let simplified_obligation_ty = fast_reject::simplify_type(self.tcx(), obligation_ty, true); let simplified_impl_ty = @@ -2875,7 +2871,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { recursion_depth: usize, def_id: DefId, // of impl or trait substs: &Substs<'tcx>, // for impl or trait - skol_map: infer::SkolemizationMap, + skol_map: infer::SkolemizationMap<'tcx>, snapshot: &infer::CombinedSnapshot) -> Vec> { diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 1954ce1993c5e..038de25312d35 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -386,7 +386,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { Ok(def_id) => { Ok(ty::TraitRef { def_id: def_id, - substs: Substs::new_trait(self, vec![], vec![], param_ty) + substs: Substs::new_trait(self, param_ty, &[]) }) } Err(e) => { @@ -401,12 +401,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { trait_def_id: DefId, recursion_depth: usize, param_ty: Ty<'tcx>, - ty_params: Vec>) + ty_params: &[Ty<'tcx>]) -> PredicateObligation<'tcx> { let trait_ref = ty::TraitRef { def_id: trait_def_id, - substs: Substs::new_trait(self, ty_params, vec![], param_ty) + substs: Substs::new_trait(self, param_ty, ty_params) }; predicate_for_trait_ref(cause, trait_ref, recursion_depth) } @@ -496,7 +496,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }; let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, - substs: Substs::new_trait(self, vec![arguments_tuple], vec![], self_ty), + substs: Substs::new_trait(self, self_ty, &[arguments_tuple]), }; ty::Binder((trait_ref, sig.0.output)) } diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs index 39dba57c47b7c..b1846e0394148 100644 --- a/src/librustc/ty/_match.rs +++ b/src/librustc/ty/_match.rs @@ -52,7 +52,8 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> { self.relate(a, b) } - fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> { + fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 3501dd4846087..e048e618e84d6 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -213,7 +213,7 @@ pub struct Tables<'tcx> { pub method_map: ty::MethodMap<'tcx>, /// Borrows - pub upvar_capture_map: ty::UpvarCaptureMap, + pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>, /// Records the type of each closure. The def ID is the ID of the /// expression defining the closure. @@ -1152,12 +1152,17 @@ fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool { impl_interners!('tcx, type_list: mk_type_list(Vec>, keep_local) -> [Ty<'tcx>], substs: mk_substs(Substs<'tcx>, |substs: &Substs| { - keep_local(&substs.types) || keep_local(&substs.regions) + substs.params().iter().any(keep_local) }) -> Substs<'tcx>, bare_fn: mk_bare_fn(BareFnTy<'tcx>, |fty: &BareFnTy| { keep_local(&fty.sig) }) -> BareFnTy<'tcx>, - region: mk_region(Region, keep_local) -> Region + region: mk_region(Region, |r| { + match r { + &ty::ReVar(_) | &ty::ReSkolemized(..) => true, + _ => false + } + }) -> Region ); impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 32c87fb615a53..3d60d326b2b0f 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -41,11 +41,11 @@ pub enum TypeError<'tcx> { FixedArraySize(ExpectedFound), TyParamSize(ExpectedFound), ArgCount, - RegionsDoesNotOutlive(Region, Region), - RegionsNotSame(Region, Region), - RegionsNoOverlap(Region, Region), - RegionsInsufficientlyPolymorphic(BoundRegion, Region), - RegionsOverlyPolymorphic(BoundRegion, Region), + RegionsDoesNotOutlive(&'tcx Region, &'tcx Region), + RegionsNotSame(&'tcx Region, &'tcx Region), + RegionsNoOverlap(&'tcx Region, &'tcx Region), + RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region), + RegionsOverlyPolymorphic(BoundRegion, &'tcx Region), Sorts(ExpectedFound>), IntegerAsChar, IntMismatch(ExpectedFound), @@ -296,7 +296,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.note_and_explain_region(db, "concrete lifetime that was found is ", conc_region, ""); } - RegionsOverlyPolymorphic(_, ty::ReVar(_)) => { + RegionsOverlyPolymorphic(_, &ty::ReVar(_)) => { // don't bother to print out the message below for // inference variables, it's not very illuminating. } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index c6c37296e9e12..1afd49ab47fbf 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -137,7 +137,7 @@ impl FlagComputation { } &ty::TyRef(r, ref m) => { - self.add_region(*r); + self.add_region(r); self.add_ty(m.ty); } @@ -176,8 +176,8 @@ impl FlagComputation { self.add_bound_computation(&computation); } - fn add_region(&mut self, r: ty::Region) { - match r { + fn add_region(&mut self, r: &ty::Region) { + match *r { ty::ReVar(..) => { self.add_flags(TypeFlags::HAS_RE_INFER); self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX); @@ -208,8 +208,11 @@ impl FlagComputation { } fn add_substs(&mut self, substs: &Substs) { - self.add_tys(&substs.types); - for &r in &substs.regions { + for ty in substs.types() { + self.add_ty(ty); + } + + for r in substs.regions() { self.add_region(r); } } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 2e114a801d6ed..2c18d1d52547f 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -169,7 +169,7 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized { fty.super_fold_with(self) } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { r.super_fold_with(self) } @@ -188,7 +188,7 @@ pub trait TypeVisitor<'tcx> : Sized { t.super_visit_with(self) } - fn visit_region(&mut self, r: ty::Region) -> bool { + fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { r.super_visit_with(self) } } @@ -222,13 +222,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// whether any late-bound regions were skipped pub fn collect_regions(self, value: &T, - region_set: &mut FnvHashSet) + region_set: &mut FnvHashSet<&'tcx ty::Region>) -> bool where T : TypeFoldable<'tcx> { let mut have_bound_regions = false; - self.fold_regions(value, &mut have_bound_regions, - |r, d| { region_set.insert(r.from_depth(d)); r }); + self.fold_regions(value, &mut have_bound_regions, |r, d| { + region_set.insert(self.mk_region(r.from_depth(d))); + r + }); have_bound_regions } @@ -240,7 +242,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { skipped_regions: &mut bool, mut f: F) -> T - where F : FnMut(ty::Region, u32) -> ty::Region, + where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region, T : TypeFoldable<'tcx>, { value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) @@ -260,14 +262,14 @@ pub struct RegionFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, skipped_regions: &'a mut bool, current_depth: u32, - fld_r: &'a mut (FnMut(ty::Region, u32) -> ty::Region + 'a), + fld_r: &'a mut (FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region + 'a), } impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, skipped_regions: &'a mut bool, fld_r: &'a mut F) -> RegionFolder<'a, 'gcx, 'tcx> - where F : FnMut(ty::Region, u32) -> ty::Region + where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region { RegionFolder { tcx: tcx, @@ -288,8 +290,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> { t } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - match r { + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + match *r { ty::ReLateBound(debruijn, _) if debruijn.depth < self.current_depth => { debug!("RegionFolder.fold_region({:?}) skipped bound region (current depth={})", r, self.current_depth); @@ -313,16 +315,16 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> { struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, current_depth: u32, - fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region + 'a), - map: FnvHashMap + fld_r: &'a mut (FnMut(ty::BoundRegion) -> &'tcx ty::Region + 'a), + map: FnvHashMap } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn replace_late_bound_regions(self, value: &Binder, mut f: F) - -> (T, FnvHashMap) - where F : FnMut(ty::BoundRegion) -> ty::Region, + -> (T, FnvHashMap) + where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region, T : TypeFoldable<'tcx>, { let mut replacer = RegionReplacer::new(self, &mut f); @@ -340,7 +342,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { where T : TypeFoldable<'tcx> { self.replace_late_bound_regions(value, |br| { - ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br}) + self.mk_region(ty::ReFree(ty::FreeRegion { + scope: all_outlive_scope, + bound_region: br + })) }).0 } @@ -353,11 +358,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let bound0_value = bound2_value.skip_binder().skip_binder(); let value = self.fold_regions(bound0_value, &mut false, |region, current_depth| { - match region { + match *region { ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => { // should be true if no escaping regions from bound2_value assert!(debruijn.depth - current_depth <= 1); - ty::ReLateBound(ty::DebruijnIndex::new(current_depth), br) + self.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(current_depth), br)) } _ => { region @@ -411,7 +416,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn erase_late_bound_regions(self, value: &Binder) -> T where T : TypeFoldable<'tcx> { - self.replace_late_bound_regions(value, |_| ty::ReErased).0 + self.replace_late_bound_regions(value, |_| self.mk_region(ty::ReErased)).0 } /// Rewrite any late-bound regions so that they are anonymous. Region numbers are @@ -428,7 +433,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let mut counter = 0; Binder(self.replace_late_bound_regions(sig, |_| { counter += 1; - ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(counter)) + self.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(counter))) }).0) } } @@ -436,7 +441,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> { fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, fld_r: &'a mut F) -> RegionReplacer<'a, 'gcx, 'tcx> - where F : FnMut(ty::BoundRegion) -> ty::Region + where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region { RegionReplacer { tcx: tcx, @@ -465,22 +470,22 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> { t.super_fold_with(self) } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - match r { + fn fold_region(&mut self, r:&'tcx ty::Region) -> &'tcx ty::Region { + match *r { ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => { let fld_r = &mut self.fld_r; let region = *self.map.entry(br).or_insert_with(|| fld_r(br)); - if let ty::ReLateBound(debruijn1, br) = region { + if let ty::ReLateBound(debruijn1, br) = *region { // If the callback returns a late-bound region, // that region should always use depth 1. Then we // adjust it to the correct depth. assert_eq!(debruijn1.depth, 1); - ty::ReLateBound(debruijn, br) + self.tcx.mk_region(ty::ReLateBound(debruijn, br)) } else { region } } - r => r + _ => r } } } @@ -528,7 +533,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { u.super_fold_with(self) } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { // because late-bound regions affect subtyping, we can't // erase the bound/free distinction, but we can replace // all free regions with 'erased. @@ -537,9 +542,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // type system never "sees" those, they get substituted // away. In trans, they will always be erased to 'erased // whenever a substitution occurs. - match r { + match *r { ty::ReLateBound(..) => r, - _ => ty::ReErased + _ => self.tcx().mk_region(ty::ReErased) } } } @@ -574,7 +579,7 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>, value, amount); value.fold_with(&mut RegionFolder::new(tcx, &mut false, &mut |region, _current_depth| { - shift_region(region, amount) + tcx.mk_region(shift_region(*region, amount)) })) } @@ -616,7 +621,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor { t.region_depth > self.depth } - fn visit_region(&mut self, r: ty::Region) -> bool { + fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { r.escapes_depth(self.depth) } } @@ -630,17 +635,18 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { t.flags.get().intersects(self.flags) } - fn visit_region(&mut self, r: ty::Region) -> bool { + fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { if self.flags.intersects(ty::TypeFlags::HAS_LOCAL_NAMES) { // does this represent a region that cannot be named // in a global way? used in fulfillment caching. - match r { + match *r { ty::ReStatic | ty::ReEmpty | ty::ReErased => {} _ => return true, } } - if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER) { - match r { + if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER | + ty::TypeFlags::KEEP_IN_LOCAL_TCX) { + match *r { ty::ReVar(_) | ty::ReSkolemized(..) => { return true } _ => {} } @@ -688,8 +694,8 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { t.super_visit_with(self) } - fn visit_region(&mut self, r: ty::Region) -> bool { - match r { + fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + match *r { ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => { self.regions.insert(br); } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 1dcc623d36558..62bd30e255592 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -264,7 +264,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match self_ty.sty { ty::TyStruct(adt_def, substs) | ty::TyEnum(adt_def, substs) => { - if substs.types.is_empty() { // ignore regions + if substs.types().next().is_none() { // ignore regions self.push_item_path(buffer, adt_def.did); } else { buffer.push(&format!("<{}>", self_ty)); diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index d5686906e6a7b..0e8bea86178f3 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -38,7 +38,7 @@ dep_map_ty! { TraitItemDefIds: TraitItemDefIds(DefId) -> Rc Option> } dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef<'tcx> } dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> } -dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc } +dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc> } dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Rc> } dep_map_ty! { ImplItems: ImplItems(DefId) -> Vec } dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc>> } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 6c82157c8ca7c..759dc30037210 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -343,7 +343,7 @@ pub struct Method<'tcx> { pub generics: &'tcx Generics<'tcx>, pub predicates: GenericPredicates<'tcx>, pub fty: &'tcx BareFnTy<'tcx>, - pub explicit_self: ExplicitSelfCategory, + pub explicit_self: ExplicitSelfCategory<'tcx>, pub vis: Visibility, pub defaultness: hir::Defaultness, pub def_id: DefId, @@ -355,7 +355,7 @@ impl<'tcx> Method<'tcx> { generics: &'tcx ty::Generics<'tcx>, predicates: GenericPredicates<'tcx>, fty: &'tcx BareFnTy<'tcx>, - explicit_self: ExplicitSelfCategory, + explicit_self: ExplicitSelfCategory<'tcx>, vis: Visibility, defaultness: hir::Defaultness, def_id: DefId, @@ -417,21 +417,6 @@ pub struct AssociatedType<'tcx> { pub container: ImplOrTraitItemContainer, } -#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)] -pub struct ItemVariances { - pub types: Vec, - pub regions: Vec, -} - -impl ItemVariances { - pub fn empty() -> ItemVariances { - ItemVariances { - types: vec![], - regions: vec![], - } - } -} - #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)] pub enum Variance { Covariant, // T <: T iff A <: B -- e.g., function return type @@ -658,28 +643,28 @@ pub enum BorrowKind { /// Information describing the capture of an upvar. This is computed /// during `typeck`, specifically by `regionck`. #[derive(PartialEq, Clone, Debug, Copy)] -pub enum UpvarCapture { +pub enum UpvarCapture<'tcx> { /// Upvar is captured by value. This is always true when the /// closure is labeled `move`, but can also be true in other cases /// depending on inference. ByValue, /// Upvar is captured by reference. - ByRef(UpvarBorrow), + ByRef(UpvarBorrow<'tcx>), } #[derive(PartialEq, Clone, Copy)] -pub struct UpvarBorrow { +pub struct UpvarBorrow<'tcx> { /// The kind of borrow: by-ref upvars have access to shared /// immutable borrows, which are not part of the normal language /// syntax. pub kind: BorrowKind, /// Region of the resulting reference. - pub region: ty::Region, + pub region: &'tcx ty::Region, } -pub type UpvarCaptureMap = FnvHashMap; +pub type UpvarCaptureMap<'tcx> = FnvHashMap>; #[derive(Copy, Clone)] pub struct ClosureUpvar<'tcx> { @@ -700,7 +685,7 @@ pub enum IntVarValue { /// this is `None`, then the default is inherited from the /// surrounding context. See RFC #599 for details. #[derive(Copy, Clone)] -pub enum ObjectLifetimeDefault { +pub enum ObjectLifetimeDefault<'tcx> { /// Require an explicit annotation. Occurs when multiple /// `T:'a` constraints are found. Ambiguous, @@ -709,7 +694,7 @@ pub enum ObjectLifetimeDefault { BaseDefault, /// Use the given region as the default. - Specific(Region), + Specific(&'tcx Region), } #[derive(Clone)] @@ -719,18 +704,18 @@ pub struct TypeParameterDef<'tcx> { pub index: u32, pub default_def_id: DefId, // for use in error reporing about defaults pub default: Option>, - pub object_lifetime_default: ObjectLifetimeDefault, + pub object_lifetime_default: ObjectLifetimeDefault<'tcx>, } #[derive(Clone)] -pub struct RegionParameterDef { +pub struct RegionParameterDef<'tcx> { pub name: Name, pub def_id: DefId, pub index: u32, - pub bounds: Vec, + pub bounds: Vec<&'tcx ty::Region>, } -impl RegionParameterDef { +impl<'tcx> RegionParameterDef<'tcx> { pub fn to_early_bound_region(&self) -> ty::Region { ty::ReEarlyBound(ty::EarlyBoundRegion { index: self.index, @@ -750,11 +735,25 @@ pub struct Generics<'tcx> { pub parent: Option, pub parent_regions: u32, pub parent_types: u32, - pub regions: Vec, + pub regions: Vec>, pub types: Vec>, pub has_self: bool, } +impl<'tcx> Generics<'tcx> { + pub fn parent_count(&self) -> usize { + self.parent_regions as usize + self.parent_types as usize + } + + pub fn own_count(&self) -> usize { + self.regions.len() + self.types.len() + } + + pub fn count(&self) -> usize { + self.parent_count() + self.own_count() + } +} + /// Bounds on generics. #[derive(Clone)] pub struct GenericPredicates<'tcx> { @@ -812,7 +811,7 @@ pub enum Predicate<'tcx> { Equate(PolyEquatePredicate<'tcx>), /// where 'a : 'b - RegionOutlives(PolyRegionOutlivesPredicate), + RegionOutlives(PolyRegionOutlivesPredicate<'tcx>), /// where T : 'a TypeOutlives(PolyTypeOutlivesPredicate<'tcx>), @@ -951,7 +950,6 @@ impl<'tcx> TraitPredicate<'tcx> { // leads to more recompilation. let def_ids: Vec<_> = self.input_types() - .iter() .flat_map(|t| t.walk()) .filter_map(|t| match t.sty { ty::TyStruct(adt_def, _) | @@ -964,8 +962,8 @@ impl<'tcx> TraitPredicate<'tcx> { DepNode::TraitSelect(self.def_id(), def_ids) } - pub fn input_types(&self) -> &[Ty<'tcx>] { - &self.trait_ref.substs.types + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { + self.trait_ref.input_types() } pub fn self_ty(&self) -> Ty<'tcx> { @@ -992,8 +990,9 @@ pub type PolyEquatePredicate<'tcx> = ty::Binder>; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct OutlivesPredicate(pub A, pub B); // `A : B` pub type PolyOutlivesPredicate = ty::Binder>; -pub type PolyRegionOutlivesPredicate = PolyOutlivesPredicate; -pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate, ty::Region>; +pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region, + &'tcx ty::Region>; +pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate, &'tcx ty::Region>; /// This kind of predicate has no *direct* correspondent in the /// syntax, but it roughly corresponds to the syntactic forms: @@ -1082,7 +1081,7 @@ impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> { } } -impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate { +impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { fn to_predicate(&self) -> Predicate<'tcx> { Predicate::RegionOutlives(self.clone()) } @@ -1107,7 +1106,7 @@ impl<'tcx> Predicate<'tcx> { pub fn walk_tys(&self) -> IntoIter> { let vec: Vec<_> = match *self { ty::Predicate::Trait(ref data) => { - data.0.trait_ref.input_types().to_vec() + data.skip_binder().input_types().collect() } ty::Predicate::Rfc1592(ref data) => { return data.walk_tys() @@ -1123,10 +1122,7 @@ impl<'tcx> Predicate<'tcx> { } ty::Predicate::Projection(ref data) => { let trait_inputs = data.0.projection_ty.trait_ref.input_types(); - trait_inputs.iter() - .cloned() - .chain(Some(data.0.ty)) - .collect() + trait_inputs.chain(Some(data.0.ty)).collect() } ty::Predicate::WellFormed(data) => { vec![data] @@ -1206,15 +1202,15 @@ impl<'tcx> TraitRef<'tcx> { } pub fn self_ty(&self) -> Ty<'tcx> { - self.substs.types[0] + self.substs.type_at(0) } - pub fn input_types(&self) -> &[Ty<'tcx>] { + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { // Select only the "input types" from a trait-reference. For // now this is all the types that appear in the // trait-reference, but it should eventually exclude // associated types. - &self.substs.types + self.substs.types() } } @@ -1239,7 +1235,7 @@ pub struct ParameterEnvironment<'tcx> { /// indicates it must outlive at least the function body (the user /// may specify stronger requirements). This field indicates the /// region of the callee. - pub implicit_region_bound: ty::Region, + pub implicit_region_bound: &'tcx ty::Region, /// Obligations that the caller must satisfy. This is basically /// the set of bounds on the in-scope type parameters, translated @@ -1866,7 +1862,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> { }; let sized_predicate = Binder(TraitRef { def_id: sized_trait, - substs: Substs::new_trait(tcx, vec![], vec![], ty) + substs: Substs::new_trait(tcx, ty, &[]) }).to_predicate(); let predicates = tcx.lookup_predicates(self.did).predicates; if predicates.into_iter().any(|p| p == sized_predicate) { @@ -2593,7 +2589,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { || self.lookup_repr_hints(did).contains(&attr::ReprSimd) } - pub fn item_variances(self, item_id: DefId) -> Rc { + pub fn item_variances(self, item_id: DefId) -> Rc> { lookup_locally_or_in_crate_store( "item_variance_map", item_id, &self.item_variance_map, || Rc::new(self.sess.cstore.item_variances(item_id))) @@ -2827,7 +2823,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::ParameterEnvironment { free_substs: Substs::empty(self), caller_bounds: Vec::new(), - implicit_region_bound: ty::ReEmpty, + implicit_region_bound: self.mk_region(ty::ReEmpty), free_id_outlive: free_id_outlive } } @@ -2843,8 +2839,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| { // map bound 'a => free 'a - ReFree(FreeRegion { scope: free_id_outlive, - bound_region: def.to_bound_region() }) + self.global_tcx().mk_region(ReFree(FreeRegion { + scope: free_id_outlive, + bound_region: def.to_bound_region() + })) }, |def, _| { // map T => T self.global_tcx().mk_param_from_def(def) @@ -2894,7 +2892,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let unnormalized_env = ty::ParameterEnvironment { free_substs: free_substs, - implicit_region_bound: ty::ReScope(free_id_outlive), + implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)), caller_bounds: predicates, free_id_outlive: free_id_outlive, }; @@ -2903,6 +2901,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { traits::normalize_param_env_or_error(tcx, unnormalized_env, cause) } + pub fn node_scope_region(self, id: NodeId) -> &'tcx Region { + self.mk_region(ty::ReScope(self.region_maps.node_extent(id))) + } + pub fn is_method_call(self, expr_id: NodeId) -> bool { self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id)) } @@ -2912,7 +2914,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { autoderefs)) } - pub fn upvar_capture(self, upvar_id: ty::UpvarId) -> Option { + pub fn upvar_capture(self, upvar_id: ty::UpvarId) -> Option> { Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone()) } @@ -2938,10 +2940,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// The category of explicit self. #[derive(Clone, Copy, Eq, PartialEq, Debug)] -pub enum ExplicitSelfCategory { +pub enum ExplicitSelfCategory<'tcx> { Static, ByValue, - ByReference(Region, hir::Mutability), + ByReference(&'tcx Region, hir::Mutability), ByBox, } diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index ee431681ad100..4d5b38212f600 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -17,7 +17,7 @@ use ty::{self, Ty, TypeFoldable}; #[derive(Debug)] pub enum Component<'tcx> { - Region(ty::Region), + Region(&'tcx ty::Region), Param(ty::ParamTy), UnresolvedInferenceVariable(ty::InferTy), @@ -210,7 +210,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } -fn push_region_constraints<'tcx>(out: &mut Vec>, regions: Vec) { +fn push_region_constraints<'tcx>(out: &mut Vec>, regions: Vec<&'tcx ty::Region>) { for r in regions { if !r.is_bound() { out.push(Component::Region(r)); diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 8975a799be143..5c157ff32e7bb 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -14,7 +14,7 @@ //! type equality, etc. use hir::def_id::DefId; -use ty::subst::Substs; +use ty::subst::{Kind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; use std::rc::Rc; @@ -71,8 +71,8 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>>; - fn regions(&mut self, a: ty::Region, b: ty::Region) - -> RelateResult<'tcx, ty::Region>; + fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region>; fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) -> RelateResult<'tcx, ty::Binder> @@ -139,7 +139,7 @@ fn relate_item_substs<'a, 'gcx, 'tcx, R>(relation: &mut R, } pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R, - variances: Option<&ty::ItemVariances>, + variances: Option<&Vec>, a_subst: &'tcx Substs<'tcx>, b_subst: &'tcx Substs<'tcx>) -> RelateResult<'tcx, &'tcx Substs<'tcx>> @@ -147,19 +147,18 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R, { let tcx = relation.tcx(); - let types = a_subst.types.iter().enumerate().map(|(i, a_ty)| { - let b_ty = &b_subst.types[i]; - let variance = variances.map_or(ty::Invariant, |v| v.types[i]); - relation.relate_with_variance(variance, a_ty, b_ty) - }).collect::>()?; - - let regions = a_subst.regions.iter().enumerate().map(|(i, a_r)| { - let b_r = &b_subst.regions[i]; - let variance = variances.map_or(ty::Invariant, |v| v.regions[i]); - relation.relate_with_variance(variance, a_r, b_r) - }).collect::>()?; + let params = a_subst.params().iter().zip(b_subst.params()).enumerate().map(|(i, (a, b))| { + let variance = variances.map_or(ty::Invariant, |v| v[i]); + if let (Some(a_ty), Some(b_ty)) = (a.as_type(), b.as_type()) { + Ok(Kind::from(relation.relate_with_variance(variance, &a_ty, &b_ty)?)) + } else if let (Some(a_r), Some(b_r)) = (a.as_region(), b.as_region()) { + Ok(Kind::from(relation.relate_with_variance(variance, &a_r, &b_r)?)) + } else { + bug!() + } + }); - Ok(Substs::new(tcx, types, regions)) + Substs::maybe_new(tcx, params) } impl<'tcx> Relate<'tcx> for &'tcx ty::BareFnTy<'tcx> { @@ -473,9 +472,9 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, (&ty::TyRef(a_r, ref a_mt), &ty::TyRef(b_r, ref b_mt)) => { - let r = relation.relate_with_variance(ty::Contravariant, a_r, b_r)?; + let r = relation.relate_with_variance(ty::Contravariant, &a_r, &b_r)?; let mt = relation.relate(a_mt, b_mt)?; - Ok(tcx.mk_ref(tcx.mk_region(r), mt)) + Ok(tcx.mk_ref(r, mt)) } (&ty::TyArray(a_t, sz_a), &ty::TyArray(b_t, sz_b)) => @@ -571,11 +570,11 @@ impl<'tcx> Relate<'tcx> for &'tcx Substs<'tcx> { } } -impl<'tcx> Relate<'tcx> for ty::Region { +impl<'tcx> Relate<'tcx> for &'tcx ty::Region { fn relate<'a, 'gcx, R>(relation: &mut R, - a: &ty::Region, - b: &ty::Region) - -> RelateResult<'tcx, ty::Region> + a: &&'tcx ty::Region, + b: &&'tcx ty::Region) + -> RelateResult<'tcx, &'tcx ty::Region> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { relation.regions(*a, *b) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index f7c4b9938c279..705cca056f24c 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -9,7 +9,6 @@ // except according to those terms. use infer::type_variable; -use ty::subst::Substs; use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; @@ -73,13 +72,6 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec { } } -impl<'tcx> Lift<'tcx> for ty::Region { - type Lifted = Self; - fn lift_to_tcx(&self, _: TyCtxt) -> Option { - Some(*self) - } -} - impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> { type Lifted = ty::TraitRef<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { @@ -316,13 +308,21 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { FixedArraySize(x) => FixedArraySize(x), TyParamSize(x) => TyParamSize(x), ArgCount => ArgCount, - RegionsDoesNotOutlive(a, b) => RegionsDoesNotOutlive(a, b), - RegionsNotSame(a, b) => RegionsNotSame(a, b), - RegionsNoOverlap(a, b) => RegionsNoOverlap(a, b), + RegionsDoesNotOutlive(a, b) => { + return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)) + } + RegionsNotSame(a, b) => { + return tcx.lift(&(a, b)).map(|(a, b)| RegionsNotSame(a, b)) + } + RegionsNoOverlap(a, b) => { + return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b)) + } RegionsInsufficientlyPolymorphic(a, b) => { - RegionsInsufficientlyPolymorphic(a, b) + return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b)) + } + RegionsOverlyPolymorphic(a, b) => { + return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b)) } - RegionsOverlyPolymorphic(a, b) => RegionsOverlyPolymorphic(a, b), IntegerAsChar => IntegerAsChar, IntMismatch(x) => IntMismatch(x), FloatMismatch(x) => FloatMismatch(x), @@ -655,7 +655,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::Region { +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { *self } @@ -673,41 +673,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { - *self - } - - fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - let region = folder.fold_region(**self); - folder.tcx().mk_region(region) - } - - fn super_visit_with>(&self, _visitor: &mut V) -> bool { - false - } - - fn visit_with>(&self, visitor: &mut V) -> bool { - visitor.visit_region(**self) - } -} - -impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - let types = self.types.fold_with(folder); - let regions = self.regions.fold_with(folder); - Substs::new(folder.tcx(), types, regions) - } - - fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - folder.fold_substs(self) - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.types.visit_with(visitor) || self.regions.visit_with(visitor) - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { ty::ClosureSubsts { @@ -783,7 +748,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault { +impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match *self { ty::ObjectLifetimeDefault::Ambiguous => @@ -805,7 +770,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault { } } -impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef { +impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { ty::RegionParameterDef { name: self.name, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 8aa81cc4743c9..0e3f18c4474ea 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -19,8 +19,8 @@ use util::common::ErrorReported; use collections::enum_set::{self, EnumSet, CLike}; use std::fmt; -use std::ops; use std::mem; +use std::ops; use syntax::abi; use syntax::ast::{self, Name}; use syntax::parse::token::keywords; @@ -293,7 +293,7 @@ impl<'tcx> Decodable for ClosureSubsts<'tcx> { #[derive(Clone, PartialEq, Eq, Hash)] pub struct TraitObject<'tcx> { pub principal: PolyExistentialTraitRef<'tcx>, - pub region_bound: ty::Region, + pub region_bound: &'tcx ty::Region, pub builtin_bounds: BuiltinBounds, pub projection_bounds: Vec>, } @@ -335,7 +335,7 @@ impl<'tcx> PolyTraitRef<'tcx> { self.0.substs } - pub fn input_types(&self) -> &[Ty<'tcx>] { + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<> self.0.input_types() } @@ -360,12 +360,12 @@ pub struct ExistentialTraitRef<'tcx> { } impl<'tcx> ExistentialTraitRef<'tcx> { - pub fn input_types(&self) -> &[Ty<'tcx>] { + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { // Select only the "input types" from a trait-reference. For // now this is all the types that appear in the // trait-reference, but it should eventually exclude // associated types. - &self.substs.types + self.substs.types() } } @@ -376,7 +376,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { self.0.def_id } - pub fn input_types(&self) -> &[Ty<'tcx>] { + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { // FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<> self.0.input_types() } @@ -675,6 +675,15 @@ pub enum Region { ReErased, } +impl<'tcx> Decodable for &'tcx Region { + fn decode(d: &mut D) -> Result<&'tcx Region, D::Error> { + let r = Decodable::decode(d)?; + cstore::tls::with_decoding_context(d, |dcx, _| { + Ok(dcx.tcx().mk_region(r)) + }) + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub struct EarlyBoundRegion { pub index: u32, @@ -1206,26 +1215,26 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { /// Returns the regions directly referenced from this type (but /// not types reachable from this type via `walk_tys`). This /// ignores late-bound regions binders. - pub fn regions(&self) -> Vec { + pub fn regions(&self) -> Vec<&'tcx ty::Region> { match self.sty { TyRef(region, _) => { - vec![*region] + vec![region] } TyTrait(ref obj) => { let mut v = vec![obj.region_bound]; - v.extend_from_slice(&obj.principal.skip_binder().substs.regions); + v.extend(obj.principal.skip_binder().substs.regions()); v } TyEnum(_, substs) | TyStruct(_, substs) | TyAnon(_, substs) => { - substs.regions.to_vec() + substs.regions().collect() } TyClosure(_, ref substs) => { - substs.func_substs.regions.to_vec() + substs.func_substs.regions().collect() } TyProjection(ref data) => { - data.trait_ref.substs.regions.to_vec() + data.trait_ref.substs.regions().collect() } TyFnDef(..) | TyFnPtr(_) | diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index e1a19a7b7992e..0ccfea2330999 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -13,41 +13,156 @@ use middle::cstore; use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder}; +use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use serialize::{Encodable, Encoder, Decodable, Decoder}; use syntax_pos::{Span, DUMMY_SP}; -/////////////////////////////////////////////////////////////////////////// +use core::nonzero::NonZero; +use std::fmt; +use std::iter; +use std::marker::PhantomData; +use std::mem; + +/// An entity in the Rust typesystem, which can be one of +/// several kinds (only types and lifetimes for now). +/// To reduce memory usage, a `Kind` is a interned pointer, +/// with the lowest 2 bits being reserved for a tag to +/// indicate the type (`Ty` or `Region`) it points to. +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct Kind<'tcx> { + ptr: NonZero, + marker: PhantomData<(Ty<'tcx>, &'tcx ty::Region)> +} + +const TAG_MASK: usize = 0b11; +const TYPE_TAG: usize = 0b00; +const REGION_TAG: usize = 0b01; + +impl<'tcx> From> for Kind<'tcx> { + fn from(ty: Ty<'tcx>) -> Kind<'tcx> { + // Ensure we can use the tag bits. + assert_eq!(mem::align_of_val(ty) & TAG_MASK, 0); + + let ptr = ty as *const _ as usize; + Kind { + ptr: unsafe { + NonZero::new(ptr | TYPE_TAG) + }, + marker: PhantomData + } + } +} + +impl<'tcx> From<&'tcx ty::Region> for Kind<'tcx> { + fn from(r: &'tcx ty::Region) -> Kind<'tcx> { + // Ensure we can use the tag bits. + assert_eq!(mem::align_of_val(r) & TAG_MASK, 0); + + let ptr = r as *const _ as usize; + Kind { + ptr: unsafe { + NonZero::new(ptr | REGION_TAG) + }, + marker: PhantomData + } + } +} + +impl<'tcx> Kind<'tcx> { + #[inline] + unsafe fn downcast(self, tag: usize) -> Option<&'tcx T> { + let ptr = *self.ptr; + if ptr & TAG_MASK == tag { + Some(&*((ptr & !TAG_MASK) as *const _)) + } else { + None + } + } + + #[inline] + pub fn as_type(self) -> Option> { + unsafe { + self.downcast(TYPE_TAG) + } + } + + #[inline] + pub fn as_region(self) -> Option<&'tcx ty::Region> { + unsafe { + self.downcast(REGION_TAG) + } + } +} + +impl<'tcx> fmt::Debug for Kind<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(ty) = self.as_type() { + write!(f, "{:?}", ty) + } else if let Some(r) = self.as_region() { + write!(f, "{:?}", r) + } else { + write!(f, "", *self.ptr as *const ()) + } + } +} + +impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + if let Some(ty) = self.as_type() { + Kind::from(ty.fold_with(folder)) + } else if let Some(r) = self.as_region() { + Kind::from(r.fold_with(folder)) + } else { + bug!() + } + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + if let Some(ty) = self.as_type() { + ty.visit_with(visitor) + } else if let Some(r) = self.as_region() { + r.visit_with(visitor) + } else { + bug!() + } + } +} /// A substitution mapping type/region parameters to new values. -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Substs<'tcx> { - pub types: Vec>, - pub regions: Vec, + params: Vec> } impl<'a, 'gcx, 'tcx> Substs<'tcx> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, - t: Vec>, - r: Vec) - -> &'tcx Substs<'tcx> - { - tcx.mk_substs(Substs { types: t, regions: r }) + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I) + -> &'tcx Substs<'tcx> + where I: IntoIterator> { + tcx.mk_substs(Substs { + params: params.into_iter().collect() + }) + } + + pub fn maybe_new(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I) + -> Result<&'tcx Substs<'tcx>, E> + where I: IntoIterator, E>> { + Ok(tcx.mk_substs(Substs { + params: params.into_iter().collect::>()? + })) } pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>, - mut t: Vec>, - r: Vec, - s: Ty<'tcx>) + s: Ty<'tcx>, + t: &[Ty<'tcx>]) -> &'tcx Substs<'tcx> { - t.insert(0, s); - Substs::new(tcx, t, r) + let t = iter::once(s).chain(t.iter().cloned()); + Substs::new(tcx, t.map(Kind::from)) } pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> { - Substs::new(tcx, vec![], vec![]) + Substs::new(tcx, vec![]) } /// Creates a Substs for generic parameter definitions, @@ -60,19 +175,16 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { mut mk_region: FR, mut mk_type: FT) -> &'tcx Substs<'tcx> - where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region, + where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> &'tcx ty::Region, FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> { let defs = tcx.lookup_generics(def_id); - let num_regions = defs.parent_regions as usize + defs.regions.len(); - let num_types = defs.parent_types as usize + defs.types.len(); let mut substs = Substs { - regions: Vec::with_capacity(num_regions), - types: Vec::with_capacity(num_types) + params: Vec::with_capacity(defs.count()) }; substs.fill_item(tcx, defs, &mut mk_region, &mut mk_type); - Substs::new(tcx, substs.types, substs.regions) + tcx.mk_substs(substs) } fn fill_item(&mut self, @@ -80,36 +192,76 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { defs: &ty::Generics<'tcx>, mk_region: &mut FR, mk_type: &mut FT) - where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region, + where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> &'tcx ty::Region, FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> { if let Some(def_id) = defs.parent { let parent_defs = tcx.lookup_generics(def_id); self.fill_item(tcx, parent_defs, mk_region, mk_type); } + // Handle Self first, before all regions. + let mut types = defs.types.iter(); + if defs.parent.is_none() && defs.has_self { + let def = types.next().unwrap(); + let ty = mk_type(def, self); + assert_eq!(def.index as usize, self.params.len()); + self.params.push(Kind::from(ty)); + } + for def in &defs.regions { let region = mk_region(def, self); - assert_eq!(def.index as usize, self.regions.len()); - self.regions.push(region); + assert_eq!(def.index as usize, self.params.len()); + self.params.push(Kind::from(region)); } - for def in &defs.types { + for def in types { let ty = mk_type(def, self); - assert_eq!(def.index as usize, self.types.len()); - self.types.push(ty); + assert_eq!(def.index as usize, self.params.len()); + self.params.push(Kind::from(ty)); } } pub fn is_noop(&self) -> bool { - self.regions.is_empty() && self.types.is_empty() + self.params.is_empty() + } + + #[inline] + pub fn params(&self) -> &[Kind<'tcx>] { + &self.params + } + + #[inline] + pub fn types(&'a self) -> impl DoubleEndedIterator> + 'a { + self.params.iter().filter_map(|k| k.as_type()) + } + + #[inline] + pub fn regions(&'a self) -> impl DoubleEndedIterator + 'a { + self.params.iter().filter_map(|k| k.as_region()) + } + + #[inline] + pub fn type_at(&self, i: usize) -> Ty<'tcx> { + self.params[i].as_type().unwrap_or_else(|| { + bug!("expected type for param #{} in {:?}", i, self.params); + }) } + #[inline] + pub fn region_at(&self, i: usize) -> &'tcx ty::Region { + self.params[i].as_region().unwrap_or_else(|| { + bug!("expected region for param #{} in {:?}", i, self.params); + }) + } + + #[inline] pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> { - self.types[ty_param_def.index as usize] + self.type_at(ty_param_def.index as usize) } - pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region { - self.regions[def.index as usize] + #[inline] + pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> &'tcx ty::Region { + self.region_at(def.index as usize) } /// Transform from substitutions for a child of `source_ancestor` @@ -122,11 +274,27 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { target_substs: &Substs<'tcx>) -> &'tcx Substs<'tcx> { let defs = tcx.lookup_generics(source_ancestor); - let regions = target_substs.regions.iter() - .chain(&self.regions[defs.regions.len()..]).cloned().collect(); - let types = target_substs.types.iter() - .chain(&self.types[defs.types.len()..]).cloned().collect(); - Substs::new(tcx, types, regions) + tcx.mk_substs(Substs { + params: target_substs.params.iter() + .chain(&self.params[defs.own_count()..]).cloned().collect() + }) + } +} + +impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + let params = self.params.iter().map(|k| k.fold_with(folder)).collect(); + folder.tcx().mk_substs(Substs { + params: params + }) + } + + fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + folder.fold_substs(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + self.params.visit_with(visitor) } } @@ -215,16 +383,18 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> { t } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { // Note: This routine only handles regions that are bound on // type declarations and other outer declarations, not those // bound in *fn types*. Region substitution of the bound // regions that appear in a function signature is done using // the specialized routine `ty::replace_late_regions()`. - match r { + match *r { ty::ReEarlyBound(data) => { - match self.substs.regions.get(data.index as usize) { - Some(&r) => { + let r = self.substs.params.get(data.index as usize) + .and_then(|k| k.as_region()); + match r { + Some(r) => { self.shift_region_through_binders(r) } None => { @@ -278,9 +448,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> { // Look up the type in the substitutions. It really should be in there. - let opt_ty = self.substs.types.get(p.idx as usize); + let opt_ty = self.substs.params.get(p.idx as usize) + .and_then(|k| k.as_type()); let ty = match opt_ty { - Some(t) => *t, + Some(t) => t, None => { let span = self.span.unwrap_or(DUMMY_SP); span_bug!( @@ -291,7 +462,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { source_ty, p.idx, self.root_ty, - self.substs); + self.substs.params); } }; @@ -354,8 +525,8 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { result } - fn shift_region_through_binders(&self, region: ty::Region) -> ty::Region { - ty::fold::shift_region(region, self.region_binders_passed) + fn shift_region_through_binders(&self, region: &'tcx ty::Region) -> &'tcx ty::Region { + self.tcx().mk_region(ty::fold::shift_region(*region, self.region_binders_passed)) } } @@ -367,12 +538,11 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> { substs: &Substs<'tcx>) -> ty::TraitRef<'tcx> { let defs = tcx.lookup_generics(trait_id); - let regions = substs.regions[..defs.regions.len()].to_vec(); - let types = substs.types[..defs.types.len()].to_vec(); + let params = substs.params[..defs.own_count()].iter().cloned(); ty::TraitRef { def_id: trait_id, - substs: Substs::new(tcx, types, regions) + substs: Substs::new(tcx, params) } } } @@ -381,13 +551,13 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> { pub fn erase_self_ty(tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_ref: ty::TraitRef<'tcx>) -> ty::ExistentialTraitRef<'tcx> { - let Substs { mut types, regions } = trait_ref.substs.clone(); - - types.remove(0); + // Assert there is a Self. + trait_ref.substs.type_at(0); + let params = trait_ref.substs.params[1..].iter().cloned(); ty::ExistentialTraitRef { def_id: trait_ref.def_id, - substs: Substs::new(tcx, types, regions) + substs: Substs::new(tcx, params) } } } @@ -404,13 +574,11 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> { assert!(!self_ty.has_escaping_regions()); self.map_bound(|trait_ref| { - let Substs { mut types, regions } = trait_ref.substs.clone(); - - types.insert(0, self_ty); - + let params = trait_ref.substs.params.iter().cloned(); + let params = iter::once(Kind::from(self_ty)).chain(params); ty::TraitRef { def_id: trait_ref.def_id, - substs: Substs::new(tcx, types, regions) + substs: Substs::new(tcx, params) } }) } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 51710c13a7dea..dd5c6a9758abf 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -306,7 +306,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn required_region_bounds(self, erased_self_ty: Ty<'tcx>, predicates: Vec>) - -> Vec { + -> Vec<&'tcx ty::Region> { debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})", erased_self_ty, predicates); @@ -496,8 +496,8 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> { ty.super_visit_with(self) } - fn visit_region(&mut self, r: ty::Region) -> bool { - match r { + fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + match *r { ty::ReStatic | ty::ReErased => { self.hash::(0); } @@ -693,10 +693,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { return false; } - let types_a = &substs_a.types; - let types_b = &substs_b.types; - - types_a.iter().zip(types_b).all(|(&a, &b)| same_type(a, b)) + substs_a.types().zip(substs_b.types()).all(|(a, b)| same_type(a, b)) } _ => { a == b diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 8a9ee45351dfc..409f5a85997bd 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -67,6 +67,12 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter> { stack.into_iter() } +// We push types on the stack in reverse order so as to +// maintain a pre-order traversal. As of the time of this +// writing, the fact that the traversal is pre-order is not +// known to be significant to any code, but it seems like the +// natural order one would expect (basically, the order of the +// types as they are written). fn push_subtypes<'tcx>(stack: &mut Vec>, parent_ty: Ty<'tcx>) { match parent_ty.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | @@ -79,28 +85,28 @@ fn push_subtypes<'tcx>(stack: &mut Vec>, parent_ty: Ty<'tcx>) { stack.push(mt.ty); } ty::TyProjection(ref data) => { - push_reversed(stack, &data.trait_ref.substs.types); + stack.extend(data.trait_ref.substs.types().rev()); } ty::TyTrait(ref obj) => { - push_reversed(stack, obj.principal.input_types()); - push_reversed(stack, &obj.projection_bounds.iter().map(|pred| { + stack.extend(obj.principal.input_types().rev()); + stack.extend(obj.projection_bounds.iter().map(|pred| { pred.0.ty - }).collect::>()); + }).rev()); } ty::TyEnum(_, ref substs) | ty::TyStruct(_, ref substs) | ty::TyAnon(_, ref substs) => { - push_reversed(stack, &substs.types); + stack.extend(substs.types().rev()); } ty::TyClosure(_, ref substs) => { - push_reversed(stack, &substs.func_substs.types); - push_reversed(stack, &substs.upvar_tys); + stack.extend(substs.func_substs.types().rev()); + stack.extend(substs.upvar_tys.iter().cloned().rev()); } - ty::TyTuple(ref ts) => { - push_reversed(stack, ts); + ty::TyTuple(ts) => { + stack.extend(ts.iter().cloned().rev()); } ty::TyFnDef(_, substs, ref ft) => { - push_reversed(stack, &substs.types); + stack.extend(substs.types().rev()); push_sig_subtypes(stack, &ft.sig); } ty::TyFnPtr(ref ft) => { @@ -111,17 +117,5 @@ fn push_subtypes<'tcx>(stack: &mut Vec>, parent_ty: Ty<'tcx>) { fn push_sig_subtypes<'tcx>(stack: &mut Vec>, sig: &ty::PolyFnSig<'tcx>) { stack.push(sig.0.output); - push_reversed(stack, &sig.0.inputs); -} - -fn push_reversed<'tcx>(stack: &mut Vec>, tys: &[Ty<'tcx>]) { - // We push slices on the stack in reverse order so as to - // maintain a pre-order traversal. As of the time of this - // writing, the fact that the traversal is pre-order is not - // known to be significant to any code, but it seems like the - // natural order one would expect (basically, the order of the - // types as they are written). - for &ty in tys.iter().rev() { - stack.push(ty); - } + stack.extend(sig.0.inputs.iter().cloned().rev()); } diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 54b19362b1d86..1f166cb192fa3 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -115,9 +115,9 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, /// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`. #[derive(Debug)] pub enum ImpliedBound<'tcx> { - RegionSubRegion(ty::Region, ty::Region), - RegionSubParam(ty::Region, ty::ParamTy), - RegionSubProjection(ty::Region, ty::ProjectionTy<'tcx>), + RegionSubRegion(&'tcx ty::Region, &'tcx ty::Region), + RegionSubParam(&'tcx ty::Region, ty::ParamTy), + RegionSubProjection(&'tcx ty::Region, ty::ProjectionTy<'tcx>), } /// Compute the implied bounds that a callee/impl can assume based on @@ -196,7 +196,7 @@ pub fn implied_bounds<'a, 'gcx, 'tcx>( /// this down to determine what relationships would have to hold for /// `T: 'a` to hold. We get to assume that the caller has validated /// those relationships. -fn implied_bounds_from_components<'tcx>(sub_region: ty::Region, +fn implied_bounds_from_components<'tcx>(sub_region: &'tcx ty::Region, sup_components: Vec>) -> Vec> { @@ -260,8 +260,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { let cause = self.cause(traits::MiscObligation); self.out.extend( - trait_ref.substs.types - .iter() + trait_ref.substs.types() .filter(|ty| !ty.has_escaping_regions()) .map(|ty| traits::Obligation::new(cause.clone(), ty::Predicate::WellFormed(ty)))); @@ -364,7 +363,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { cause, ty::Predicate::TypeOutlives( ty::Binder( - ty::OutlivesPredicate(mt.ty, *r))))); + ty::OutlivesPredicate(mt.ty, r))))); } } @@ -535,7 +534,7 @@ pub fn object_region_bounds<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, principal: ty::PolyExistentialTraitRef<'tcx>, others: ty::BuiltinBounds) - -> Vec + -> Vec<&'tcx ty::Region> { // Since we don't actually *know* the self type for an object, // this "open(err)" serves as a kind of dummy standin -- basically diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 02ad8fb7033ed..24b68c66e4667 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -22,6 +22,8 @@ use ty::fold::{TypeFolder, TypeVisitor}; use std::cell::Cell; use std::fmt; +use std::usize; + use syntax::abi::Abi; use syntax::parse::token; use syntax::ast::CRATE_NODE_ID; @@ -80,15 +82,17 @@ pub fn parameterized(f: &mut fmt::Formatter, verbose = tcx.sess.verbose(); has_self = generics.has_self; + let mut child_types = 0; if let Some(def_id) = generics.parent { // Methods. assert_eq!(ns, Ns::Value); + child_types = generics.types.len(); generics = tcx.lookup_generics(def_id); num_regions = generics.regions.len(); num_types = generics.types.len(); if has_self { - write!(f, "<{} as ", substs.types[0])?; + write!(f, "<{} as ", substs.type_at(0))?; } item_name = Some(tcx.item_name(did)); @@ -107,8 +111,8 @@ pub fn parameterized(f: &mut fmt::Formatter, if !verbose { if generics.types.last().map_or(false, |def| def.default.is_some()) { if let Some(substs) = tcx.lift(&substs) { - let tps = &substs.types[..num_types]; - for (def, actual) in generics.types.iter().zip(tps).rev() { + 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) { break; } @@ -124,7 +128,7 @@ pub fn parameterized(f: &mut fmt::Formatter, if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { let projection_ty = projections[0].ty; - if let TyTuple(ref args) = substs.types[1].sty { + if let TyTuple(ref args) = substs.type_at(1).sty { return fn_sig(f, args, false, projection_ty); } } @@ -139,13 +143,15 @@ pub fn parameterized(f: &mut fmt::Formatter, } }; - let print_regions = |f: &mut fmt::Formatter, start: &str, regions: &[ty::Region]| { + let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| { // Don't print any regions if they're all erased. - if regions.iter().all(|r| *r == ty::ReErased) { + let regions = || substs.regions().skip(skip).take(count); + if regions().all(|r: &ty::Region| *r == ty::ReErased) { return Ok(()); } - for region in regions { + for region in regions() { + let region: &ty::Region = region; start_or_continue(f, start, ", ")?; if verbose { write!(f, "{:?}", region)?; @@ -167,11 +173,12 @@ pub fn parameterized(f: &mut fmt::Formatter, Ok(()) }; - print_regions(f, "<", &substs.regions[..num_regions])?; + print_regions(f, "<", 0, num_regions)?; - let tps = &substs.types[..num_types]; + let tps = substs.types().take(num_types - num_supplied_defaults) + .skip(has_self as usize); - for &ty in &tps[has_self as usize..tps.len() - num_supplied_defaults] { + for ty in tps { start_or_continue(f, "<", ", ")?; write!(f, "{}", ty)?; } @@ -197,10 +204,10 @@ pub fn parameterized(f: &mut fmt::Formatter, write!(f, "::{}", item_name)?; } - print_regions(f, "::<", &substs.regions[num_regions..])?; + print_regions(f, "::<", num_regions, usize::MAX)?; // FIXME: consider being smart with defaults here too - for ty in &substs.types[num_types..] { + for ty in substs.types().skip(num_types) { start_or_continue(f, "::<", ", ")?; write!(f, "{}", ty)?; } @@ -240,7 +247,7 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter, let new_value = tcx.replace_late_bound_regions(&value, |br| { let _ = start_or_continue(f, "for<", ", "); - ty::ReLateBound(ty::DebruijnIndex::new(1), match br { + let br = match br { ty::BrNamed(_, name, _) => { let _ = write!(f, "{}", name); br @@ -254,7 +261,8 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter, name, ty::Issue32330::WontChange) } - }) + }; + tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), br)) }).0; start_or_continue(f, "", "> ")?; @@ -344,7 +352,7 @@ impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> { } } -impl fmt::Debug for ty::RegionParameterDef { +impl<'tcx> fmt::Debug for ty::RegionParameterDef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "RegionParameterDef({}, {:?}, {}, {:?})", self.name, @@ -368,13 +376,6 @@ impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> { } } -impl<'tcx> fmt::Debug for Substs<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Substs[types={:?}, regions={:?}]", - self.types, self.regions) - } -} - impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ItemSubsts({:?})", self.substs) @@ -598,7 +599,7 @@ impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> { } } -impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault { +impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"), @@ -654,13 +655,6 @@ impl fmt::Debug for ty::Variance { } } -impl fmt::Debug for ty::ItemVariances { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ItemVariances(types={:?}, regions={:?})", - self.types, self.regions) - } -} - impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "GenericPredicates({:?})", self.predicates) @@ -793,13 +787,14 @@ impl<'tcx> fmt::Display for ty::Binder> { } } -impl<'tcx> fmt::Display for ty::Binder, ty::Region>> { +impl<'tcx> fmt::Display for ty::Binder, &'tcx ty::Region>> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) } } -impl fmt::Display for ty::Binder> { +impl<'tcx> fmt::Display for ty::Binder> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) } @@ -973,7 +968,7 @@ impl fmt::Debug for ty::UpvarId { } } -impl fmt::Debug for ty::UpvarBorrow { +impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "UpvarBorrow({:?}, {:?})", self.kind, self.region) @@ -997,7 +992,7 @@ impl fmt::Display for ty::InferTy { } } -impl fmt::Display for ty::ExplicitSelfCategory { +impl<'tcx> fmt::Display for ty::ExplicitSelfCategory<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match *self { ty::ExplicitSelfCategory::Static => "static", diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index c1f162e5772bf..e86fa9a05f372 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { borrow_id: ast::NodeId, borrow_span: Span, cmt: mc::cmt<'tcx>, - loan_region: ty::Region, + loan_region: &'tcx ty::Region, bk: ty::BorrowKind, loan_cause: euv::LoanCause) { diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 667bf16874ec4..9f95175d59d43 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -28,7 +28,7 @@ pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, span: Span, cause: euv::LoanCause, cmt: mc::cmt<'tcx>, - loan_region: ty::Region, + loan_region: &'tcx ty::Region, _: ty::BorrowKind) -> Result<(),()> { //! Reports error if `loan_region` is larger than S @@ -56,7 +56,7 @@ struct GuaranteeLifetimeContext<'a, 'tcx: 'a> { span: Span, cause: euv::LoanCause, - loan_region: ty::Region, + loan_region: &'tcx ty::Region, cmt_original: mc::cmt<'tcx> } @@ -92,7 +92,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } } - fn check_scope(&self, max_scope: ty::Region) -> R { + fn check_scope(&self, max_scope: &'tcx ty::Region) -> R { //! Reports an error if `loan_region` is larger than `max_scope` if !self.bccx.is_subregion_of(self.loan_region, max_scope) { @@ -102,7 +102,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } } - fn scope(&self, cmt: &mc::cmt) -> ty::Region { + fn scope(&self, cmt: &mc::cmt<'tcx>) -> &'tcx ty::Region { //! Returns the maximal region scope for the which the //! lvalue `cmt` is guaranteed to be valid without any //! rooting etc, and presuming `cmt` is not mutated. @@ -112,16 +112,15 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { temp_scope } Categorization::Upvar(..) => { - ty::ReScope(self.item_scope) - } - Categorization::StaticItem => { - ty::ReStatic + self.bccx.tcx.mk_region(ty::ReScope(self.item_scope)) } Categorization::Local(local_id) => { - ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id)) + self.bccx.tcx.mk_region(ty::ReScope( + self.bccx.tcx.region_maps.var_scope(local_id))) } + Categorization::StaticItem | Categorization::Deref(_, _, mc::UnsafePtr(..)) => { - ty::ReStatic + self.bccx.tcx.mk_region(ty::ReStatic) } Categorization::Deref(_, _, mc::BorrowedPtr(_, r)) | Categorization::Deref(_, _, mc::Implicit(_, r)) => { @@ -135,7 +134,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } } - fn report_error(&self, code: bckerr_code) { + fn report_error(&self, code: bckerr_code<'tcx>) { self.bccx.report(BckError { cmt: self.cmt_original.clone(), span: self.span, cause: BorrowViolation(self.cause), diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index c982fc091d24c..a255564f01e25 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -130,7 +130,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { borrow_id: ast::NodeId, borrow_span: Span, cmt: mc::cmt<'tcx>, - loan_region: ty::Region, + loan_region: &'tcx ty::Region, bk: ty::BorrowKind, loan_cause: euv::LoanCause) { @@ -307,7 +307,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { borrow_span: Span, cmt: mc::cmt<'tcx>, req_kind: ty::BorrowKind, - loan_region: ty::Region, + loan_region: &'tcx ty::Region, cause: euv::LoanCause) { debug!("guarantee_valid(borrow_id={}, cmt={:?}, \ req_mutbl={:?}, loan_region={:?})", @@ -318,7 +318,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { // a loan for the empty region can never be dereferenced, so // it is always safe - if loan_region == ty::ReEmpty { + if *loan_region == ty::ReEmpty { return; } @@ -358,7 +358,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { } RestrictionResult::SafeIf(loan_path, restricted_paths) => { - let loan_scope = match loan_region { + let loan_scope = match *loan_region { ty::ReScope(scope) => scope, ty::ReFree(ref fr) => fr.scope, diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index 3d9df4c8bd008..d08f792b30c14 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -31,7 +31,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, span: Span, cause: euv::LoanCause, cmt: mc::cmt<'tcx>, - loan_region: ty::Region) + loan_region: &'tcx ty::Region) -> RestrictionResult<'tcx> { let ctxt = RestrictionsContext { bccx: bccx, @@ -49,7 +49,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, struct RestrictionsContext<'a, 'tcx: 'a> { bccx: &'a BorrowckCtxt<'a, 'tcx>, span: Span, - loan_region: ty::Region, + loan_region: &'tcx ty::Region, cause: euv::LoanCause, } @@ -157,7 +157,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { fn extend(&self, result: RestrictionResult<'tcx>, cmt: &mc::cmt<'tcx>, - elem: LoanPathElem) -> RestrictionResult<'tcx> { + elem: LoanPathElem<'tcx>) -> RestrictionResult<'tcx> { match result { RestrictionResult::Safe => RestrictionResult::Safe, RestrictionResult::SafeIf(base_lp, mut base_vec) => { diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 111646912ade3..3ff2fb8e2e527 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}; +use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::mir::repr::*; use rustc::mir::transform::{Pass, MirPass, MirSource}; use rustc::middle::const_val::ConstVal; @@ -26,6 +26,7 @@ use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; use std::fmt; +use std::iter; use std::u32; pub struct ElaborateDrops; @@ -859,7 +860,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, vec![ty], vec![]); + let substs = Substs::new(tcx, iter::once(Kind::from(ty))); let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs); self.patch.new_block(BasicBlockData { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 225895adefa4b..5826064c267a0 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -365,7 +365,7 @@ pub enum LoanPathKind<'tcx> { LpVar(ast::NodeId), // `x` in README.md LpUpvar(ty::UpvarId), // `x` captured by-value into closure LpDowncast(Rc>, DefId), // `x` downcast to particular enum variant - LpExtend(Rc>, mc::MutabilityCategory, LoanPathElem) + LpExtend(Rc>, mc::MutabilityCategory, LoanPathElem<'tcx>) } impl<'tcx> LoanPath<'tcx> { @@ -410,8 +410,8 @@ impl ToInteriorKind for mc::InteriorKind { // `enum E { X { foo: u32 }, Y { foo: u32 }}` // each `foo` is qualified by the definitition id of the variant (`X` or `Y`). #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub enum LoanPathElem { - LpDeref(mc::PointerKind), +pub enum LoanPathElem<'tcx> { + LpDeref(mc::PointerKind<'tcx>), LpInterior(Option, InteriorKind), } @@ -564,10 +564,11 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option>> { // Errors that can occur #[derive(PartialEq)] -pub enum bckerr_code { +pub enum bckerr_code<'tcx> { err_mutbl, - err_out_of_scope(ty::Region, ty::Region, euv::LoanCause), // superscope, subscope, loan cause - err_borrowed_pointer_too_short(ty::Region, ty::Region), // loan, ptr + /// superscope, subscope, loan cause + err_out_of_scope(&'tcx ty::Region, &'tcx ty::Region, euv::LoanCause), + err_borrowed_pointer_too_short(&'tcx ty::Region, &'tcx ty::Region), // loan, ptr } // Combination of an error code and the categorization of the expression @@ -577,7 +578,7 @@ pub struct BckError<'tcx> { span: Span, cause: AliasableViolationKind, cmt: mc::cmt<'tcx>, - code: bckerr_code + code: bckerr_code<'tcx> } #[derive(Copy, Clone, Debug, PartialEq)] @@ -605,7 +606,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.free_region_map = old_free_region_map; } - pub fn is_subregion_of(&self, r_sub: ty::Region, r_sup: ty::Region) + pub fn is_subregion_of(&self, r_sub: &'tcx ty::Region, r_sup: &'tcx ty::Region) -> bool { self.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup) @@ -614,9 +615,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { pub fn report(&self, err: BckError<'tcx>) { // Catch and handle some particular cases. match (&err.code, &err.cause) { - (&err_out_of_scope(ty::ReScope(_), ty::ReStatic, _), + (&err_out_of_scope(&ty::ReScope(_), &ty::ReStatic, _), &BorrowViolation(euv::ClosureCapture(span))) | - (&err_out_of_scope(ty::ReScope(_), ty::ReFree(..), _), + (&err_out_of_scope(&ty::ReScope(_), &ty::ReFree(..), _), &BorrowViolation(euv::ClosureCapture(span))) => { return self.report_out_of_scope_escaping_closure_capture(&err, span); } @@ -965,8 +966,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { .emit(); } - fn region_end_span(&self, region: ty::Region) -> Option { - match region { + fn region_end_span(&self, region: &'tcx ty::Region) -> Option { + match *region { ty::ReScope(scope) => { match scope.span(&self.tcx.region_maps, &self.tcx.map) { Some(s) => { @@ -1194,8 +1195,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } -fn statement_scope_span(tcx: TyCtxt, region: ty::Region) -> Option { - match region { +fn statement_scope_span(tcx: TyCtxt, region: &ty::Region) -> Option { + match *region { ty::ReScope(scope) => { match tcx.map.find(scope.node_id(&tcx.region_maps)) { Some(hir_map::NodeStmt(stmt)) => Some(stmt.span), diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 3c82358542876..82c142c919e34 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -1172,7 +1172,7 @@ impl<'a, 'gcx, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'gcx> { _: NodeId, span: Span, _: cmt, - _: Region, + _: &'tcx Region, kind: BorrowKind, _: LoanCause) { match kind { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 32d0bbbfdb6b7..460a6e68a5c5a 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -20,13 +20,14 @@ use rustc::middle::region::{self, CodeExtent}; use rustc::middle::region::CodeExtentData; use rustc::middle::resolve_lifetime; use rustc::middle::stability; -use rustc::ty::subst::{Subst, Substs}; +use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::traits::Reveal; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::infer::{self, InferOk, InferResult, TypeOrigin}; use rustc_metadata::cstore::CStore; use rustc::hir::map as hir_map; use rustc::session::{self, config}; +use std::iter; use std::rc::Rc; use syntax::ast; use syntax::abi::Abi; @@ -283,25 +284,26 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { pub fn re_early_bound(&self, index: u32, name: &'static str) - -> ty::Region { + -> &'tcx ty::Region { let name = token::intern(name); - ty::ReEarlyBound(ty::EarlyBoundRegion { + self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { index: index, name: name, - }) + })) } - pub fn re_late_bound_with_debruijn(&self, id: u32, debruijn: ty::DebruijnIndex) -> ty::Region { - ty::ReLateBound(debruijn, ty::BrAnon(id)) + pub fn re_late_bound_with_debruijn(&self, id: u32, debruijn: ty::DebruijnIndex) + -> &'tcx ty::Region { + self.infcx.tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id))) } - pub fn t_rptr(&self, r: ty::Region) -> Ty<'tcx> { - self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) + pub fn t_rptr(&self, r: &'tcx ty::Region) -> Ty<'tcx> { + self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize) } pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> { let r = self.re_late_bound_with_debruijn(id, ty::DebruijnIndex::new(1)); - self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize) } pub fn t_rptr_late_bound_with_debruijn(&self, @@ -309,7 +311,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { debruijn: ty::DebruijnIndex) -> Ty<'tcx> { let r = self.re_late_bound_with_debruijn(id, debruijn); - self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize) } pub fn t_rptr_scope(&self, id: ast::NodeId) -> Ty<'tcx> { @@ -317,16 +319,16 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) } - pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region { - ty::ReFree(ty::FreeRegion { + pub fn re_free(&self, nid: ast::NodeId, id: u32) -> &'tcx ty::Region { + self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: self.tcx().region_maps.item_extent(nid), bound_region: ty::BrAnon(id), - }) + })) } pub fn t_rptr_free(&self, nid: ast::NodeId, id: u32) -> Ty<'tcx> { let r = self.re_free(nid, id); - self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize) } pub fn t_rptr_static(&self) -> Ty<'tcx> { @@ -675,7 +677,7 @@ fn subst_ty_renumber_bound() { env.t_fn(&[t_param], env.t_nil()) }; - let substs = Substs::new(env.infcx.tcx, vec![t_rptr_bound1], vec![]); + let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(t_rptr_bound1))); let t_substituted = t_source.subst(env.infcx.tcx, substs); // t_expected = fn(&'a isize) @@ -710,7 +712,7 @@ fn subst_ty_renumber_some_bounds() { env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil())) }; - let substs = Substs::new(env.infcx.tcx, vec![t_rptr_bound1], vec![]); + let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(t_rptr_bound1))); let t_substituted = t_source.subst(env.infcx.tcx, substs); // t_expected = (&'a isize, fn(&'a isize)) @@ -772,7 +774,7 @@ fn subst_region_renumber_region() { env.t_fn(&[env.t_rptr(re_early)], env.t_nil()) }; - let substs = Substs::new(env.infcx.tcx, vec![], vec![re_bound1]); + let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(re_bound1))); let t_substituted = t_source.subst(env.infcx.tcx, substs); // t_expected = fn(&'a isize) diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index ad52d346857ff..0236f9c413ddc 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -517,7 +517,7 @@ pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) { // Encoding and decoding the side tables trait rbml_writer_helpers<'tcx> { - fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region); + fn emit_region(&mut self, ecx: &e::EncodeContext, r: &'tcx ty::Region); fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>); fn emit_substs<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, substs: &Substs<'tcx>); @@ -531,7 +531,7 @@ trait rbml_writer_helpers<'tcx> { } impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { - fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region) { + fn emit_region(&mut self, ecx: &e::EncodeContext, r: &'tcx ty::Region) { self.emit_opaque(|this| Ok(tyencode::enc_region(&mut this.cursor, &ecx.ty_str_ctxt(), r))); @@ -617,7 +617,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { &adjustment::AutoPtr(r, m) => { this.emit_enum_variant("AutoPtr", 0, 2, |this| { this.emit_enum_variant_arg(0, - |this| Ok(this.emit_region(ecx, *r))); + |this| Ok(this.emit_region(ecx, r))); this.emit_enum_variant_arg(1, |this| m.encode(this)) }) } @@ -824,7 +824,7 @@ trait rbml_decoder_decoder_helpers<'tcx> { f: F) -> R where F: for<'x> FnOnce(&mut tydecode::TyDecoder<'x, 'tcx>) -> R; - fn read_region(&mut self, dcx: &DecodeContext) -> ty::Region; + fn read_region<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> &'tcx ty::Region; fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>; fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec>; fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) @@ -835,8 +835,8 @@ trait rbml_decoder_decoder_helpers<'tcx> { -> ty::Predicate<'tcx>; fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> &'tcx Substs<'tcx>; - fn read_upvar_capture(&mut self, dcx: &DecodeContext) - -> ty::UpvarCapture; + fn read_upvar_capture<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) + -> ty::UpvarCapture<'tcx>; fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> adjustment::AutoAdjustment<'tcx>; fn read_cast_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) @@ -908,7 +908,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { str } } - fn read_region(&mut self, dcx: &DecodeContext) -> ty::Region { + fn read_region<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> &'tcx ty::Region { // Note: regions types embed local node ids. In principle, we // should translate these node ids into the new decode // context. However, we do not bother, because region types @@ -948,7 +948,8 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { .parse_substs()) }).unwrap() } - fn read_upvar_capture(&mut self, dcx: &DecodeContext) -> ty::UpvarCapture { + fn read_upvar_capture<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) + -> ty::UpvarCapture<'tcx> { self.read_enum("UpvarCapture", |this| { let variants = ["ByValue", "ByRef"]; this.read_enum_variant(&variants, |this, i| { @@ -1032,7 +1033,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { this.read_enum_variant(&variants, |this, i| { Ok(match i { 0 => { - let r: ty::Region = + let r: &'tcx ty::Region = this.read_enum_variant_arg(0, |this| { Ok(this.read_region(dcx)) }).unwrap(); @@ -1041,7 +1042,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> { Decodable::decode(this) }).unwrap(); - adjustment::AutoPtr(dcx.tcx.mk_region(r), m) + adjustment::AutoPtr(r, m) } 1 => { let m: hir::Mutability = diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index 94426dcbf1d8d..0fd7b683067b7 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -73,7 +73,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::closure_ty(&cdata, def_id.index, tcx) } - fn item_variances(&self, def: DefId) -> ty::ItemVariances { + fn item_variances(&self, def: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(def)); let cdata = self.get_crate_data(def.krate); decoder::get_item_variances(&cdata, def.index) @@ -291,13 +291,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::is_foreign_item(&cdata, did.index) } - fn is_static_method(&self, def: DefId) -> bool - { - self.dep_graph.read(DepNode::MetaData(def)); - let cdata = self.get_crate_data(def.krate); - decoder::is_static_method(&cdata, def.index) - } - fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { self.do_is_statically_included_foreign_item(id) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b0335258b4041..bbda089b1c2a8 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -859,7 +859,8 @@ pub fn maybe_get_item_mir<'a, 'tcx>(cdata: Cmd, } } -fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory { +fn get_explicit_self<'a, 'tcx>(item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>) + -> ty::ExplicitSelfCategory<'tcx> { fn get_mutability(ch: u8) -> hir::Mutability { match ch as char { 'i' => hir::MutImmutable, @@ -879,7 +880,7 @@ fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory { // FIXME(#4846) expl. region '&' => { ty::ExplicitSelfCategory::ByReference( - ty::ReEmpty, + tcx.mk_region(ty::ReEmpty), get_mutability(string.as_bytes()[1])) } _ => bug!("unknown self type code: `{}`", explicit_self_kind as char) @@ -905,16 +906,6 @@ pub fn get_trait_name(cdata: Cmd, id: DefIndex) -> ast::Name { item_name(doc) } -pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool { - let doc = cdata.lookup_item(id); - match item_sort(doc) { - Some('r') | Some('p') => { - get_explicit_self(doc) == ty::ExplicitSelfCategory::Static - } - _ => false - } -} - pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option> { let item_doc = cdata.lookup_item(id); @@ -959,7 +950,7 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a "the type {:?} of the method {:?} is not a function?", ity, name) }; - let explicit_self = get_explicit_self(item_doc); + let explicit_self = get_explicit_self(item_doc, tcx); ty::MethodTraitItem(Rc::new(ty::Method::new(name, generics, @@ -1000,7 +991,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex) }).collect() } -pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances { +pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> Vec { let item_doc = cdata.lookup_item(id); let variance_doc = reader::get_doc(item_doc, tag_item_variances); let mut decoder = reader::Decoder::new(variance_doc); diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs index c76cf23639237..f51299226fe7d 100644 --- a/src/librustc_metadata/tydecode.rs +++ b/src/librustc_metadata/tydecode.rs @@ -20,7 +20,7 @@ use rustc::hir; use rustc::hir::def_id::{DefId, DefIndex}; use middle::region; -use rustc::ty::subst::Substs; +use rustc::ty::subst::{Kind, Substs}; use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rbml; @@ -129,19 +129,19 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> { - let mut regions = vec![]; - let mut types = vec![]; + let mut params = vec![]; assert_eq!(self.next(), '['); - while self.peek() != '|' { - regions.push(self.parse_region()); - } - assert_eq!(self.next(), '|'); while self.peek() != ']' { - types.push(self.parse_ty()); + let k = match self.next() { + 'r' => Kind::from(self.parse_region()), + 't' => Kind::from(self.parse_ty()), + _ => bug!() + }; + params.push(k); } assert_eq!(self.next(), ']'); - Substs::new(self.tcx, types, regions) + Substs::new(self.tcx, params) } pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> { @@ -207,8 +207,8 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } } - pub fn parse_region(&mut self) -> ty::Region { - match self.next() { + pub fn parse_region(&mut self) -> &'tcx ty::Region { + self.tcx.mk_region(match self.next() { 'b' => { assert_eq!(self.next(), '['); let id = ty::DebruijnIndex::new(self.parse_u32()); @@ -245,7 +245,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { 'e' => ty::ReEmpty, 'E' => ty::ReErased, _ => bug!("parse_region: bad input") - } + }) } fn parse_scope(&mut self) -> region::CodeExtent { @@ -403,9 +403,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { '~' => return tcx.mk_box(self.parse_ty()), '*' => return tcx.mk_ptr(self.parse_mt()), '&' => { - let r = self.parse_region(); - let mt = self.parse_mt(); - return tcx.mk_ref(tcx.mk_region(r), mt); + return tcx.mk_ref(self.parse_region(), self.parse_mt()); } 'V' => { let t = self.parse_ty(); @@ -657,7 +655,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } } - fn parse_region_param_def(&mut self) -> ty::RegionParameterDef { + fn parse_region_param_def(&mut self) -> ty::RegionParameterDef<'tcx> { let name = self.parse_name(':'); let def_id = self.parse_def(); let index = self.parse_u32(); @@ -681,7 +679,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } - fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault { + fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault<'tcx> { match self.next() { 'a' => ty::ObjectLifetimeDefault::Ambiguous, 'b' => ty::ObjectLifetimeDefault::BaseDefault, diff --git a/src/librustc_metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs index 90fd8a0eb2f65..7255eae61d453 100644 --- a/src/librustc_metadata/tyencode.rs +++ b/src/librustc_metadata/tyencode.rs @@ -133,7 +133,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx ty::TyRawPtr(mt) => { write!(w, "*"); enc_mt(w, cx, mt); } ty::TyRef(r, mt) => { write!(w, "&"); - enc_region(w, cx, *r); + enc_region(w, cx, r); enc_mt(w, cx, mt); } ty::TyArray(t, sz) => { @@ -251,12 +251,16 @@ fn enc_opt(w: &mut Cursor>, t: Option, enc_f: F) where pub fn enc_substs<'a, 'tcx>(w: &mut Cursor>, cx: &ctxt<'a, 'tcx>, substs: &Substs<'tcx>) { write!(w, "["); - for &r in &substs.regions { - enc_region(w, cx, r); - } - write!(w, "|"); - for &ty in &substs.types { - enc_ty(w, cx, ty); + for &k in substs.params() { + if let Some(ty) = k.as_type() { + write!(w, "t"); + enc_ty(w, cx, ty); + } else if let Some(r) = k.as_region() { + write!(w, "r"); + enc_region(w, cx, r); + } else { + bug!() + } } write!(w, "]"); } @@ -286,8 +290,8 @@ pub fn enc_generics<'a, 'tcx>(w: &mut Cursor>, cx: &ctxt<'a, 'tcx>, } } -pub fn enc_region(w: &mut Cursor>, cx: &ctxt, r: ty::Region) { - match r { +pub fn enc_region(w: &mut Cursor>, cx: &ctxt, r: &ty::Region) { + match *r { ty::ReLateBound(id, br) => { write!(w, "b[{}|", id.depth); enc_bound_region(w, cx, br); diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index ec390704d0789..1b64b4d0b5317 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -278,7 +278,7 @@ struct Binding<'tcx> { var_id: NodeId, var_ty: Ty<'tcx>, mutability: Mutability, - binding_mode: BindingMode, + binding_mode: BindingMode<'tcx>, } #[derive(Clone, Debug)] diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 8c9ed53c8ab4d..bf43bfb326a58 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -293,7 +293,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { assert!(ty.is_slice()); let eq_def_id = self.hir.tcx().lang_items.eq_trait().unwrap(); let ty = mt.ty; - let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, vec![ty]); + let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty]); let bool_ty = self.hir.bool_ty(); let eq_result = self.temp(bool_ty); diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 2f83c0ef1bebb..0b33e5a145083 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -89,13 +89,15 @@ should go to. use build::{BlockAnd, BlockAndExtension, Builder, CFG, ScopeAuxiliary, ScopeId}; use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::middle::lang_items; -use rustc::ty::subst::{Substs, Subst}; +use rustc::ty::subst::{Kind, Substs, Subst}; use rustc::ty::{Ty, TyCtxt}; use rustc::mir::repr::*; use syntax_pos::Span; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::fnv::FnvHashMap; +use std::iter; + pub struct Scope<'tcx> { /// the scope-id within the scope_auxiliary id: ScopeId, @@ -789,7 +791,7 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, -> TerminatorKind<'tcx> { let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem) .unwrap_or_else(|e| tcx.sess.fatal(&e)); - let substs = Substs::new(tcx, vec![data.item_ty], vec![]); + let substs = Substs::new(tcx, iter::once(Kind::from(data.item_ty))); TerminatorKind::Call { func: Operand::Constant(Constant { span: data.span, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index a61fdb79df822..6e8a5771eea94 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -108,7 +108,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { region, ty::TypeAndMut { ty: expr.ty, mutbl: mutbl }), span: expr.span, kind: ExprKind::Borrow { - region: *region, + region: region, borrow_kind: to_borrow_kind(mutbl), arg: expr.to_ref() } @@ -137,7 +137,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { ty: adjusted_ty, span: self.span, kind: ExprKind::Borrow { - region: *r, + region: r, borrow_kind: to_borrow_kind(m), arg: expr.to_ref(), }, @@ -154,7 +154,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { ty: cx.tcx.mk_ref(region, ty::TypeAndMut { ty: expr.ty, mutbl: m }), span: self.span, kind: ExprKind::Borrow { - region: *region, + region: region, borrow_kind: to_borrow_kind(m), arg: expr.to_ref(), }, @@ -310,7 +310,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, _ => span_bug!(expr.span, "type of & not region"), }; ExprKind::Borrow { - region: *region, + region: region, borrow_kind: to_borrow_kind(mutbl), arg: expr.to_ref(), } @@ -842,8 +842,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ExprKind::Deref { arg: Expr { temp_lifetime: temp_lifetime, - ty: cx.tcx.mk_ref( - cx.tcx.mk_region(borrow.region), + ty: cx.tcx.mk_ref(borrow.region, ty::TypeAndMut { ty: var_ty, mutbl: borrow.kind.to_mutbl_lossy() @@ -907,8 +906,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } PassArgs::ByRef => { - let scope = cx.tcx.region_maps.node_extent(expr.id); - let region = cx.tcx.mk_region(ty::ReScope(scope)); + let region = cx.tcx.node_scope_region(expr.id); let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); argrefs.extend( args.iter() @@ -922,7 +920,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, temp_lifetime: temp_lifetime, ty: adjusted_ty, span: expr.span, - kind: ExprKind::Borrow { region: *region, + kind: ExprKind::Borrow { region: region, borrow_kind: BorrowKind::Shared, arg: arg.to_ref() } }.to_ref() diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 972e7f5be7075..a38b429333b70 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -144,10 +144,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { trait_def_id: DefId, method_name: &str, self_ty: Ty<'tcx>, - params: Vec>) + params: &[Ty<'tcx>]) -> (Ty<'tcx>, Literal<'tcx>) { let method_name = token::intern(method_name); - let substs = Substs::new_trait(self.tcx, params, vec![], self_ty); + let substs = Substs::new_trait(self.tcx, self_ty, params); for trait_item in self.tcx.trait_items(trait_def_id).iter() { match *trait_item { ty::ImplOrTraitItem::MethodTraitItem(ref method) => { diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index c54c8bfb5981e..0bd22cd2d9308 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -161,7 +161,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { let id = self.cx.tcx.expect_def(pat.id).var_id(); let var_ty = self.cx.tcx.node_id_to_type(pat.id); let region = match var_ty.sty { - ty::TyRef(&r, _) => Some(r), + ty::TyRef(r, _) => Some(r), _ => None, }; let (mutability, mode) = match bm { diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 2a5b7d0fb2902..353f243335302 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -193,7 +193,7 @@ pub enum ExprKind<'tcx> { id: DefId, }, Borrow { - region: Region, + region: &'tcx Region, borrow_kind: BorrowKind, arg: ExprRef<'tcx>, }, @@ -284,7 +284,7 @@ pub enum PatternKind<'tcx> { Binding { mutability: Mutability, name: ast::Name, - mode: BindingMode, + mode: BindingMode<'tcx>, var: ast::NodeId, ty: Ty<'tcx>, subpattern: Option>, @@ -332,9 +332,9 @@ pub enum PatternKind<'tcx> { } #[derive(Copy, Clone, Debug)] -pub enum BindingMode { +pub enum BindingMode<'tcx> { ByValue, - ByRef(Region, BorrowKind), + ByRef(&'tcx Region, BorrowKind), } #[derive(Clone, Debug)] diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index bcdc0d2ea3f9d..32c78ca4a5ad1 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -543,7 +543,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let Literal::Item { def_id, substs } = constant.literal { // Don't peek inside generic (associated) constants. - if !substs.types.is_empty() { + if substs.types().next().is_some() { self.add_type(constant.ty); } else { let qualif = qualify_const_item_cached(self.tcx, diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index b116ab7b3161a..4aae6d690c4df 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -683,7 +683,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { borrow_id: ast::NodeId, _borrow_span: Span, cmt: mc::cmt<'tcx>, - _loan_region: ty::Region, + _loan_region: &'tcx ty::Region, bk: ty::BorrowKind, loan_cause: euv::LoanCause) { // Kind of hacky, but we allow Unsafe coercions in constants. diff --git a/src/librustc_passes/rvalues.rs b/src/librustc_passes/rvalues.rs index 782ee34edd4f9..c3ef5a72a2944 100644 --- a/src/librustc_passes/rvalues.rs +++ b/src/librustc_passes/rvalues.rs @@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'gcx, 'tc _borrow_id: ast::NodeId, _borrow_span: Span, _cmt: mc::cmt, - _loan_region: ty::Region, + _loan_region: &'tcx ty::Region, _bk: ty::BorrowKind, _loan_cause: euv::LoanCause) { } diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index 25a1479c28948..9b02cbe6721f3 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -104,8 +104,9 @@ use util::sha2::{Digest, Sha256}; use rustc::middle::{cstore, weak_lang_items}; use rustc::hir::def_id::DefId; use rustc::hir::map as hir_map; -use rustc::ty::{self, TyCtxt, TypeFoldable}; +use rustc::ty::{Ty, TyCtxt, TypeFoldable}; use rustc::ty::item_path::{self, ItemPathBuffer, RootMode}; +use rustc::ty::subst::Substs; use rustc::hir::map::definitions::{DefPath, DefPathData}; use syntax::attr; @@ -126,14 +127,14 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, // parameters substituted; this is // included in the hash as a kind of // safeguard. - item_type: ty::Ty<'tcx>, + item_type: Ty<'tcx>, // values for generic type parameters, // if any. - parameters: &[ty::Ty<'tcx>]) + substs: Option<&Substs<'tcx>>) -> String { debug!("get_symbol_hash(def_path={:?}, parameters={:?})", - def_path, parameters); + def_path, substs); let tcx = scx.tcx(); @@ -154,11 +155,13 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, hash_state.input(&encoded_item_type[..]); // also include any type parameters (for generic items) - for t in parameters { - assert!(!t.has_erasable_regions()); - assert!(!t.needs_subst()); - let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string); - hash_state.input(&encoded_type[..]); + if let Some(substs) = substs { + for t in substs.types() { + assert!(!t.has_erasable_regions()); + assert!(!t.needs_subst()); + let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string); + hash_state.input(&encoded_type[..]); + } } return format!("h{}", truncated_hash_result(&mut *hash_state)); @@ -252,7 +255,7 @@ impl<'a, 'tcx> Instance<'tcx> { // and should not matter anyhow. let instance_ty = scx.tcx().erase_regions(&instance_ty.ty); - let hash = get_symbol_hash(scx, &def_path, instance_ty, &substs.types); + let hash = get_symbol_hash(scx, &def_path, instance_ty, Some(substs)); let mut buffer = SymbolPathBuffer { names: Vec::with_capacity(def_path.data.len()) @@ -282,14 +285,14 @@ impl ItemPathBuffer for SymbolPathBuffer { } pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, - t: ty::Ty<'tcx>, + t: Ty<'tcx>, prefix: &str) -> String { let empty_def_path = DefPath { data: vec![], krate: cstore::LOCAL_CRATE, }; - let hash = get_symbol_hash(scx, &empty_def_path, t, &[]); + let hash = get_symbol_hash(scx, &empty_def_path, t, None); let path = [token::intern_and_get_ident(prefix)]; mangle(path.iter().cloned(), Some(&hash[..])) } @@ -297,7 +300,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a, /// Only symbols that are invisible outside their compilation unit should use a /// name generated by this function. pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - t: ty::Ty<'tcx>, + t: Ty<'tcx>, suffix: &str) -> String { let path = [token::intern(&t.to_string()).as_str(), @@ -306,7 +309,7 @@ pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx> data: vec![], krate: cstore::LOCAL_CRATE, }; - let hash = get_symbol_hash(ccx.shared(), &def_path, t, &[]); + let hash = get_symbol_hash(ccx.shared(), &def_path, t, None); mangle(path.iter().cloned(), Some(&hash[..])) } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 165884c8f55a2..5e431193a2c4c 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -514,7 +514,7 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx -> CustomCoerceUnsized { let trait_ref = ty::Binder(ty::TraitRef { def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(), - substs: Substs::new_trait(scx.tcx(), vec![target_ty], vec![], source_ty) + substs: Substs::new_trait(scx.tcx(), source_ty, &[target_ty]) }); match fulfill_obligation(scx, DUMMY_SP, trait_ref) { diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 9aa486dc62811..a30f8f291a677 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -400,9 +400,9 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("get_fn(def_id={:?}, substs={:?})", def_id, substs); - assert!(!substs.types.needs_infer()); - assert!(!substs.types.has_escaping_regions()); - assert!(!substs.types.has_param_types()); + assert!(!substs.needs_infer()); + assert!(!substs.has_escaping_regions()); + assert!(!substs.has_param_types()); let substs = tcx.normalize_associated_type(&substs); let instance = Instance::new(def_id, substs); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 76910304eebb0..8dd76535cf811 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -753,7 +753,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, .drop_trait() .unwrap(); - let self_type_substs = Substs::new_trait(scx.tcx(), vec![], vec![], ty); + let self_type_substs = Substs::new_trait(scx.tcx(), ty, &[]); let trait_ref = ty::TraitRef { def_id: drop_trait_def_id, @@ -1235,7 +1235,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // The substitutions we have are on the impl, so we grab // the method type from the impl to substitute into. let impl_substs = Substs::for_item(tcx, impl_def_id, - |_, _| ty::ReErased, + |_, _| tcx.mk_region(ty::ReErased), |_, _| tcx.types.err); let mth = meth::get_impl_method(tcx, callee_substs, diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index c5053e4feee62..5055ed86a0386 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -265,7 +265,7 @@ pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res { } pub fn validate_substs(substs: &Substs) { - assert!(!substs.types.needs_infer()); + assert!(!substs.needs_infer()); } // Function context. Every LLVM function we create will have one of diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 0a295b251b31e..71184dd3f814d 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -563,7 +563,9 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { /// Given the def-id of some item that has no type parameters, make /// a suitable "empty substs" for it. pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> { - Substs::for_item(self.tcx(), item_def_id, |_, _| ty::ReErased, |_, _| { + Substs::for_item(self.tcx(), item_def_id, + |_, _| self.tcx().mk_region(ty::ReErased), + |_, _| { bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id) }) } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index fccb326b23221..67d4a0e044c9c 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -342,11 +342,10 @@ impl<'tcx> TypeMap<'tcx> { // Add the def-index as the second part output.push_str(&format!("{:x}", def_id.index.as_usize())); - let tps = &substs.types; - if !tps.is_empty() { + if substs.types().next().is_some() { output.push('<'); - for &type_parameter in tps { + for type_parameter in substs.types() { let param_type_id = type_map.get_unique_type_id_of_type(cx, type_parameter); let param_type_id = diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 58425cf60d550..4d8a9a2ac40d7 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -344,37 +344,35 @@ 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>, - param_substs: &Substs<'tcx>, + substs: &Substs<'tcx>, file_metadata: DIFile, name_to_append_suffix_to: &mut String) -> DIArray { - let actual_types = ¶m_substs.types; - - if actual_types.is_empty() { + if substs.types().next().is_none() { return create_DIArray(DIB(cx), &[]); } name_to_append_suffix_to.push('<'); - for (i, &actual_type) in actual_types.iter().enumerate() { + for (i, actual_type) in substs.types().enumerate() { + if i != 0 { + name_to_append_suffix_to.push_str(","); + } + let actual_type = cx.tcx().normalize_associated_type(&actual_type); // Add actual type name to <...> clause of function name let actual_type_name = compute_debuginfo_type_name(cx, actual_type, true); name_to_append_suffix_to.push_str(&actual_type_name[..]); - - if i != actual_types.len() - 1 { - name_to_append_suffix_to.push_str(","); - } } name_to_append_suffix_to.push('>'); // Again, only create type information if full debuginfo is enabled let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo { let names = get_type_parameter_names(cx, generics); - actual_types.iter().zip(names).map(|(ty, name)| { - let actual_type = cx.tcx().normalize_associated_type(ty); + substs.types().zip(names).map(|(ty, name)| { + let actual_type = cx.tcx().normalize_associated_type(&ty); let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); let name = CString::new(name.as_str().as_bytes()).unwrap(); unsafe { diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 2a996ca75a37e..f757578e6954d 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -175,13 +175,13 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, substs: &Substs<'tcx>, output: &mut String) { - if substs.types.is_empty() { + if substs.types().next().is_none() { return; } output.push('<'); - for &type_parameter in &substs.types { + for type_parameter in substs.types() { push_debuginfo_type_name(cx, type_parameter, true, output); output.push_str(", "); } diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 6a072c84dd9b3..f29d85f3b52f0 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -302,7 +302,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let trait_ref = ty::Binder(ty::TraitRef { def_id: tcx.lang_items.drop_trait().unwrap(), - substs: Substs::new_trait(tcx, vec![], vec![], t) + substs: Substs::new_trait(tcx, t, &[]) }); let vtbl = match fulfill_obligation(bcx.ccx().shared(), DUMMY_SP, trait_ref) { traits::VtableImpl(data) => data, diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 7faff98aea442..8bef7584db9e2 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -146,12 +146,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, Call(bcx, llfn, &[], call_debug_location) } (_, "size_of") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); let lltp_ty = type_of::type_of(ccx, tp_ty); C_uint(ccx, machine::llsize_of_alloc(ccx, lltp_ty)) } (_, "size_of_val") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); if !type_is_sized(tcx, tp_ty) { let (llsize, _) = glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]); @@ -162,11 +162,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } } (_, "min_align_of") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); C_uint(ccx, type_of::align_of(ccx, tp_ty)) } (_, "min_align_of_val") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); if !type_is_sized(tcx, tp_ty) { let (_, llalign) = glue::size_and_align_of_dst(&bcx.build(), tp_ty, llargs[1]); @@ -176,12 +176,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } } (_, "pref_align_of") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); let lltp_ty = type_of::type_of(ccx, tp_ty); C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty)) } (_, "drop_in_place") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); let is_sized = type_is_sized(tcx, tp_ty); let ptr = if is_sized { llargs[0] @@ -199,15 +199,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, C_nil(ccx) } (_, "type_name") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); let ty_name = token::intern_and_get_ident(&tp_ty.to_string()); C_str_slice(ccx, ty_name) } (_, "type_id") => { - C_u64(ccx, ccx.tcx().type_id_hash(substs.types[0])) + C_u64(ccx, ccx.tcx().type_id_hash(substs.type_at(0))) } (_, "init") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); if !type_is_zero_size(ccx, tp_ty) { // Just zero out the stack slot. (See comment on base::memzero for explanation) init_zero_mem(bcx, llresult, tp_ty); @@ -219,7 +219,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, C_nil(ccx) } (_, "needs_drop") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); C_bool(ccx, bcx.fcx.type_needs_drop(tp_ty)) } @@ -238,7 +238,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, copy_intrinsic(bcx, false, false, - substs.types[0], + substs.type_at(0), llargs[1], llargs[0], llargs[2], @@ -248,7 +248,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, copy_intrinsic(bcx, true, false, - substs.types[0], + substs.type_at(0), llargs[1], llargs[0], llargs[2], @@ -257,7 +257,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, (_, "write_bytes") => { memset_intrinsic(bcx, false, - substs.types[0], + substs.type_at(0), llargs[0], llargs[1], llargs[2], @@ -268,7 +268,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, copy_intrinsic(bcx, false, true, - substs.types[0], + substs.type_at(0), llargs[0], llargs[1], llargs[2], @@ -278,7 +278,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, copy_intrinsic(bcx, true, true, - substs.types[0], + substs.type_at(0), llargs[0], llargs[1], llargs[2], @@ -287,14 +287,14 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, (_, "volatile_set_memory") => { memset_intrinsic(bcx, true, - substs.types[0], + substs.type_at(0), llargs[0], llargs[1], llargs[2], call_debug_location) } (_, "volatile_load") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); let mut ptr = llargs[0]; if let Some(ty) = fn_ty.ret.cast { ptr = PointerCast(bcx, ptr, ty.ptr_to()); @@ -306,7 +306,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, to_immediate(bcx, load, tp_ty) }, (_, "volatile_store") => { - let tp_ty = substs.types[0]; + let tp_ty = substs.type_at(0); if type_is_fat_ptr(bcx.tcx(), tp_ty) { VolatileStore(bcx, llargs[1], get_dataptr(bcx, llargs[0])); VolatileStore(bcx, llargs[2], get_meta(bcx, llargs[0])); @@ -406,7 +406,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, }, (_, "discriminant_value") => { - let val_ty = substs.types[0]; + let val_ty = substs.type_at(0); match val_ty.sty { ty::TyEnum(..) => { let repr = adt::represent_type(ccx, val_ty); @@ -458,7 +458,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, match split[1] { "cxchg" | "cxchgweak" => { - let sty = &substs.types[0].sty; + let sty = &substs.type_at(0).sty; if int_type_width_signed(sty, ccx).is_some() { let weak = if split[1] == "cxchgweak" { llvm::True } else { llvm::False }; let val = AtomicCmpXchg(bcx, llargs[0], llargs[1], llargs[2], @@ -477,7 +477,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } "load" => { - let sty = &substs.types[0].sty; + let sty = &substs.type_at(0).sty; if int_type_width_signed(sty, ccx).is_some() { AtomicLoad(bcx, llargs[0], order) } else { @@ -490,7 +490,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } "store" => { - let sty = &substs.types[0].sty; + let sty = &substs.type_at(0).sty; if int_type_width_signed(sty, ccx).is_some() { AtomicStore(bcx, llargs[1], llargs[0], order); } else { @@ -529,7 +529,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, _ => ccx.sess().fatal("unknown atomic operation") }; - let sty = &substs.types[0].sty; + let sty = &substs.type_at(0).sty; if int_type_width_signed(sty, ccx).is_some() { AtomicRMW(bcx, atom_op, llargs[0], llargs[1], order) } else { diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 97c77ee3d8c72..483bc99c310fc 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -265,7 +265,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // the method may have some early-bound lifetimes, add // regions for those let method_substs = Substs::for_item(tcx, trait_method_def_id, - |_, _| ty::ReErased, + |_, _| tcx.mk_region(ty::ReErased), |_, _| tcx.types.err); // The substitutions we have are on the impl, so we grab @@ -307,7 +307,7 @@ pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, name: Name) -> ImplMethod<'tcx> { - assert!(!substs.types.needs_infer()); + assert!(!substs.needs_infer()); let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); let trait_def = tcx.lookup_trait_def(trait_def_id); diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index 020ac8d643b86..0ffb83067f91c 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -32,7 +32,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> { impl<'tcx> Instance<'tcx> { pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>) -> Instance<'tcx> { - assert!(substs.regions.iter().all(|&r| r == ty::ReErased)); + assert!(substs.regions().all(|&r| r == ty::ReErased)); Instance { def: def_id, substs: substs } } pub fn mono<'a>(scx: &SharedCrateContext<'a, 'tcx>, def_id: DefId) -> Instance<'tcx> { diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index 87d0ea0fe81f3..7341e8db41de5 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -342,7 +342,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, TransItem::DropGlue(..) => unreachable!(), // Is there any benefit to using ExternalLinkage?: TransItem::Fn(ref instance) => { - if instance.substs.types.is_empty() { + if instance.substs.types().next().is_none() { // This is a non-generic functions, we always // make it visible externally on the chance that // it might be used in another codegen unit. @@ -487,7 +487,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[0]; + let self_ty = instance.substs.type_at(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_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 90dcc3a61fd7e..2c91c408487b8 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -171,8 +171,8 @@ impl<'a, 'tcx> TransItem<'tcx> { instance: Instance<'tcx>, linkage: llvm::Linkage, symbol_name: &str) { - assert!(!instance.substs.types.needs_infer() && - !instance.substs.types.has_param_types()); + assert!(!instance.substs.needs_infer() && + !instance.substs.has_param_types()); let item_ty = ccx.tcx().lookup_item_type(instance.def).ty; let item_ty = ccx.tcx().erase_regions(&item_ty); @@ -244,7 +244,7 @@ impl<'a, 'tcx> TransItem<'tcx> { pub fn requests_inline(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { match *self { TransItem::Fn(ref instance) => { - !instance.substs.types.is_empty() || { + instance.substs.types().next().is_some() || { let attributes = tcx.get_attrs(instance.def); attr::requests_inline(&attributes[..]) } @@ -264,8 +264,9 @@ impl<'a, 'tcx> TransItem<'tcx> { pub fn is_instantiated_only_on_demand(&self) -> bool { match *self { - TransItem::Fn(ref instance) => !instance.def.is_local() || - !instance.substs.types.is_empty(), + TransItem::Fn(ref instance) => { + !instance.def.is_local() || instance.substs.types().next().is_some() + } TransItem::DropGlue(..) => true, TransItem::Static(..) => false, } @@ -273,7 +274,9 @@ impl<'a, 'tcx> TransItem<'tcx> { pub fn is_generic_fn(&self) -> bool { match *self { - TransItem::Fn(ref instance) => !instance.substs.types.is_empty(), + TransItem::Fn(ref instance) => { + instance.substs.types().next().is_some() + } TransItem::DropGlue(..) | TransItem::Static(..) => false, } @@ -374,7 +377,7 @@ impl<'a, 'tcx> TransItem<'tcx> { /// Same as `unique_type_name()` but with the result pushed onto the given /// `output` parameter. pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - t: ty::Ty<'tcx>, + t: Ty<'tcx>, output: &mut String) { match t.sty { ty::TyBool => output.push_str("bool"), @@ -396,7 +399,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TyStruct(adt_def, substs) | ty::TyEnum(adt_def, substs) => { push_item_name(tcx, adt_def.did, output); - push_type_params(tcx, &substs.types, &[], output); + push_type_params(tcx, substs, &[], output); }, ty::TyTuple(component_types) => { output.push('('); @@ -446,7 +449,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TyTrait(ref trait_data) => { push_item_name(tcx, trait_data.principal.def_id(), output); push_type_params(tcx, - &trait_data.principal.skip_binder().substs.types, + trait_data.principal.skip_binder().substs, &trait_data.projection_bounds, output); }, @@ -494,7 +497,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, output.push_str("{"); output.push_str(&format!("{}:{}", def_id.krate, def_id.index.as_usize())); output.push_str("}"); - push_type_params(tcx, &closure_substs.func_substs.types, &[], output); + push_type_params(tcx, closure_substs.func_substs, &[], output); } ty::TyError | ty::TyInfer(_) | @@ -529,16 +532,16 @@ fn push_item_name(tcx: TyCtxt, } fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - types: &[Ty<'tcx>], + substs: &Substs<'tcx>, projections: &[ty::PolyExistentialProjection<'tcx>], output: &mut String) { - if types.is_empty() && projections.is_empty() { + if substs.types().next().is_none() && projections.is_empty() { return; } output.push('<'); - for &type_parameter in types { + for type_parameter in substs.types() { push_unique_type_name(tcx, type_parameter, output); output.push_str(", "); } @@ -562,7 +565,7 @@ fn push_instance_as_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, output: &mut String) { push_item_name(tcx, instance.def, output); - push_type_params(tcx, &instance.substs.types, &[], output); + push_type_params(tcx, instance.substs, &[], output); } pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String { @@ -572,7 +575,7 @@ pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String { } pub fn type_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: ty::Ty<'tcx>) + ty: Ty<'tcx>) -> String { let mut output = String::new(); push_unique_type_name(tcx, ty, &mut output); diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 6862002ed83b2..b47d2cd0f204b 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -17,6 +17,7 @@ use common::*; use machine; use rustc::traits::Reveal; use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::subst::Substs; use type_::Type; @@ -256,7 +257,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> // avoids creating more than one copy of the enum when one // of the enum's variants refers to the enum itself. let repr = adt::represent_type(cx, t); - let name = llvm_type_name(cx, def.did, &substs.types); + let name = llvm_type_name(cx, def.did, substs); adt::incomplete_type_of(cx, &repr, &name[..]) } ty::TyClosure(..) => { @@ -330,7 +331,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> // in *after* placing it into the type cache. This prevents // infinite recursion with recursive struct types. let repr = adt::represent_type(cx, t); - let name = llvm_type_name(cx, def.did, &substs.types); + let name = llvm_type_name(cx, def.did, substs); adt::incomplete_type_of(cx, &repr, &name[..]) } } @@ -367,10 +368,10 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, did: DefId, - tps: &[Ty<'tcx>]) + substs: &Substs<'tcx>) -> String { let base = cx.tcx().item_path_str(did); - let strings: Vec = tps.iter().map(|t| t.to_string()).collect(); + let strings: Vec = substs.types().map(|t| t.to_string()).collect(); let tstr = if strings.is_empty() { base } else { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f6984f42cab34..f24a7cf2121eb 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -178,8 +178,9 @@ type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec = ty::TyInfer(ty::FreshTy(0)); -pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime) - -> ty::Region { +pub fn ast_region_to_region<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + lifetime: &hir::Lifetime) + -> &'tcx ty::Region { let r = match tcx.named_region_map.defs.get(&lifetime.id) { None => { // should have been recorded by the `resolve_lifetime` pass @@ -238,7 +239,7 @@ pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime) lifetime.id, r); - r + tcx.mk_region(r) } fn report_elision_failure( @@ -313,14 +314,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { pub fn opt_ast_region_to_region(&self, rscope: &RegionScope, default_span: Span, - opt_lifetime: &Option) -> ty::Region + opt_lifetime: &Option) -> &'tcx ty::Region { let r = match *opt_lifetime { Some(ref lifetime) => { ast_region_to_region(self.tcx(), lifetime) } - None => match rscope.anon_regions(default_span, 1) { + None => self.tcx().mk_region(match rscope.anon_regions(default_span, 1) { Ok(rs) => rs[0], Err(params) => { let ampersand_span = Span { hi: default_span.lo, ..default_span}; @@ -335,7 +336,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { err.emit(); ty::ReStatic } - } + }) }; debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {:?}", @@ -366,7 +367,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { .emit(); return Substs::for_item(tcx, def_id, |_, _| { - ty::ReStatic + tcx.mk_region(ty::ReStatic) }, |_, _| { tcx.types.err }); @@ -431,7 +432,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let expected_num_region_params = decl_generics.regions.len(); let supplied_num_region_params = lifetimes.len(); let regions = if expected_num_region_params == supplied_num_region_params { - lifetimes.iter().map(|l| ast_region_to_region(tcx, l)).collect() + lifetimes.iter().map(|l| *ast_region_to_region(tcx, l)).collect() } else { let anon_regions = rscope.anon_regions(span, expected_num_region_params); @@ -472,7 +473,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let mut output_assoc_binding = None; let substs = Substs::for_item(tcx, def_id, |def, _| { - regions[def.index as usize] + let i = def.index as usize - self_ty.is_some() as usize; + tcx.mk_region(regions[i]) }, |def, substs| { let i = def.index as usize; @@ -481,7 +483,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { return ty; } - let i = i - self_ty.is_some() as usize; + let i = i - self_ty.is_some() as usize - decl_generics.regions.len(); if num_types_provided.map_or(false, |n| i < n) { // A provided type parameter. match *parameters { @@ -588,7 +590,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } if lifetimes_for_params.iter().map(|e| e.lifetime_count).sum::() == 1 { - Ok(possible_implied_output_region.unwrap()) + Ok(*possible_implied_output_region.unwrap()) } else { Err(Some(lifetimes_for_params)) } @@ -937,8 +939,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // FIXME(#12938): This is a hack until we have full support for DST. if Some(did) == self.tcx().lang_items.owned_box() { - assert_eq!(substs.types.len(), 1); - return self.tcx().mk_box(substs.types[0]); + assert_eq!(substs.types().count(), 1); + return self.tcx().mk_box(substs.type_at(0)); } decl_ty.subst(self.tcx(), substs) @@ -1100,7 +1102,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let region_bound = match region_bound { Some(r) => r, None => { - match rscope.object_lifetime_default(span) { + tcx.mk_region(match rscope.object_lifetime_default(span) { Some(r) => r, None => { span_err!(self.tcx().sess, span, E0228, @@ -1108,7 +1110,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { from context; please supply an explicit bound"); ty::ReStatic } - } + }) } }; @@ -1643,7 +1645,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { rscope, ty::ObjectLifetimeDefault::Specific(r)); let t = self.ast_ty_to_ty(rscope1, &mt.ty); - tcx.mk_ref(tcx.mk_region(r), ty::TypeAndMut {ty: t, mutbl: mt.mutbl}) + tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl}) } hir::TyNever => { tcx.types.never @@ -1801,7 +1803,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { sig: &hir::MethodSig, untransformed_self_ty: Ty<'tcx>, anon_scope: Option) - -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) { + -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>) { self.ty_of_method_or_bare_fn(sig.unsafety, sig.abi, Some(untransformed_self_ty), @@ -1826,7 +1828,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { decl: &hir::FnDecl, arg_anon_scope: Option, ret_anon_scope: Option) - -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) + -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory<'tcx>) { debug!("ty_of_method_or_bare_fn"); @@ -1863,7 +1865,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // reference) in the arguments, then any anonymous regions in the output // have that lifetime. let implied_output_region = match explicit_self_category { - ty::ExplicitSelfCategory::ByReference(region, _) => Ok(region), + ty::ExplicitSelfCategory::ByReference(region, _) => Ok(*region), _ => self.find_implied_output_region(&arg_tys, arg_pats) }; @@ -1890,7 +1892,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { rscope: &RegionScope, untransformed_self_ty: Ty<'tcx>, explicit_self: &hir::ExplicitSelf) - -> (Ty<'tcx>, ty::ExplicitSelfCategory) + -> (Ty<'tcx>, ty::ExplicitSelfCategory<'tcx>) { return match explicit_self.node { SelfKind::Value(..) => { @@ -1902,8 +1904,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { rscope, explicit_self.span, lifetime); - (self.tcx().mk_ref( - self.tcx().mk_region(region), + (self.tcx().mk_ref(region, ty::TypeAndMut { ty: untransformed_self_ty, mutbl: mutability @@ -1957,7 +1958,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { ty::ExplicitSelfCategory::ByValue } else { match explicit_type.sty { - ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(*r, mt.mutbl), + ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(r, mt.mutbl), ty::TyBox(_) => ty::ExplicitSelfCategory::ByBox, _ => ty::ExplicitSelfCategory::ByValue, } @@ -2070,7 +2071,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { explicit_region_bounds: &[&hir::Lifetime], principal_trait_ref: ty::PolyExistentialTraitRef<'tcx>, builtin_bounds: ty::BuiltinBounds) - -> Option // if None, use the default + -> Option<&'tcx ty::Region> // if None, use the default { let tcx = self.tcx(); @@ -2093,7 +2094,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { if let Err(ErrorReported) = self.ensure_super_predicates(span, principal_trait_ref.def_id()) { - return Some(ty::ReStatic); + return Some(tcx.mk_region(ty::ReStatic)); } // No explicit region bound specified. Therefore, examine trait @@ -2109,8 +2110,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // If any of the derived region bounds are 'static, that is always // the best choice. - if derived_region_bounds.iter().any(|r| ty::ReStatic == *r) { - return Some(ty::ReStatic); + if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) { + return Some(tcx.mk_region(ty::ReStatic)); } // Determine whether there is exactly one unique region in the set @@ -2242,7 +2243,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected // and return from functions in multiple places. #[derive(PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { - pub region_bounds: Vec, + pub region_bounds: Vec<&'tcx ty::Region>, pub builtin_bounds: ty::BuiltinBounds, pub trait_bounds: Vec>, pub projection_bounds: Vec>, @@ -2264,7 +2265,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> { for ®ion_bound in &self.region_bounds { // account for the binder being introduced below; no need to shift `param_ty` // because, at present at least, it can only refer to early-bound regions - let region_bound = ty::fold::shift_region(region_bound, 1); + let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1)); vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate()); } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 52073359c0fd9..78175c85b19bf 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -122,7 +122,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // and T is the expected type. let region_var = self.next_region_var(infer::PatternRegion(pat.span)); let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl }; - let region_ty = tcx.mk_ref(tcx.mk_region(region_var), mt); + let region_ty = tcx.mk_ref(region_var, mt); // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is // required. However, we use equality, which is stronger. See (*) for @@ -220,7 +220,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let inner_ty = self.next_ty_var(); let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl }; let region = self.next_region_var(infer::PatternRegion(pat.span)); - let rptr_ty = tcx.mk_ref(tcx.mk_region(region), mt); + let rptr_ty = tcx.mk_ref(region, mt); self.demand_eqtype(pat.span, expected, rptr_ty); (rptr_ty, inner_ty) } diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 9a3cbabe55331..19261a2447f91 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> { Some(f) => f, None => return None }, - substs: Substs::new_trait(tcx, vec![], vec![], self.cur_ty) + substs: Substs::new_trait(tcx, self.cur_ty, &[]) }; let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 377ca5eaebe30..46e8c27f6d33b 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -203,7 +203,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return None; } - let arg_param_ty = trait_ref.substs().types[1]; + let arg_param_ty = trait_ref.substs().type_at(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/coercion.rs b/src/librustc_typeck/check/coercion.rs index 4a0d529812891..26a4705528976 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -336,7 +336,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { if r_borrow_var.is_none() { // create var lazilly, at most once let coercion = Coercion(span); let r = self.next_region_var(coercion); - r_borrow_var = Some(self.tcx.mk_region(r)); // [4] above + r_borrow_var = Some(r); // [4] above } r_borrow_var.unwrap() }; @@ -436,8 +436,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let coercion = Coercion(self.origin.span()); let r_borrow = self.next_region_var(coercion); - let region = self.tcx.mk_region(r_borrow); - (mt_a.ty, Some(AutoPtr(region, mt_b.mutbl))) + (mt_a.ty, Some(AutoPtr(r_borrow, mt_b.mutbl))) } (&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) => { coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?; @@ -459,7 +458,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { coerce_unsized_did, 0, source, - vec![target])); + &[target])); // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 82545d564a20c..cede9d871ff4d 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -412,7 +412,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>( ty); cx.rcx.type_must_outlive(infer::SubregionOrigin::SafeDestructor(cx.span), - ty, ty::ReScope(cx.parent_scope)); + ty, tcx.mk_region(ty::ReScope(cx.parent_scope))); return Ok(()); } @@ -438,7 +438,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>( ty::TyStruct(def, substs) if def.is_phantom_data() => { // PhantomData - behaves identically to T - let ity = substs.types[0]; + let ity = substs.type_at(0); iterate_over_potentially_unsafe_regions_in_type( cx, context, ity, depth+1) } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 7f9e715b7fafc..ad48827a1d039 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -37,7 +37,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let i_ty = tcx.lookup_item_type(def_id); let substs = Substs::for_item(tcx, def_id, - |_, _| ty::ReErased, + |_, _| tcx.mk_region(ty::ReErased), |def, _| tcx.mk_param_from_def(def)); let fty = tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy { diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 9e0b38fd9fe51..be77ca435a18c 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -145,7 +145,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { { let (autoref, unsize) = if let Some(mutbl) = pick.autoref { let region = self.next_region_var(infer::Autoref(self.span)); - let autoref = AutoPtr(self.tcx.mk_region(region), mutbl); + let autoref = AutoPtr(region, mutbl); (Some(autoref), pick.unsize.map(|target| { target.adjust_for_autoref(self.tcx, Some(autoref)) })) @@ -327,19 +327,22 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // parameters from the type and those from the method. // // FIXME -- permit users to manually specify lifetimes + let supplied_start = substs.params().len() + method.generics.regions.len(); Substs::for_item(self.tcx, method.def_id, |def, _| { - if let Some(&r) = substs.regions.get(def.index as usize) { - r + let i = def.index as usize; + if i < substs.params().len() { + substs.region_at(i) } else { self.region_var_for_def(self.span, def) } }, |def, cur_substs| { - if let Some(&ty) = substs.types.get(def.index as usize) { - ty + let i = def.index as usize; + if i < substs.params().len() { + substs.type_at(i) } else if supplied_method_types.is_empty() { self.type_var_for_def(self.span, def, cur_substs) } else { - supplied_method_types[def.index as usize - substs.types.len()] + supplied_method_types[i - supplied_start] } }) } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index c306463ec1de0..a64982cd1bf81 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -519,9 +519,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { trait_ref.substs, m); assert_eq!(m.generics.parent_types as usize, - trait_ref.substs.types.len()); + trait_ref.substs.types().count()); assert_eq!(m.generics.parent_regions as usize, - trait_ref.substs.regions.len()); + trait_ref.substs.regions().count()); } // Because this trait derives from a where-clause, it @@ -529,7 +529,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // artifacts. This means it is safe to put into the // `WhereClauseCandidate` and (eventually) into the // `WhereClausePick`. - assert!(!trait_ref.substs.types.needs_infer()); + assert!(!trait_ref.substs.needs_infer()); this.inherent_candidates.push(Candidate { xform_self_ty: xform_self_ty, @@ -1220,8 +1220,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // are given do not include type/lifetime parameters for the // method yet. So create fresh variables here for those too, // if there are any. - assert_eq!(substs.types.len(), method.generics.parent_types as usize); - assert_eq!(substs.regions.len(), method.generics.parent_regions as usize); + assert_eq!(substs.types().count(), method.generics.parent_types as usize); + assert_eq!(substs.regions().count(), method.generics.parent_regions as usize); if self.mode == Mode::Path { return impl_ty; @@ -1236,16 +1236,18 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { xform_self_ty.subst(self.tcx, substs) } else { let substs = Substs::for_item(self.tcx, method.def_id, |def, _| { - if let Some(&r) = substs.regions.get(def.index as usize) { - r + let i = def.index as usize; + if i < substs.params().len() { + substs.region_at(i) } else { // In general, during probe we erase regions. See // `impl_self_ty()` for an explanation. - ty::ReErased + self.tcx.mk_region(ty::ReErased) } }, |def, cur_substs| { - if let Some(&ty) = substs.types.get(def.index as usize) { - ty + let i = def.index as usize; + if i < substs.params().len() { + substs.type_at(i) } else { self.type_var_for_def(self.span, def, cur_substs) } @@ -1262,7 +1264,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let impl_ty = self.tcx.lookup_item_type(impl_def_id).ty; let substs = Substs::for_item(self.tcx, impl_def_id, - |_, _| ty::ReErased, + |_, _| self.tcx.mk_region(ty::ReErased), |_, _| self.next_ty_var()); (impl_ty, substs) @@ -1324,7 +1326,7 @@ impl<'tcx> Candidate<'tcx> { // inference variables or other artifacts. This // means they are safe to put into the // `WhereClausePick`. - assert!(!trait_ref.substs().types.needs_infer()); + assert!(!trait_ref.substs().needs_infer()); WhereClausePick(trait_ref.clone()) } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 573dae46456ba..f9699a55f5068 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -54,7 +54,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.autoderef(span, ty).any(|(ty, _)| self.probe(|_| { let fn_once_substs = - Substs::new_trait(tcx, vec![self.next_ty_var()], vec![], ty); + Substs::new_trait(tcx, ty, &[self.next_ty_var()]); let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); let poly_trait_ref = trait_ref.to_poly_trait_ref(); let obligation = Obligation::misc(span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 16300d869abf5..e972a5ca7fb38 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -770,7 +770,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } hir::ItemTy(_, ref generics) => { let pty_ty = ccx.tcx.node_id_to_type(it.id); - check_bounds_are_used(ccx, &generics.ty_params, pty_ty); + check_bounds_are_used(ccx, generics, pty_ty); } hir::ItemForeignMod(ref m) => { if m.abi == Abi::RustIntrinsic { @@ -1422,13 +1422,13 @@ impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> { // (and anyway, within a fn body the right region may not even // be something the user can write explicitly, since it might // be some expression). - self.next_region_var(infer::MiscVariable(span)) + *self.next_region_var(infer::MiscVariable(span)) } fn anon_regions(&self, span: Span, count: usize) -> Result, Option>> { Ok((0..count).map(|_| { - self.next_region_var(infer::MiscVariable(span)) + *self.next_region_var(infer::MiscVariable(span)) }).collect()) } } @@ -1862,7 +1862,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// outlive the region `r`. pub fn register_region_obligation(&self, ty: Ty<'tcx>, - region: ty::Region, + region: &'tcx ty::Region, cause: traits::ObligationCause<'tcx>) { let mut fulfillment_cx = self.fulfillment_cx.borrow_mut(); @@ -1893,13 +1893,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually let cause = traits::ObligationCause::new(span, self.body_id, code); - self.register_region_obligation(ty, ty::ReEmpty, cause); + self.register_region_obligation(ty, self.tcx.mk_region(ty::ReEmpty), cause); } /// Registers obligations that all types appearing in `substs` are well-formed. pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr) { - for &ty in &substs.types { + for ty in substs.types() { self.register_wf_obligation(ty, expr.span, traits::MiscObligation); } } @@ -3454,7 +3454,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // value whose address was taken can actually be made to live // as long as it needs to live. let region = self.next_region_var(infer::AddrOfRegion(expr.span)); - tcx.mk_ref(tcx.mk_region(region), tm) + tcx.mk_ref(region, tm) }; self.write_ty(id, oprnd_t); } @@ -4242,18 +4242,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.check_path_parameter_count(span, !require_type_space, &mut type_segment); self.check_path_parameter_count(span, true, &mut fn_segment); + let (fn_start, has_self) = match (type_segment, fn_segment) { + (_, Some((_, generics))) => { + (generics.parent_count(), generics.has_self) + } + (Some((_, generics)), None) => { + (generics.own_count(), generics.has_self) + } + (None, None) => (0, false) + }; let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| { let mut i = def.index as usize; - let type_regions = match (type_segment, fn_segment) { - (_, Some((_, generics))) => generics.parent_regions as usize, - (Some((_, generics)), None) => generics.regions.len(), - (None, None) => 0 - }; - let segment = if i < type_regions { + let segment = if i < fn_start { + i -= has_self as usize; type_segment } else { - i -= type_regions; + i -= fn_start; fn_segment }; let lifetimes = match segment.map(|(s, _)| &s.parameters) { @@ -4269,18 +4274,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }, |def, substs| { let mut i = def.index as usize; - let (type_types, has_self) = match (type_segment, fn_segment) { - (_, Some((_, generics))) => { - (generics.parent_types as usize, generics.has_self) - } - (Some((_, generics)), None) => { - (generics.types.len(), generics.has_self) - } - (None, None) => (0, false) - }; - let can_omit = i >= type_types || !require_type_space; - let segment = if i < type_types { + let can_omit = i >= fn_start || !require_type_space; + let segment = if i < fn_start { // Handle Self first, so we can adjust the index to match the AST. if has_self && i == 0 { return opt_self_ty.unwrap_or_else(|| { @@ -4290,7 +4286,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { i -= has_self as usize; type_segment } else { - i -= type_types; + i -= fn_start; fn_segment }; let types = match segment.map(|(s, _)| &s.parameters) { @@ -4299,6 +4295,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None => &[] }; + // Skip over the lifetimes in the same segment. + if let Some((_, generics)) = segment { + i -= generics.regions.len(); + } + let omitted = can_omit && types.is_empty(); if let Some(ast_ty) = types.get(i) { // A provided type parameter. @@ -4502,28 +4503,28 @@ pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool { } pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - tps: &[hir::TyParam], + generics: &hir::Generics, ty: Ty<'tcx>) { debug!("check_bounds_are_used(n_tps={}, ty={:?})", - tps.len(), ty); + generics.ty_params.len(), ty); // make a vector of booleans initially false, set to true when used - if tps.is_empty() { return; } - let mut tps_used = vec![false; tps.len()]; + if generics.ty_params.is_empty() { return; } + let mut tps_used = vec![false; generics.ty_params.len()]; for leaf_ty in ty.walk() { if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty { debug!("Found use of ty param num {}", idx); - tps_used[idx as usize] = true; + tps_used[idx as usize - generics.lifetimes.len()] = true; } } - for (i, b) in tps_used.iter().enumerate() { - if !*b { - struct_span_err!(ccx.tcx.sess, tps[i].span, E0091, + for (&used, param) in tps_used.iter().zip(&generics.ty_params) { + if !used { + struct_span_err!(ccx.tcx.sess, param.span, E0091, "type parameter `{}` is unused", - tps[i].name) - .span_label(tps[i].span, &format!("unused type parameter")) + param.name) + .span_label(param.span, &format!("unused type parameter")) .emit(); } } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 859d5ff0543d0..cef2bb07e35ca 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -169,7 +169,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, - region_bound_pairs: Vec<(ty::Region, GenericKind<'tcx>)>, + region_bound_pairs: Vec<(&'tcx ty::Region, GenericKind<'tcx>)>, free_region_map: FreeRegionMap, @@ -324,9 +324,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let call_site_scope = self.call_site_scope.unwrap(); debug!("visit_fn_body body.id {} call_site_scope: {:?}", body.id, call_site_scope); + let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope)); self.type_of_node_must_outlive(infer::CallReturn(span), body.id, - ty::ReScope(call_site_scope)); + call_site_region); self.region_bound_pairs.truncate(old_region_bounds_pairs_len); @@ -407,8 +408,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { for implication in implied_bounds { debug!("implication: {:?}", implication); match implication { - ImpliedBound::RegionSubRegion(ty::ReFree(free_a), - ty::ReVar(vid_b)) => { + ImpliedBound::RegionSubRegion(&ty::ReFree(free_a), + &ty::ReVar(vid_b)) => { self.add_given(free_a, vid_b); } ImpliedBound::RegionSubParam(r_a, param_b) => { @@ -476,9 +477,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // variable's type enclose at least the variable's scope. let var_scope = tcx.region_maps.var_scope(id); + let var_region = self.tcx.mk_region(ty::ReScope(var_scope)); let origin = infer::BindingTypeIsNotValidAtDecl(span); - self.type_of_node_must_outlive(origin, id, ty::ReScope(var_scope)); + self.type_of_node_must_outlive(origin, id, var_region); let typ = self.resolve_node_type(id); dropck::check_safety_of_destructor_if_necessary(self, typ, span, var_scope); @@ -525,7 +527,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { // scope of that expression. This also guarantees basic WF. let expr_ty = self.resolve_node_type(expr.id); // the region corresponding to this expression - let expr_region = ty::ReScope(self.tcx.region_maps.node_extent(expr.id)); + let expr_region = self.tcx.node_scope_region(expr.id); self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span), expr_ty, expr_region); @@ -713,7 +715,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { None => self.resolve_node_type(base.id) }; if let ty::TyRef(r_ptr, _) = base_ty.sty { - self.mk_subregion_due_to_dereference(expr.span, expr_region, *r_ptr); + self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr); } intravisit::walk_expr(self, expr); @@ -780,9 +782,10 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { let call_site_scope = self.call_site_scope; debug!("visit_expr ExprRet ret_expr.id {} call_site_scope: {:?}", ret_expr.id, call_site_scope); + let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope.unwrap())); self.type_of_node_must_outlive(infer::CallReturn(ret_expr.span), ret_expr.id, - ty::ReScope(call_site_scope.unwrap())); + call_site_region); intravisit::walk_expr(self, expr); } @@ -819,7 +822,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /*From:*/ (&ty::TyRef(from_r, ref from_mt), /*To: */ &ty::TyRef(to_r, ref to_mt)) => { // Target cannot outlive source, naturally. - self.sub_regions(infer::Reborrow(cast_expr.span), *to_r, *from_r); + self.sub_regions(infer::Reborrow(cast_expr.span), to_r, from_r); self.walk_cast(cast_expr, from_mt.ty, to_mt.ty); } @@ -889,7 +892,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // // FIXME(#6268) to support nested method calls, should be callee_id let callee_scope = self.tcx.region_maps.node_extent(call_expr.id); - let callee_region = ty::ReScope(callee_scope); + let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope)); debug!("callee_region={:?}", callee_region); @@ -933,8 +936,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { derefs, derefd_ty); - let s_deref_expr = self.tcx.region_maps.node_extent(deref_expr.id); - let r_deref_expr = ty::ReScope(s_deref_expr); + let r_deref_expr = self.tcx.node_scope_region(deref_expr.id); for i in 0..derefs { let method_call = MethodCall::autoderef(deref_expr.id, i as u32); debug!("constrain_autoderefs: method_call={:?} (of {:?} total)", method_call, derefs); @@ -989,7 +991,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { if let ty::TyRef(r_ptr, _) = derefd_ty.sty { self.mk_subregion_due_to_dereference(deref_expr.span, - r_deref_expr, *r_ptr); + r_deref_expr, r_ptr); } match derefd_ty.builtin_deref(true, ty::NoPreference) { @@ -1003,8 +1005,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { pub fn mk_subregion_due_to_dereference(&mut self, deref_span: Span, - minimum_lifetime: ty::Region, - maximum_lifetime: ty::Region) { + minimum_lifetime: &'tcx ty::Region, + maximum_lifetime: &'tcx ty::Region) { self.sub_regions(infer::DerefPointer(deref_span), minimum_lifetime, maximum_lifetime) } @@ -1014,7 +1016,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { span: Span) { match cmt.cat { Categorization::Rvalue(region) => { - match region { + match *region { ty::ReScope(rvalue_scope) => { let typ = self.resolve_type(cmt.ty); dropck::check_safety_of_destructor_if_necessary(self, @@ -1023,7 +1025,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { rvalue_scope); } ty::ReStatic => {} - region => { + _ => { span_bug!(span, "unexpected rvalue region in rvalue \ destructor safety checking: `{:?}`", @@ -1049,7 +1051,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { match mt.ty.sty { ty::TySlice(_) | ty::TyStr => { self.sub_regions(infer::IndexSlice(index_expr.span), - r_index_expr, *r_ptr); + self.tcx.mk_region(r_index_expr), r_ptr); } _ => {} } @@ -1061,7 +1063,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn type_of_node_must_outlive(&mut self, origin: infer::SubregionOrigin<'tcx>, id: ast::NodeId, - minimum_lifetime: ty::Region) + minimum_lifetime: &'tcx ty::Region) { let tcx = self.tcx; @@ -1132,7 +1134,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let mc = mc::MemCategorizationContext::new(self); for arg in args { let arg_ty = self.node_ty(arg.id); - let re_scope = ty::ReScope(body_scope); + let re_scope = self.tcx.mk_region(ty::ReScope(body_scope)); let arg_cmt = mc.cat_rvalue(arg.id, arg.ty.span, re_scope, arg_ty); debug!("arg_ty={:?} arg_cmt={:?} arg={:?}", arg_ty, @@ -1168,7 +1170,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn link_autoref(&self, expr: &hir::Expr, autoderefs: usize, - autoref: &adjustment::AutoRef) + autoref: &adjustment::AutoRef<'tcx>) { debug!("link_autoref(autoref={:?})", autoref); let mc = mc::MemCategorizationContext::new(self); @@ -1182,8 +1184,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } adjustment::AutoUnsafe(m) => { - let r = ty::ReScope(self.tcx.region_maps.node_extent(expr.id)); - self.link_region(expr.span, &r, ty::BorrowKind::from_mutbl(m), expr_cmt); + let r = self.tcx.node_scope_region(expr.id); + self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt); } } } @@ -1197,8 +1199,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { expr, callee_scope); let mc = mc::MemCategorizationContext::new(self); let expr_cmt = ignore_err!(mc.cat_expr(expr)); - let borrow_region = ty::ReScope(callee_scope); - self.link_region(expr.span, &borrow_region, ty::ImmBorrow, expr_cmt); + let borrow_region = self.tcx.mk_region(ty::ReScope(callee_scope)); + self.link_region(expr.span, borrow_region, ty::ImmBorrow, expr_cmt); } /// Like `link_region()`, except that the region is extracted from the type of `id`, @@ -1212,9 +1214,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { id, mutbl, cmt_borrowed); let rptr_ty = self.resolve_node_type(id); - if let ty::TyRef(&r, _) = rptr_ty.sty { + if let ty::TyRef(r, _) = rptr_ty.sty { debug!("rptr_ty={}", rptr_ty); - self.link_region(span, &r, ty::BorrowKind::from_mutbl(mutbl), + self.link_region(span, r, ty::BorrowKind::from_mutbl(mutbl), cmt_borrowed); } } @@ -1225,14 +1227,14 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// between regions, as explained in `link_reborrowed_region()`. fn link_region(&self, span: Span, - borrow_region: &ty::Region, + borrow_region: &'tcx ty::Region, borrow_kind: ty::BorrowKind, borrow_cmt: mc::cmt<'tcx>) { let mut borrow_cmt = borrow_cmt; let mut borrow_kind = borrow_kind; let origin = infer::DataBorrowed(borrow_cmt.ty, span); - self.type_must_outlive(origin, borrow_cmt.ty, *borrow_region); + self.type_must_outlive(origin, borrow_cmt.ty, borrow_region); loop { debug!("link_region(borrow_region={:?}, borrow_kind={:?}, borrow_cmt={:?})", @@ -1322,10 +1324,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// recurse and process `ref_cmt` (see case 2 above). fn link_reborrowed_region(&self, span: Span, - borrow_region: &ty::Region, + borrow_region: &'tcx ty::Region, borrow_kind: ty::BorrowKind, ref_cmt: mc::cmt<'tcx>, - ref_region: ty::Region, + ref_region: &'tcx ty::Region, mut ref_kind: ty::BorrowKind, note: mc::Note) -> Option<(mc::cmt<'tcx>, ty::BorrowKind)> @@ -1364,7 +1366,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("link_reborrowed_region: {:?} <= {:?}", borrow_region, ref_region); - self.sub_regions(cause, *borrow_region, ref_region); + self.sub_regions(cause, borrow_region, ref_region); // If we end up needing to recurse and establish a region link // with `ref_cmt`, calculate what borrow kind we will end up @@ -1436,7 +1438,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { origin: infer::ParameterOrigin, substs: &Substs<'tcx>, expr_span: Span, - expr_region: ty::Region) { + expr_region: &'tcx ty::Region) { debug!("substs_wf_in_scope(substs={:?}, \ expr_region={:?}, \ origin={:?}, \ @@ -1445,11 +1447,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let origin = infer::ParameterInScope(origin, expr_span); - for ®ion in &substs.regions { + for region in substs.regions() { self.sub_regions(origin.clone(), expr_region, region); } - for &ty in &substs.types { + for ty in substs.types() { let ty = self.resolve_type(ty); self.type_must_outlive(origin.clone(), ty, expr_region); } @@ -1461,7 +1463,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { pub fn type_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, ty: Ty<'tcx>, - region: ty::Region) + region: &'tcx ty::Region) { let ty = self.resolve_type(ty); @@ -1479,7 +1481,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn components_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, components: Vec>, - region: ty::Region) + region: &'tcx ty::Region) { for component in components { let origin = origin.clone(); @@ -1510,7 +1512,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn param_ty_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, - region: ty::Region, + region: &'tcx ty::Region, param_ty: ty::ParamTy) { debug!("param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})", region, param_ty, origin); @@ -1522,7 +1524,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn projection_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, - region: ty::Region, + region: &'tcx ty::Region, projection_ty: ty::ProjectionTy<'tcx>) { debug!("projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})", @@ -1552,7 +1554,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // If we know that the projection outlives 'static, then we're // done here. - if env_bounds.contains(&ty::ReStatic) { + if env_bounds.contains(&&ty::ReStatic) { debug!("projection_must_outlive: 'static as declared bound"); return; } @@ -1575,11 +1577,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { if env_bounds.is_empty() && needs_infer { debug!("projection_must_outlive: no declared bounds"); - for &component_ty in &projection_ty.trait_ref.substs.types { + for component_ty in projection_ty.trait_ref.substs.types() { self.type_must_outlive(origin.clone(), component_ty, region); } - for &r in &projection_ty.trait_ref.substs.regions { + for r in projection_ty.trait_ref.substs.regions() { self.sub_regions(origin.clone(), region, r); } @@ -1597,10 +1599,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { if !env_bounds.is_empty() && env_bounds[1..].iter().all(|b| *b == env_bounds[0]) { let unique_bound = env_bounds[0]; debug!("projection_must_outlive: unique declared bound = {:?}", unique_bound); - if projection_ty.trait_ref.substs.regions - .iter() - .any(|r| env_bounds.contains(r)) - { + if projection_ty.trait_ref.substs.regions().any(|r| env_bounds.contains(&r)) { debug!("projection_must_outlive: unique declared bound appears in trait ref"); self.sub_regions(origin.clone(), region, unique_bound); return; @@ -1617,7 +1616,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.verify_generic_bound(origin, generic.clone(), region, verify_bound); } - fn type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound { + fn type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound<'tcx> { match ty.sty { ty::TyParam(p) => { self.param_bound(p) @@ -1632,7 +1631,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } } - fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound { + fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> { let param_env = &self.parameter_environment; debug!("param_bound(param_ty={:?})", @@ -1650,7 +1649,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn projection_declared_bounds(&self, span: Span, projection_ty: ty::ProjectionTy<'tcx>) - -> Vec + -> Vec<&'tcx ty::Region> { // First assemble bounds from where clauses and traits. @@ -1665,9 +1664,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn projection_bound(&self, span: Span, - declared_bounds: Vec, + declared_bounds: Vec<&'tcx ty::Region>, projection_ty: ty::ProjectionTy<'tcx>) - -> VerifyBound { + -> VerifyBound<'tcx> { debug!("projection_bound(declared_bounds={:?}, projection_ty={:?})", declared_bounds, projection_ty); @@ -1679,7 +1678,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { VerifyBound::AnyRegion(declared_bounds).or(recursive_bound) } - fn recursive_type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound { + fn recursive_type_bound(&self, span: Span, ty: Ty<'tcx>) -> VerifyBound<'tcx> { let mut bounds = vec![]; for subty in ty.walk_shallow() { @@ -1701,7 +1700,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>) - -> Vec + -> Vec<&'tcx ty::Region> { let param_env = &self.parameter_environment; @@ -1735,7 +1734,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn declared_projection_bounds_from_trait(&self, span: Span, projection_ty: ty::ProjectionTy<'tcx>) - -> Vec + -> Vec<&'tcx ty::Region> { debug!("projection_bounds(projection_ty={:?})", projection_ty); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 030491b521d95..a85e295784e97 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -252,7 +252,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { match capture { ty::UpvarCapture::ByValue => freevar_ty, ty::UpvarCapture::ByRef(borrow) => - tcx.mk_ref(tcx.mk_region(borrow.region), + tcx.mk_ref(borrow.region, ty::TypeAndMut { ty: freevar_ty, mutbl: borrow.kind.to_mutbl_lossy(), @@ -536,7 +536,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> { borrow_id: ast::NodeId, _borrow_span: Span, cmt: mc::cmt<'tcx>, - _loan_region: ty::Region, + _loan_region: &'tcx ty::Region, bk: ty::BorrowKind, _loan_cause: euv::LoanCause) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index bcad7dd3bd0fa..38ec7ba686f6f 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -416,7 +416,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { ty::ExplicitSelfCategory::Static => return, ty::ExplicitSelfCategory::ByValue => self_ty, ty::ExplicitSelfCategory::ByReference(region, mutability) => { - fcx.tcx.mk_ref(fcx.tcx.mk_region(region), ty::TypeAndMut { + fcx.tcx.mk_ref(region, ty::TypeAndMut { ty: self_ty, mutbl: mutability }) @@ -457,7 +457,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { let variances = self.tcx().item_variances(item_def_id); let mut constrained_parameters: HashSet<_> = - variances.types + variances[ast_generics.lifetimes.len()..] .iter().enumerate() .filter(|&(_, &variance)| variance != ty::Bivariant) .map(|(index, _)| self.param_ty(ast_generics, index)) @@ -468,22 +468,22 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { None, &mut constrained_parameters); - for (index, _) in variances.types.iter().enumerate() { - let param_ty = self.param_ty(ast_generics, index); - if constrained_parameters.contains(&Parameter::Type(param_ty)) { - continue; - } - let span = ast_generics.ty_params[index].span; - self.report_bivariance(span, param_ty.name); - } - - for (index, &variance) in variances.regions.iter().enumerate() { - if variance != ty::Bivariant { - continue; - } + for (index, &variance) in variances.iter().enumerate() { + let (span, name) = if index < ast_generics.lifetimes.len() { + if variance != ty::Bivariant { + continue; + } - let span = ast_generics.lifetimes[index].lifetime.span; - let name = ast_generics.lifetimes[index].lifetime.name; + (ast_generics.lifetimes[index].lifetime.span, + ast_generics.lifetimes[index].lifetime.name) + } else { + let index = index - ast_generics.lifetimes.len(); + let param_ty = self.param_ty(ast_generics, index); + if constrained_parameters.contains(&Parameter::Type(param_ty)) { + continue; + } + (ast_generics.ty_params[index].span, param_ty.name) + }; self.report_bivariance(span, name); } } @@ -597,7 +597,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Trait impl: take implied bounds from all types that // appear in the trait reference. let trait_ref = self.instantiate_type_scheme(span, free_substs, trait_ref); - trait_ref.substs.types.to_vec() + trait_ref.substs.types().collect() } None => { diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index cfc1292c34b78..3bd0e890bb811 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -87,7 +87,7 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { // early-bound versions of them, visible from the // outside of the function. This is needed by, and // only populated if there are any `impl Trait`. - free_to_bound_regions: DefIdMap + free_to_bound_regions: DefIdMap<&'gcx ty::Region> } impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { @@ -102,16 +102,22 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { return wbcx; } + let gcx = fcx.tcx.global_tcx(); let free_substs = fcx.parameter_environment.free_substs; - for (i, r) in free_substs.regions.iter().enumerate() { + for (i, k) in free_substs.params().iter().enumerate() { + let r = if let Some(r) = k.as_region() { + r + } else { + continue; + }; match *r { ty::ReFree(ty::FreeRegion { bound_region: ty::BoundRegion::BrNamed(def_id, name, _), .. }) => { - let bound_region = ty::ReEarlyBound(ty::EarlyBoundRegion { + let bound_region = gcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { index: i as u32, name: name, - }); + })); wbcx.free_to_bound_regions.insert(def_id, bound_region); } _ => { @@ -311,9 +317,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing free regions with early-bound ones. let outside_ty = gcx.fold_regions(&inside_ty, &mut false, |r, _| { - match r { + match *r { // 'static is valid everywhere. - ty::ReStatic => ty::ReStatic, + ty::ReStatic => gcx.mk_region(ty::ReStatic), // Free regions that come from early-bound regions are valid. ty::ReFree(ty::FreeRegion { @@ -331,7 +337,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { span_err!(self.tcx().sess, span, E0564, "only named lifetimes are allowed in `impl Trait`, \ but `{}` was found in the type `{}`", r, inside_ty); - ty::ReStatic + gcx.mk_region(ty::ReStatic) } ty::ReVar(_) | @@ -626,12 +632,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> { } } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { + fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { match self.infcx.fully_resolve(&r) { Ok(r) => r, Err(e) => { self.report_error(e); - ty::ReStatic + self.tcx.mk_region(ty::ReStatic) } } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index d00cbf0221e0e..7d6cee7b3bac1 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[1]; + let target = trait_ref.substs.type_at(1); debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)", source, target); @@ -413,7 +413,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { (&ty::TyBox(a), &ty::TyBox(b)) => (a, b, unsize_trait, None), (&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => { - infcx.sub_regions(infer::RelateObjectBound(span), *r_b, *r_a); + infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a); check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty)) } @@ -498,7 +498,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_node_id); let predicate = tcx.predicate_for_trait_def(cause, trait_def_id, 0, - source, vec![target]); + source, &[target]); fulfill_cx.register_predicate_obligation(&infcx, predicate); // Check that all transitive obligations are satisfied. diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7e1fb32881d6f..0074d3930e29f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1486,6 +1486,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let has_self = opt_self.is_some(); let mut parent_has_self = false; + let mut own_start = has_self as u32; let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| { let generics = generics_of_def_id(ccx, def_id); assert_eq!(generics.parent, None); @@ -1493,6 +1494,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, assert_eq!(generics.parent_types, 0); assert_eq!(has_self, false); parent_has_self = generics.has_self; + own_start = generics.count() as u32; (generics.regions.len() as u32, generics.types.len() as u32) }); @@ -1500,17 +1502,18 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let regions = early_lifetimes.iter().enumerate().map(|(i, l)| { ty::RegionParameterDef { name: l.lifetime.name, - index: parent_regions + i as u32, + index: own_start + i as u32, def_id: tcx.map.local_def_id(l.lifetime.id), bounds: l.bounds.iter().map(|l| { ast_region_to_region(tcx, l) }).collect() } - }).collect(); + }).collect::>(); // 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 = parent_types + has_self as u32 + i as u32; + let i = type_start + i as u32; get_or_create_type_parameter_def(ccx, ast_generics, i, p, allow_defaults) }); let types: Vec<_> = opt_self.into_iter().chain(types).collect(); @@ -1529,8 +1532,8 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, tcx.alloc_generics(ty::Generics { parent: parent_def_id, - parent_regions: parent_regions as u32, - parent_types: parent_types as u32, + parent_regions: parent_regions, + parent_types: parent_types, regions: regions, types: types, has_self: has_self || parent_has_self @@ -1741,12 +1744,12 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, -> ty::GenericPredicates<'tcx> { let tcx = ccx.tcx; - let (parent_regions, parent_types) = parent.map_or((0, 0), |def_id| { + let parent_count = parent.map_or(0, |def_id| { let generics = generics_of_def_id(ccx, def_id); assert_eq!(generics.parent, None); assert_eq!(generics.parent_regions, 0); assert_eq!(generics.parent_types, 0); - (generics.regions.len() as u32, generics.types.len() as u32) + generics.count() as u32 }); let ref base_predicates = match parent { Some(def_id) => { @@ -1762,10 +1765,29 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, }; let mut predicates = super_predicates; + // Collect the region predicates that were declared inline as + // well. In the case of parameters declared on a fn or method, we + // have to be careful to only iterate over early-bound regions. + let own_start = parent_count + has_self as u32; + let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics); + for (index, param) in early_lifetimes.iter().enumerate() { + let index = own_start + index as u32; + let region = ccx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { + index: index, + name: param.lifetime.name + })); + for bound in ¶m.bounds { + let bound_region = ast_region_to_region(ccx.tcx, bound); + let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region)); + predicates.push(outlives.to_predicate()); + } + } + // Collect the predicates that were written inline by the user on each // type parameter (e.g., ``). + let type_start = own_start + early_lifetimes.len() as u32; for (index, param) in ast_generics.ty_params.iter().enumerate() { - let index = parent_types + has_self as u32 + index as u32; + let index = type_start + index as u32; let param_ty = ty::ParamTy::new(index, param.name).to_ty(ccx.tcx); let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)), param_ty, @@ -1776,24 +1798,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, predicates.extend(bounds.predicates(ccx.tcx, param_ty)); } - // Collect the region predicates that were declared inline as - // well. In the case of parameters declared on a fn or method, we - // have to be careful to only iterate over early-bound regions. - let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics); - for (index, param) in early_lifetimes.iter().enumerate() { - let index = parent_regions + index as u32; - let region = - ty::ReEarlyBound(ty::EarlyBoundRegion { - index: index, - name: param.lifetime.name - }); - for bound in ¶m.bounds { - let bound_region = ast_region_to_region(ccx.tcx, bound); - let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region)); - predicates.push(outlives.to_predicate()); - } - } - // Add in the bounds that appear in the where-clause let where_clause = &ast_generics.where_clause; for predicate in &where_clause.predicates { @@ -1919,7 +1923,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, param_id: ast::NodeId, param_bounds: &[hir::TyParamBound], where_clause: &hir::WhereClause) - -> ty::ObjectLifetimeDefault + -> ty::ObjectLifetimeDefault<'tcx> { let inline_bounds = from_bounds(ccx, param_bounds); let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates); @@ -1937,7 +1941,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, bounds: &[hir::TyParamBound]) - -> Vec + -> Vec<&'tcx ty::Region> { bounds.iter() .filter_map(|bound| { @@ -1954,7 +1958,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, param_id: ast::NodeId, predicates: &[hir::WherePredicate]) - -> Vec + -> Vec<&'tcx ty::Region> { predicates.iter() .flat_map(|predicate| { @@ -2126,7 +2130,7 @@ pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, } Substs::for_item(tcx, def_id, - |def, _| def.to_early_bound_region(), + |def, _| tcx.mk_region(def.to_early_bound_region()), |def, _| tcx.mk_param_from_def(def)) } diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 7d3bd095a3a88..637df52e3cb03 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -58,8 +58,8 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { t.super_visit_with(self) } - fn visit_region(&mut self, r: ty::Region) -> bool { - match r { + fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + match *r { ty::ReEarlyBound(data) => { self.parameters.push(Parameter::Region(data)); } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 8a8232535c775..2a989105c9cb4 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -172,7 +172,7 @@ fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, node_id, item_substs); - assert!(!item_substs.substs.types.needs_infer()); + assert!(!item_substs.substs.needs_infer()); ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs); } diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index 9aca779dd89c4..f5b13c4207d90 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -257,12 +257,12 @@ impl RegionScope for BindingRscope { /// A scope which overrides the default object lifetime but has no other effect. pub struct ObjectLifetimeDefaultRscope<'r> { base_scope: &'r (RegionScope+'r), - default: ty::ObjectLifetimeDefault, + default: ty::ObjectLifetimeDefault<'r>, } impl<'r> ObjectLifetimeDefaultRscope<'r> { pub fn new(base_scope: &'r (RegionScope+'r), - default: ty::ObjectLifetimeDefault) + default: ty::ObjectLifetimeDefault<'r>) -> ObjectLifetimeDefaultRscope<'r> { ObjectLifetimeDefaultRscope { @@ -283,7 +283,7 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> { Some(self.base_object_lifetime_default(span)), ty::ObjectLifetimeDefault::Specific(r) => - Some(r), + Some(*r), } } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 536fa629fd611..2cf84b5745af4 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -26,7 +26,6 @@ use rustc::hir::intravisit::Visitor; use super::terms::*; use super::terms::VarianceTerm::*; -use super::terms::ParamKind::*; use super::xform::*; pub struct ConstraintContext<'a, 'tcx: 'a> { @@ -209,7 +208,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn declared_variance(&self, param_def_id: DefId, item_def_id: DefId, - kind: ParamKind, index: usize) -> VarianceTermPtr<'a> { assert_eq!(param_def_id.krate, item_def_id.krate); @@ -224,11 +222,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // Parameter on an item defined within another crate: // variance already inferred, just look it up. let variances = self.tcx().item_variances(item_def_id); - let variance = match kind { - TypeParam => variances.types[index], - RegionParam => variances.regions[index], - }; - self.constant_term(variance) + self.constant_term(variances[index]) } } @@ -330,7 +324,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::TyRef(region, ref mt) => { let contra = self.contravariant(variance); - self.add_constraints_from_region(generics, *region, contra); + self.add_constraints_from_region(generics, region, contra); self.add_constraints_from_mt(generics, mt, variance); } @@ -401,8 +395,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::TyParam(ref data) => { assert_eq!(generics.parent, None); - assert!((data.idx as usize) < generics.types.len()); - let def_id = generics.types[data.idx as usize].def_id; + let mut i = data.idx as usize; + if !generics.has_self || i > 0 { + i -= generics.regions.len(); + } + let def_id = generics.types[i].def_id; let node_id = self.tcx().map.as_local_node_id(def_id).unwrap(); match self.terms_cx.inferred_map.get(&node_id) { Some(&index) => { @@ -449,7 +446,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { for p in type_param_defs { let variance_decl = - self.declared_variance(p.def_id, def_id, TypeParam, p.index as usize); + self.declared_variance(p.def_id, def_id, p.index as usize); let variance_i = self.xform(variance, variance_decl); let substs_ty = substs.type_for_def(p); debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}", @@ -459,7 +456,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { for p in region_param_defs { let variance_decl = - self.declared_variance(p.def_id, def_id, RegionParam, p.index as usize); + self.declared_variance(p.def_id, def_id, p.index as usize); let variance_i = self.xform(variance, variance_decl); let substs_r = substs.region_for_def(p); self.add_constraints_from_region(generics, substs_r, variance_i); @@ -483,13 +480,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { /// context with ambient variance `variance` fn add_constraints_from_region(&mut self, generics: &ty::Generics<'tcx>, - region: ty::Region, + region: &'tcx ty::Region, variance: VarianceTermPtr<'a>) { - match region { + match *region { ty::ReEarlyBound(ref data) => { assert_eq!(generics.parent, None); - assert!((data.index as usize) < generics.regions.len()); - let def_id = generics.regions[data.index as usize].def_id; + let i = data.index as usize - generics.has_self as usize; + let def_id = generics.regions[i].def_id; let node_id = self.tcx().map.as_local_node_id(def_id).unwrap(); if self.is_to_be_inferred(node_id) { let index = self.inferred_index(node_id); diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs index d3b63119bcb32..82b63d0cc0937 100644 --- a/src/librustc_typeck/variance/solve.rs +++ b/src/librustc_typeck/variance/solve.rs @@ -21,7 +21,6 @@ use std::rc::Rc; use super::constraints::*; use super::terms::*; use super::terms::VarianceTerm::*; -use super::terms::ParamKind::*; use super::xform::*; struct SolveContext<'a, 'tcx: 'a> { @@ -109,24 +108,16 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { while index < num_inferred { let item_id = inferred_infos[index].item_id; - let mut item_variances = ty::ItemVariances::empty(); + let mut item_variances = vec![]; while index < num_inferred && inferred_infos[index].item_id == item_id { let info = &inferred_infos[index]; let variance = solutions[index]; - debug!("Index {} Info {} / {:?} Variance {:?}", - index, info.index, info.kind, variance); - match info.kind { - TypeParam => { - assert_eq!(item_variances.types.len(), info.index); - item_variances.types.push(variance); - } - RegionParam => { - assert_eq!(item_variances.regions.len(), info.index); - item_variances.regions.push(variance); - } - } + debug!("Index {} Info {} Variance {:?}", + index, info.index, variance); + assert_eq!(item_variances.len(), info.index); + item_variances.push(variance); index += 1; } diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index d30cbc8f117cf..c0b53787177d5 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -31,7 +31,6 @@ use rustc::hir::intravisit::Visitor; use util::nodemap::NodeMap; use self::VarianceTerm::*; -use self::ParamKind::*; pub type VarianceTermPtr<'a> = &'a VarianceTerm<'a>; @@ -61,7 +60,7 @@ pub struct TermsContext<'a, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub arena: &'a TypedArena>, - pub empty_variances: Rc, + pub empty_variances: Rc>, // For marker types, UnsafeCell, and other lang items where // variance is hardcoded, records the item-id and the hardcoded @@ -76,15 +75,8 @@ pub struct TermsContext<'a, 'tcx: 'a> { pub inferred_infos: Vec> , } -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum ParamKind { - TypeParam, - RegionParam, -} - pub struct InferredInfo<'a> { pub item_id: ast::NodeId, - pub kind: ParamKind, pub index: usize, pub param_id: ast::NodeId, pub term: VarianceTermPtr<'a>, @@ -110,7 +102,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>( // cache and share the variance struct used for items with // no type/region parameters - empty_variances: Rc::new(ty::ItemVariances::empty()) + empty_variances: Rc::new(vec![]) }; // See README.md for a discussion on dep-graph management. @@ -162,17 +154,19 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { let inferreds_on_entry = self.num_inferred(); + if has_self { + self.add_inferred(item_id, 0, item_id); + } + for (i, p) in generics.lifetimes.iter().enumerate() { let id = p.lifetime.id; - self.add_inferred(item_id, RegionParam, i, id); + let i = has_self as usize + i; + self.add_inferred(item_id, i, id); } - if has_self { - self.add_inferred(item_id, TypeParam, 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, i, p.id); + let i = has_self as usize + generics.lifetimes.len() + i; + self.add_inferred(item_id, i, p.id); } // If this item has no type or lifetime parameters, @@ -194,14 +188,12 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { fn add_inferred(&mut self, item_id: ast::NodeId, - kind: ParamKind, index: usize, param_id: ast::NodeId) { let inf_index = InferredIndex(self.inferred_infos.len()); let term = self.arena.alloc(InferredTerm(inf_index)); let initial_variance = self.pick_initial_variance(item_id, index); self.inferred_infos.push(InferredInfo { item_id: item_id, - kind: kind, index: index, param_id: param_id, term: term, @@ -211,13 +203,12 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { debug!("add_inferred(item_path={}, \ item_id={}, \ - kind={:?}, \ index={}, \ param_id={}, \ inf_index={:?}, \ initial_variance={:?})", self.tcx.item_path_str(self.tcx.map.local_def_id(item_id)), - item_id, kind, index, param_id, inf_index, + item_id, index, param_id, inf_index, initial_variance); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e2e655ce38bcc..c8620254b6f42 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -642,8 +642,8 @@ impl Clean for hir::TyParamBound { fn external_path_params(cx: &DocContext, trait_did: Option, has_self: bool, bindings: Vec, substs: &Substs) -> PathParameters { - let lifetimes = substs.regions.iter().filter_map(|v| v.clean(cx)).collect(); - let types = substs.types[has_self as usize..].to_vec(); + let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect(); + let types = substs.types().skip(has_self as usize).collect::>(); match (trait_did, cx.tcx_opt()) { // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C @@ -737,12 +737,11 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { let path = external_path(cx, &tcx.item_name(self.def_id).as_str(), Some(self.def_id), true, vec![], self.substs); - debug!("ty::TraitRef\n substs.types: {:?}\n", - &self.input_types()[1..]); + debug!("ty::TraitRef\n subst: {:?}\n", self.substs); // collect any late bound regions let mut late_bounds = vec![]; - for &ty_s in &self.input_types()[1..] { + for ty_s in self.input_types().skip(1) { if let ty::TyTuple(ts) = ty_s.sty { for &ty_s in ts { if let ty::TyRef(ref reg, _) = ty_s.sty { @@ -775,9 +774,9 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { impl<'tcx> Clean>> for Substs<'tcx> { fn clean(&self, cx: &DocContext) -> Option> { let mut v = Vec::new(); - v.extend(self.regions.iter().filter_map(|r| r.clean(cx)) + v.extend(self.regions().filter_map(|r| r.clean(cx)) .map(RegionBound)); - v.extend(self.types.iter().map(|t| TraitBound(PolyTrait { + v.extend(self.types().map(|t| TraitBound(PolyTrait { trait_: t.clean(cx), lifetimes: vec![] }, hir::TraitBoundModifier::None))); @@ -822,7 +821,7 @@ impl Clean for hir::LifetimeDef { } } -impl Clean for ty::RegionParameterDef { +impl<'tcx> Clean for ty::RegionParameterDef<'tcx> { fn clean(&self, _: &DocContext) -> Lifetime { Lifetime(self.name.to_string()) } @@ -914,7 +913,7 @@ impl<'tcx> Clean for ty::EquatePredicate<'tcx> { } } -impl Clean for ty::OutlivesPredicate { +impl<'tcx> Clean for ty::OutlivesPredicate<&'tcx ty::Region, &'tcx ty::Region> { fn clean(&self, cx: &DocContext) -> WherePredicate { let ty::OutlivesPredicate(ref a, ref b) = *self; WherePredicate::RegionPredicate { @@ -924,7 +923,7 @@ impl Clean for ty::OutlivesPredicate { } } -impl<'tcx> Clean for ty::OutlivesPredicate, ty::Region> { +impl<'tcx> Clean for ty::OutlivesPredicate, &'tcx ty::Region> { fn clean(&self, cx: &DocContext) -> WherePredicate { let ty::OutlivesPredicate(ref ty, ref lt) = *self; diff --git a/src/test/compile-fail/variance-associated-types.rs b/src/test/compile-fail/variance-associated-types.rs index 5539a26d2a170..7dbfc6ac1257d 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 [-, +] field: (T, &'a ()) } #[rustc_variance] -struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[o], regions=[o]) +struct Bar<'a, T : Trait<'a>> { //~ ERROR [o, o] field: >::Type } diff --git a/src/test/compile-fail/variance-object-types.rs b/src/test/compile-fail/variance-object-types.rs index 2f422bfd38cc7..1f54771e3676a 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 [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 99416057b2540..41d204a541b5a 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 [o] } #[rustc_variance] -trait Bar { //~ ERROR types=[o, o] +trait Bar { //~ ERROR [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 78591063de8ab..bf46edcfab8b1 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 [-, -, -] 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 [+, +, +] 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 [-, 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 [+, 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 [-, 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 [*] //~^ 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 [+, -, 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 d8af30da163bf..e28828f62e52d 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 [+, -, 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 [*, 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 [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 [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 [+, -, 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 150a1aa56fe72..4c737a7594d26 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 [o, o] fn get(&self) -> T; } #[rustc_variance] -trait Setter { //~ ERROR types=[o, o] +trait Setter { //~ ERROR [o, o] fn get(&self, T); } #[rustc_variance] -struct TestStruct> { //~ ERROR types=[+, +] +struct TestStruct> { //~ ERROR [+, +] t: T, u: U } #[rustc_variance] -enum TestEnum> {//~ ERROR types=[*, +] +enum TestEnum> {//~ ERROR [*, +] //~^ ERROR parameter `U` is never used Foo(T) } #[rustc_variance] -trait TestTrait> { //~ ERROR types=[o, o, o] +trait TestTrait> { //~ ERROR [o, o, o] fn getter(&self, u: U) -> T; } #[rustc_variance] -trait TestTrait2 : Getter { //~ ERROR types=[o, o] +trait TestTrait2 : Getter { //~ ERROR [o, o] } #[rustc_variance] -trait TestTrait3 { //~ ERROR types=[o, o] +trait TestTrait3 { //~ ERROR [o, o] fn getter>(&self); } #[rustc_variance] -struct TestContraStruct> { //~ ERROR types=[*, +] +struct TestContraStruct> { //~ ERROR [*, +] //~^ ERROR parameter `U` is never used t: T } #[rustc_variance] -struct TestBox+Setter> { //~ ERROR types=[*, +] +struct TestBox+Setter> { //~ ERROR [*, +] //~^ 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 4244b0e1d8b8b..b120588ecab52 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 [-] v: Option>, } diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs index c47710d6d376d..2df94cc907a9c 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 [+, +] x: A, y: B, } #[rustc_variance] -struct TestMut { //~ ERROR types=[+, o] +struct TestMut { //~ ERROR [+, o] x: A, y: &'static mut B, } #[rustc_variance] -struct TestIndirect { //~ ERROR types=[+, o] +struct TestIndirect { //~ ERROR [+, o] m: TestMut } #[rustc_variance] -struct TestIndirect2 { //~ ERROR types=[o, o] +struct TestIndirect2 { //~ ERROR [o, o] n: TestMut, m: TestMut } #[rustc_variance] -trait Getter { //~ ERROR types=[o, o] +trait Getter { //~ ERROR [o, o] fn get(&self) -> A; } #[rustc_variance] -trait Setter { //~ ERROR types=[o, o] +trait Setter { //~ ERROR [o, o] fn set(&mut self, a: A); } #[rustc_variance] -trait GetterSetter { //~ ERROR types=[o, o] +trait GetterSetter { //~ ERROR [o, o] fn get(&self) -> A; fn set(&mut self, a: A); } #[rustc_variance] -trait GetterInTypeBound { //~ ERROR types=[o, o] +trait GetterInTypeBound { //~ ERROR [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 [o, o] fn do_it>(&self); } #[rustc_variance] -struct TestObject { //~ ERROR types=[o, o] +struct TestObject { //~ ERROR [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 d5164412358fc..7667972c9d251 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 [-, o, o] t: &'a mut (A,B) } #[rustc_variance] -struct InvariantCell { //~ ERROR types=[o] +struct InvariantCell { //~ ERROR [o] t: Cell } #[rustc_variance] -struct InvariantIndirect { //~ ERROR types=[o] +struct InvariantIndirect { //~ ERROR [o] t: InvariantCell } #[rustc_variance] -struct Covariant { //~ ERROR types=[+] +struct Covariant { //~ ERROR [+] t: A, u: fn() -> A } #[rustc_variance] -struct Contravariant { //~ ERROR types=[-] +struct Contravariant { //~ ERROR [-] t: fn(A) } #[rustc_variance] -enum Enum { //~ ERROR types=[+, -, o] +enum Enum { //~ ERROR [+, -, o] Foo(Covariant), Bar(Contravariant), Zed(Covariant,Contravariant)