Skip to content

Commit 8628cce

Browse files
Add inferred obligation storage to all Vtable variants and SelectionContext
1 parent e37f859 commit 8628cce

File tree

7 files changed

+111
-41
lines changed

7 files changed

+111
-41
lines changed

src/librustc/traits/mod.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ pub enum Vtable<'tcx, N> {
239239
VtableParam(Vec<N>),
240240

241241
/// Virtual calls through an object
242-
VtableObject(VtableObjectData<'tcx>),
242+
VtableObject(VtableObjectData<'tcx, N>),
243243

244244
/// Successful resolution for a builtin trait.
245245
VtableBuiltin(VtableBuiltinData<N>),
@@ -250,7 +250,7 @@ pub enum Vtable<'tcx, N> {
250250
VtableClosure(VtableClosureData<'tcx, N>),
251251

252252
/// Same as above, but for a fn pointer type with the given signature.
253-
VtableFnPointer(ty::Ty<'tcx>),
253+
VtableFnPointer(VtableFnPointerData<'tcx, N>),
254254
}
255255

256256
/// Identifies a particular impl in the source, along with a set of
@@ -293,14 +293,22 @@ pub struct VtableBuiltinData<N> {
293293
/// A vtable for some object-safe trait `Foo` automatically derived
294294
/// for the object type `Foo`.
295295
#[derive(PartialEq,Eq,Clone)]
296-
pub struct VtableObjectData<'tcx> {
296+
pub struct VtableObjectData<'tcx, N> {
297297
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
298298
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
299299

300300
/// The vtable is formed by concatenating together the method lists of
301301
/// the base object trait and all supertraits; this is the start of
302302
/// `upcast_trait_ref`'s methods in that vtable.
303-
pub vtable_base: usize
303+
pub vtable_base: usize,
304+
305+
pub nested: Vec<N>,
306+
}
307+
308+
#[derive(Clone, PartialEq, Eq)]
309+
pub struct VtableFnPointerData<'tcx, N> {
310+
pub fn_ty: ty::Ty<'tcx>,
311+
pub nested: Vec<N>
304312
}
305313

306314
/// Creates predicate obligations from the generic bounds.
@@ -569,7 +577,8 @@ impl<'tcx, N> Vtable<'tcx, N> {
569577
VtableBuiltin(i) => i.nested,
570578
VtableDefaultImpl(d) => d.nested,
571579
VtableClosure(c) => c.nested,
572-
VtableObject(_) | VtableFnPointer(..) => vec![]
580+
VtableObject(d) => d.nested,
581+
VtableFnPointer(d) => d.nested,
573582
}
574583
}
575584

@@ -578,18 +587,25 @@ impl<'tcx, N> Vtable<'tcx, N> {
578587
VtableImpl(i) => VtableImpl(VtableImplData {
579588
impl_def_id: i.impl_def_id,
580589
substs: i.substs,
581-
nested: i.nested.into_iter().map(f).collect()
590+
nested: i.nested.into_iter().map(f).collect(),
582591
}),
583592
VtableParam(n) => VtableParam(n.into_iter().map(f).collect()),
584593
VtableBuiltin(i) => VtableBuiltin(VtableBuiltinData {
585-
nested: i.nested.into_iter().map(f).collect()
594+
nested: i.nested.into_iter().map(f).collect(),
595+
}),
596+
VtableObject(o) => VtableObject(VtableObjectData {
597+
upcast_trait_ref: o.upcast_trait_ref,
598+
vtable_base: o.vtable_base,
599+
nested: o.nested.into_iter().map(f).collect(),
586600
}),
587-
VtableObject(o) => VtableObject(o),
588601
VtableDefaultImpl(d) => VtableDefaultImpl(VtableDefaultImplData {
589602
trait_def_id: d.trait_def_id,
590-
nested: d.nested.into_iter().map(f).collect()
603+
nested: d.nested.into_iter().map(f).collect(),
604+
}),
605+
VtableFnPointer(p) => VtableFnPointer(VtableFnPointerData {
606+
fn_ty: p.fn_ty,
607+
nested: p.nested.into_iter().map(f).collect(),
591608
}),
592-
VtableFnPointer(f) => VtableFnPointer(f),
593609
VtableClosure(c) => VtableClosure(VtableClosureData {
594610
closure_def_id: c.closure_def_id,
595611
substs: c.substs,

src/librustc/traits/project.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use super::PredicateObligation;
1919
use super::SelectionContext;
2020
use super::SelectionError;
2121
use super::VtableClosureData;
22+
use super::VtableFnPointerData;
2223
use super::VtableImplData;
2324
use super::util;
2425

@@ -158,7 +159,7 @@ enum ProjectionTyCandidate<'tcx> {
158159
Closure(VtableClosureData<'tcx, PredicateObligation<'tcx>>),
159160

160161
// fn pointer return type
161-
FnPointer(Ty<'tcx>),
162+
FnPointer(VtableFnPointerData<'tcx, PredicateObligation<'tcx>>),
162163
}
163164

164165
struct ProjectionTyCandidateSet<'tcx> {
@@ -929,9 +930,9 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
929930
candidate_set.vec.push(
930931
ProjectionTyCandidate::Closure(data));
931932
}
932-
super::VtableFnPointer(fn_type) => {
933+
super::VtableFnPointer(data) => {
933934
candidate_set.vec.push(
934-
ProjectionTyCandidate::FnPointer(fn_type));
935+
ProjectionTyCandidate::FnPointer(data));
935936
}
936937
super::VtableParam(..) => {
937938
// This case tell us nothing about the value of an
@@ -997,19 +998,22 @@ fn confirm_candidate<'cx, 'gcx, 'tcx>(
997998
confirm_closure_candidate(selcx, obligation, closure_vtable)
998999
}
9991000

1000-
ProjectionTyCandidate::FnPointer(fn_type) => {
1001-
confirm_fn_pointer_candidate(selcx, obligation, fn_type)
1001+
ProjectionTyCandidate::FnPointer(fn_pointer_vtable) => {
1002+
confirm_fn_pointer_candidate(selcx, obligation, fn_pointer_vtable)
10021003
}
10031004
}
10041005
}
10051006

10061007
fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
10071008
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
10081009
obligation: &ProjectionTyObligation<'tcx>,
1009-
fn_type: Ty<'tcx>)
1010+
fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
10101011
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
10111012
{
1012-
let fn_type = selcx.infcx().shallow_resolve(fn_type);
1013+
// FIXME(#32730) propagate obligations (fn pointer vtable nested obligations ONLY come from
1014+
// unification in inference)
1015+
assert!(fn_pointer_vtable.nested.is_empty());
1016+
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
10131017
let sig = fn_type.fn_sig();
10141018
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
10151019
}

src/librustc/traits/select.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use super::SelectionResult;
3030
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
3131
VtableFnPointer, VtableObject, VtableDefaultImpl};
3232
use super::{VtableImplData, VtableObjectData, VtableBuiltinData,
33-
VtableClosureData, VtableDefaultImplData};
33+
VtableClosureData, VtableDefaultImplData, VtableFnPointerData};
3434
use super::util;
3535

3636
use hir::def_id::DefId;
@@ -42,13 +42,24 @@ use traits;
4242
use ty::fast_reject;
4343
use ty::relate::TypeRelation;
4444

45+
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
4546
use std::cell::RefCell;
4647
use std::fmt;
48+
use std::marker::PhantomData;
4749
use std::rc::Rc;
4850
use syntax::abi::Abi;
4951
use hir;
5052
use util::nodemap::FnvHashMap;
5153

54+
struct InferredObligationsSnapshotVecDelegate<'tcx> {
55+
phantom: PhantomData<&'tcx i32>,
56+
}
57+
impl<'tcx> SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate<'tcx> {
58+
type Value = PredicateObligation<'tcx>;
59+
type Undo = ();
60+
fn reverse(_: &mut Vec<Self::Value>, _: Self::Undo) {}
61+
}
62+
5263
pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
5364
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
5465

@@ -74,6 +85,8 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
7485
/// there is no type that the user could *actually name* that
7586
/// would satisfy it. This avoids crippling inference, basically.
7687
intercrate: bool,
88+
89+
inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
7790
}
7891

7992
// A stack that walks back up the stack frame.
@@ -300,6 +313,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
300313
infcx: infcx,
301314
freshener: infcx.freshener(),
302315
intercrate: false,
316+
inferred_obligations: SnapshotVec::new(),
303317
}
304318
}
305319

@@ -308,6 +322,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
308322
infcx: infcx,
309323
freshener: infcx.freshener(),
310324
intercrate: true,
325+
inferred_obligations: SnapshotVec::new(),
311326
}
312327
}
313328

@@ -1977,9 +1992,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
19771992
}
19781993

19791994
FnPointerCandidate => {
1980-
let fn_type =
1995+
let data =
19811996
self.confirm_fn_pointer_candidate(obligation)?;
1982-
Ok(VtableFnPointer(fn_type))
1997+
Ok(VtableFnPointer(data))
19831998
}
19841999

19852000
ProjectionCandidate => {
@@ -2227,7 +2242,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22272242

22282243
fn confirm_object_candidate(&mut self,
22292244
obligation: &TraitObligation<'tcx>)
2230-
-> VtableObjectData<'tcx>
2245+
-> VtableObjectData<'tcx, PredicateObligation<'tcx>>
22312246
{
22322247
debug!("confirm_object_candidate({:?})",
22332248
obligation);
@@ -2279,15 +2294,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22792294

22802295
}
22812296

2297+
// FIXME(#32730) propagate obligations
22822298
VtableObjectData {
22832299
upcast_trait_ref: upcast_trait_ref.unwrap(),
22842300
vtable_base: vtable_base,
2301+
nested: vec![]
22852302
}
22862303
}
22872304

2288-
fn confirm_fn_pointer_candidate(&mut self,
2289-
obligation: &TraitObligation<'tcx>)
2290-
-> Result<ty::Ty<'tcx>,SelectionError<'tcx>>
2305+
fn confirm_fn_pointer_candidate(&mut self, obligation: &TraitObligation<'tcx>)
2306+
-> Result<VtableFnPointerData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
22912307
{
22922308
debug!("confirm_fn_pointer_candidate({:?})",
22932309
obligation);
@@ -2305,7 +2321,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
23052321
self.confirm_poly_trait_refs(obligation.cause.clone(),
23062322
obligation.predicate.to_poly_trait_ref(),
23072323
trait_ref)?;
2308-
Ok(self_ty)
2324+
// FIXME(#32730) propagate obligations
2325+
Ok(VtableFnPointerData { fn_ty: self_ty, nested: vec![] })
23092326
}
23102327

23112328
fn confirm_closure_candidate(&mut self,

src/librustc/traits/structural_impls.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,20 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableDefaultImplData<N> {
9999
}
100100
}
101101

102-
impl<'tcx> fmt::Debug for traits::VtableObjectData<'tcx> {
102+
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> {
103103
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104-
write!(f, "VtableObject(upcast={:?}, vtable_base={})",
104+
write!(f, "VtableObject(upcast={:?}, vtable_base={}, nested={:?})",
105105
self.upcast_trait_ref,
106-
self.vtable_base)
106+
self.vtable_base,
107+
self.nested)
108+
}
109+
}
110+
111+
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> {
112+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113+
write!(f, "VtableFnPointer(fn_ty={:?}, nested={:?})",
114+
self.fn_ty,
115+
self.nested)
107116
}
108117
}
109118

@@ -185,19 +194,26 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
185194
})
186195
})
187196
}
188-
traits::VtableFnPointer(ty) => {
189-
tcx.lift(&ty).map(traits::VtableFnPointer)
197+
traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
198+
tcx.lift(&fn_ty).map(|fn_ty| {
199+
traits::VtableFnPointer(traits::VtableFnPointerData {
200+
fn_ty: fn_ty,
201+
nested: nested,
202+
})
203+
})
190204
}
191205
traits::VtableParam(n) => Some(traits::VtableParam(n)),
192206
traits::VtableBuiltin(d) => Some(traits::VtableBuiltin(d)),
193207
traits::VtableObject(traits::VtableObjectData {
194208
upcast_trait_ref,
195-
vtable_base
209+
vtable_base,
210+
nested
196211
}) => {
197212
tcx.lift(&upcast_trait_ref).map(|trait_ref| {
198213
traits::VtableObject(traits::VtableObjectData {
199214
upcast_trait_ref: trait_ref,
200-
vtable_base: vtable_base
215+
vtable_base: vtable_base,
216+
nested: nested
201217
})
202218
})
203219
}
@@ -276,16 +292,30 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinDa
276292
}
277293
}
278294

279-
impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> {
295+
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
280296
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
281297
traits::VtableObjectData {
282298
upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
283-
vtable_base: self.vtable_base
299+
vtable_base: self.vtable_base,
300+
nested: self.nested.fold_with(folder),
301+
}
302+
}
303+
304+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
305+
self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
306+
}
307+
}
308+
309+
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
310+
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
311+
traits::VtableFnPointerData {
312+
fn_ty: self.fn_ty.fold_with(folder),
313+
nested: self.nested.fold_with(folder),
284314
}
285315
}
286316

287317
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
288-
self.upcast_trait_ref.visit_with(visitor)
318+
self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
289319
}
290320
}
291321

src/librustc/traits/util.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
473473
/// Given an upcast trait object described by `object`, returns the
474474
/// index of the method `method_def_id` (which should be part of
475475
/// `object.upcast_trait_ref`) within the vtable for `object`.
476-
pub fn get_vtable_index_of_object_method(self,
477-
object: &super::VtableObjectData<'tcx>,
478-
method_def_id: DefId) -> usize {
476+
pub fn get_vtable_index_of_object_method<N>(self,
477+
object: &super::VtableObjectData<'tcx, N>,
478+
method_def_id: DefId) -> usize {
479479
// Count number of methods preceding the one we are selecting and
480480
// add them to the total offset.
481481
// Skip over associated types and constants.

src/librustc_trans/callee.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@ impl<'tcx> Callee<'tcx> {
188188
};
189189
Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty))
190190
}
191-
traits::VtableFnPointer(fn_ty) => {
191+
traits::VtableFnPointer(vtable_fn_pointer) => {
192192
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
193-
let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, fn_ty);
193+
let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, vtable_fn_pointer.fn_ty);
194194

195195
let method_ty = def_ty(tcx, def_id, substs);
196196
let fn_ptr_ty = match method_ty.sty {

src/librustc_trans/meth.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
176176
trait_closure_kind);
177177
vec![llfn].into_iter()
178178
}
179-
traits::VtableFnPointer(bare_fn_ty) => {
179+
traits::VtableFnPointer(
180+
traits::VtableFnPointerData {
181+
fn_ty: bare_fn_ty,
182+
nested: _ }) => {
180183
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
181184
vec![trans_fn_pointer_shim(ccx, trait_closure_kind, bare_fn_ty)].into_iter()
182185
}

0 commit comments

Comments
 (0)