Skip to content

Commit 4158673

Browse files
committed
rustc: reduce Substs and Generics to a simple immutable API.
1 parent bfdfa1c commit 4158673

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1226
-1548
lines changed

src/librustc/infer/error_reporting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
13661366
hir::TyPath(ref maybe_qself, ref path) => {
13671367
match self.tcx.expect_def(cur_ty.id) {
13681368
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => {
1369-
let generics = self.tcx.lookup_item_type(did).generics;
1369+
let generics = self.tcx.lookup_generics(did);
13701370

13711371
let expected =
13721372
generics.regions.len(subst::TypeSpace) as u32;

src/librustc/infer/mod.rs

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ use middle::mem_categorization as mc;
2525
use middle::mem_categorization::McResult;
2626
use middle::region::CodeExtent;
2727
use mir::tcx::LvalueTy;
28-
use ty::subst;
29-
use ty::subst::Substs;
30-
use ty::subst::Subst;
28+
use ty::subst::{Subst, Substs};
3129
use ty::adjustment;
3230
use ty::{TyVid, IntVid, FloatVid};
3331
use ty::{self, Ty, TyCtxt};
@@ -1236,43 +1234,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12361234

12371235
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
12381236
/// type/region parameter to a fresh inference variable.
1239-
pub fn fresh_substs_for_generics(&self,
1240-
span: Span,
1241-
generics: &ty::Generics<'tcx>)
1242-
-> &'tcx subst::Substs<'tcx>
1243-
{
1244-
let substs = Substs::from_generics(generics, |def, _| {
1237+
pub fn fresh_substs_for_item(&self,
1238+
span: Span,
1239+
def_id: DefId)
1240+
-> &'tcx Substs<'tcx> {
1241+
Substs::for_item(self.tcx, def_id, |def, _| {
12451242
self.region_var_for_def(span, def)
12461243
}, |def, substs| {
12471244
self.type_var_for_def(span, def, substs)
1248-
});
1249-
1250-
self.tcx.mk_substs(substs)
1251-
}
1252-
1253-
/// Given a set of generics defined on a trait, returns a substitution mapping each output
1254-
/// type/region parameter to a fresh inference variable, and mapping the self type to
1255-
/// `self_ty`.
1256-
pub fn fresh_substs_for_trait(&self,
1257-
span: Span,
1258-
generics: &ty::Generics<'tcx>,
1259-
self_ty: Ty<'tcx>)
1260-
-> &'tcx subst::Substs<'tcx>
1261-
{
1262-
assert!(generics.types.len(subst::SelfSpace) == 1);
1263-
assert!(generics.types.len(subst::FnSpace) == 0);
1264-
1265-
let substs = Substs::from_generics(generics, |def, _| {
1266-
self.region_var_for_def(span, def)
1267-
}, |def, substs| {
1268-
if def.space == subst::SelfSpace {
1269-
self_ty
1270-
} else {
1271-
self.type_var_for_def(span, def, substs)
1272-
}
1273-
});
1274-
1275-
self.tcx.mk_substs(substs)
1245+
})
12761246
}
12771247

12781248
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {

src/librustc/middle/cstore.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,16 @@ pub trait CrateStore<'tcx> {
154154
fn item_variances(&self, def: DefId) -> ty::ItemVariances;
155155
fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
156156
fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
157-
-> ty::TypeScheme<'tcx>;
157+
-> Ty<'tcx>;
158158
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
159159
fn item_name(&self, def: DefId) -> ast::Name;
160160
fn opt_item_name(&self, def: DefId) -> Option<ast::Name>;
161161
fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
162162
-> ty::GenericPredicates<'tcx>;
163163
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
164164
-> ty::GenericPredicates<'tcx>;
165+
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
166+
-> &'tcx ty::Generics<'tcx>;
165167
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
166168
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
167169
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
@@ -187,8 +189,7 @@ pub trait CrateStore<'tcx> {
187189
fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
188190

189191
// trait/impl-item info
190-
fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
191-
-> Option<DefId>;
192+
fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;
192193
fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
193194
-> Option<ty::ImplOrTraitItem<'tcx>>;
194195

@@ -334,7 +335,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
334335
fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") }
335336
fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
336337
fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
337-
-> ty::TypeScheme<'tcx> { bug!("item_type") }
338+
-> Ty<'tcx> { bug!("item_type") }
338339
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
339340
bug!("visible_parent_map")
340341
}
@@ -344,6 +345,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
344345
-> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
345346
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
346347
-> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
348+
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
349+
-> &'tcx ty::Generics<'tcx> { bug!("item_generics") }
347350
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
348351
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
349352
{ bug!("trait_def") }
@@ -379,8 +382,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
379382
fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
380383

381384
// trait/impl-item info
382-
fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
383-
-> Option<DefId> { bug!("trait_of_item") }
385+
fn trait_of_item(&self, def_id: DefId) -> Option<DefId> { bug!("trait_of_item") }
384386
fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
385387
-> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
386388

@@ -583,7 +585,7 @@ pub mod tls {
583585
pub trait DecodingContext<'tcx> {
584586
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
585587
fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx>;
586-
fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx>;
588+
fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> &'tcx Substs<'tcx>;
587589
fn translate_def_id(&self, def_id: DefId) -> DefId;
588590
}
589591

src/librustc/middle/dead.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use hir::{self, pat_util, PatKind};
1818
use hir::intravisit::{self, Visitor};
1919

2020
use middle::privacy;
21-
use ty::{self, TyCtxt};
21+
use ty::{self, subst, TyCtxt};
2222
use hir::def::Def;
2323
use hir::def_id::{DefId};
2424
use lint;
@@ -88,15 +88,24 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
8888
fn lookup_and_handle_definition(&mut self, id: ast::NodeId) {
8989
use ty::TypeVariants::{TyEnum, TyStruct};
9090

91+
let def = self.tcx.expect_def(id);
92+
9193
// If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar`
92-
self.tcx.tables.borrow().item_substs.get(&id)
93-
.and_then(|substs| substs.substs.self_ty())
94-
.map(|ty| match ty.sty {
95-
TyEnum(tyid, _) | TyStruct(tyid, _) => self.check_def_id(tyid.did),
96-
_ => (),
97-
});
94+
match def {
95+
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
96+
if self.tcx.trait_of_item(def.def_id()).is_some() => {
97+
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
98+
match substs.substs.types.get(subst::SelfSpace, 0).sty {
99+
TyEnum(tyid, _) | TyStruct(tyid, _) => {
100+
self.check_def_id(tyid.did)
101+
}
102+
_ => {}
103+
}
104+
}
105+
}
106+
_ => {}
107+
}
98108

99-
let def = self.tcx.expect_def(id);
100109
match def {
101110
Def::Const(_) | Def::AssociatedConst(..) => {
102111
self.check_def_id(def.def_id());

src/librustc/mir/repr.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,10 +1073,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
10731073
let variant_def = &adt_def.variants[variant];
10741074

10751075
ppaux::parameterized(fmt, substs, variant_def.did,
1076-
ppaux::Ns::Value, &[],
1077-
|tcx| {
1078-
Some(tcx.lookup_item_type(variant_def.did).generics)
1079-
})?;
1076+
ppaux::Ns::Value, &[])?;
10801077

10811078
match variant_def.kind {
10821079
ty::VariantKind::Unit => Ok(()),
@@ -1169,9 +1166,7 @@ impl<'tcx> Debug for Literal<'tcx> {
11691166
use self::Literal::*;
11701167
match *self {
11711168
Item { def_id, substs } => {
1172-
ppaux::parameterized(
1173-
fmt, substs, def_id, ppaux::Ns::Value, &[],
1174-
|tcx| Some(tcx.lookup_item_type(def_id).generics))
1169+
ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[])
11751170
}
11761171
Value { ref value } => {
11771172
write!(fmt, "const ")?;

src/librustc/traits/error_reporting.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
221221

222222
self.tcx.lookup_trait_def(trait_ref.def_id)
223223
.for_each_relevant_impl(self.tcx, trait_self_ty, |def_id| {
224-
let ity = tcx.lookup_item_type(def_id);
225-
let impl_substs = self.fresh_substs_for_generics(obligation.cause.span,
226-
&ity.generics);
224+
let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
227225
let impl_trait_ref = tcx
228226
.impl_trait_ref(def_id)
229227
.unwrap()

src/librustc/traits/fulfill.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,9 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> {
160160
// We can resolve the `impl Trait` to its concrete type.
161161
if let Some(ty_scheme) = tcx.opt_lookup_item_type(def_id) {
162162
let concrete_ty = ty_scheme.ty.subst(tcx, substs);
163-
let concrete_substs = Substs::new_trait(vec![], vec![], concrete_ty);
164163
let predicate = ty::TraitRef {
165164
def_id: self.predicate.def_id(),
166-
substs: tcx.mk_substs(concrete_substs)
165+
substs: Substs::new_trait(tcx, vec![], vec![], concrete_ty)
167166
}.to_predicate();
168167

169168
let original_obligation = Obligation::new(self.cause.clone(),

src/librustc/traits/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub use self::ObligationCauseCode::*;
1717

1818
use hir::def_id::DefId;
1919
use middle::free_region::FreeRegionMap;
20-
use ty::subst;
20+
use ty::subst::Substs;
2121
use ty::{self, Ty, TyCtxt, TypeFoldable};
2222
use infer::InferCtxt;
2323

@@ -272,7 +272,7 @@ pub enum Vtable<'tcx, N> {
272272
#[derive(Clone, PartialEq, Eq)]
273273
pub struct VtableImplData<'tcx, N> {
274274
pub impl_def_id: DefId,
275-
pub substs: &'tcx subst::Substs<'tcx>,
275+
pub substs: &'tcx Substs<'tcx>,
276276
pub nested: Vec<N>
277277
}
278278

src/librustc/traits/object_safety.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -166,25 +166,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
166166
}
167167

168168
fn trait_has_sized_self(self, trait_def_id: DefId) -> bool {
169-
let trait_def = self.lookup_trait_def(trait_def_id);
170-
let trait_predicates = self.lookup_predicates(trait_def_id);
171-
self.generics_require_sized_self(&trait_def.generics, &trait_predicates)
169+
self.generics_require_sized_self(trait_def_id)
172170
}
173171

174-
fn generics_require_sized_self(self,
175-
generics: &ty::Generics<'gcx>,
176-
predicates: &ty::GenericPredicates<'gcx>)
177-
-> bool
178-
{
172+
fn generics_require_sized_self(self, def_id: DefId) -> bool {
179173
let sized_def_id = match self.lang_items.sized_trait() {
180174
Some(def_id) => def_id,
181175
None => { return false; /* No Sized trait, can't require it! */ }
182176
};
183177

184178
// Search for a predicate like `Self : Sized` amongst the trait bounds.
185-
let free_substs = self.construct_free_substs(generics,
179+
let free_substs = self.construct_free_substs(def_id,
186180
self.region_maps.node_extent(ast::DUMMY_NODE_ID));
187-
let predicates = predicates.instantiate(self, &free_substs).predicates;
181+
let predicates = self.lookup_predicates(def_id);
182+
let predicates = predicates.instantiate(self, free_substs).predicates;
188183
elaborate_predicates(self, predicates)
189184
.any(|predicate| {
190185
match predicate {
@@ -214,7 +209,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
214209
{
215210
// Any method that has a `Self : Sized` requisite is otherwise
216211
// exempt from the regulations.
217-
if self.generics_require_sized_self(&method.generics, &method.predicates) {
212+
if self.generics_require_sized_self(method.def_id) {
218213
return None;
219214
}
220215

@@ -231,7 +226,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
231226
-> bool
232227
{
233228
// Any method that has a `Self : Sized` requisite can't be called.
234-
if self.generics_require_sized_self(&method.generics, &method.predicates) {
229+
if self.generics_require_sized_self(method.def_id) {
235230
return false;
236231
}
237232

src/librustc/traits/select.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use traits;
4242
use ty::fast_reject;
4343
use ty::relate::TypeRelation;
4444

45+
use rustc_data_structures::bitvec::BitVector;
4546
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
4647
use std::cell::RefCell;
4748
use std::fmt;
@@ -1935,7 +1936,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
19351936

19361937
// for `PhantomData<T>`, we pass `T`
19371938
ty::TyStruct(def, substs) if def.is_phantom_data() => {
1938-
substs.types.get_slice(TypeSpace).to_vec()
1939+
substs.types.as_full_slice().to_vec()
19391940
}
19401941

19411942
ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
@@ -2584,30 +2585,33 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25842585
} else {
25852586
return Err(Unimplemented);
25862587
};
2587-
let mut ty_params = vec![];
2588+
let mut ty_params = BitVector::new(substs_a.types.len(TypeSpace));
2589+
let mut found = false;
25882590
for ty in field.walk() {
25892591
if let ty::TyParam(p) = ty.sty {
25902592
assert!(p.space == TypeSpace);
2591-
let idx = p.idx as usize;
2592-
if !ty_params.contains(&idx) {
2593-
ty_params.push(idx);
2594-
}
2593+
ty_params.insert(p.idx as usize);
2594+
found = true;
25952595
}
25962596
}
2597-
if ty_params.is_empty() {
2597+
if !found {
25982598
return Err(Unimplemented);
25992599
}
26002600

26012601
// Replace type parameters used in unsizing with
26022602
// TyError and ensure they do not affect any other fields.
26032603
// This could be checked after type collection for any struct
26042604
// with a potentially unsized trailing field.
2605-
let mut new_substs = substs_a.clone();
2606-
for &i in &ty_params {
2607-
new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err;
2608-
}
2605+
let types = substs_a.types.map_enumerated(|(_, i, ty)| {
2606+
if ty_params.contains(i) {
2607+
tcx.types.err
2608+
} else {
2609+
ty
2610+
}
2611+
});
2612+
let substs = Substs::new(tcx, types, substs_a.regions.clone());
26092613
for &ty in fields.split_last().unwrap().1 {
2610-
if ty.subst(tcx, &new_substs).references_error() {
2614+
if ty.subst(tcx, substs).references_error() {
26112615
return Err(Unimplemented);
26122616
}
26132617
}
@@ -2618,11 +2622,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26182622

26192623
// Check that the source structure with the target's
26202624
// type parameters is a subtype of the target.
2621-
for &i in &ty_params {
2622-
let param_b = *substs_b.types.get(TypeSpace, i);
2623-
new_substs.types.get_mut_slice(TypeSpace)[i] = param_b;
2624-
}
2625-
let new_struct = tcx.mk_struct(def, tcx.mk_substs(new_substs));
2625+
let types = substs_a.types.map_enumerated(|(_, i, ty)| {
2626+
if ty_params.contains(i) {
2627+
*substs_b.types.get(TypeSpace, i)
2628+
} else {
2629+
ty
2630+
}
2631+
});
2632+
let substs = Substs::new(tcx, types, substs_a.regions.clone());
2633+
let new_struct = tcx.mk_struct(def, substs);
26262634
let origin = TypeOrigin::Misc(obligation.cause.span);
26272635
let InferOk { obligations, .. } =
26282636
self.infcx.sub_types(false, origin, new_struct, target)
@@ -2691,12 +2699,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26912699
snapshot);
26922700
let skol_obligation_trait_ref = skol_obligation.trait_ref;
26932701

2694-
let impl_substs = util::fresh_type_vars_for_impl(self.infcx,
2695-
obligation.cause.span,
2696-
impl_def_id);
2702+
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span,
2703+
impl_def_id);
26972704

26982705
let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
2699-
&impl_substs);
2706+
impl_substs);
27002707

27012708
let impl_trait_ref =
27022709
project::normalize_with_depth(self,

0 commit comments

Comments
 (0)