Skip to content

Commit

Permalink
Rollup merge of rust-lang#33576 - soltanmm:vtable, r=nikomatsakis
Browse files Browse the repository at this point in the history
Plumb inference obligations through selection, take 2

Using a `SnapshotVec` and dumping inferred obligations into `Vtable` variants.

r? @nikomatsakis
  • Loading branch information
eddyb committed May 13, 2016
2 parents 1879aaa + f52b655 commit 2c55f77
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 105 deletions.
48 changes: 38 additions & 10 deletions src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ pub enum Vtable<'tcx, N> {
VtableParam(Vec<N>),

/// Virtual calls through an object
VtableObject(VtableObjectData<'tcx>),
VtableObject(VtableObjectData<'tcx, N>),

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

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

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

/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits; this is the start of
/// `upcast_trait_ref`'s methods in that vtable.
pub vtable_base: usize
pub vtable_base: usize,

pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq)]
pub struct VtableFnPointerData<'tcx, N> {
pub fn_ty: ty::Ty<'tcx>,
pub nested: Vec<N>
}

/// Creates predicate obligations from the generic bounds.
Expand Down Expand Up @@ -569,7 +577,20 @@ impl<'tcx, N> Vtable<'tcx, N> {
VtableBuiltin(i) => i.nested,
VtableDefaultImpl(d) => d.nested,
VtableClosure(c) => c.nested,
VtableObject(_) | VtableFnPointer(..) => vec![]
VtableObject(d) => d.nested,
VtableFnPointer(d) => d.nested,
}
}

fn nested_obligations_mut(&mut self) -> &mut Vec<N> {
match self {
&mut VtableImpl(ref mut i) => &mut i.nested,
&mut VtableParam(ref mut n) => n,
&mut VtableBuiltin(ref mut i) => &mut i.nested,
&mut VtableDefaultImpl(ref mut d) => &mut d.nested,
&mut VtableClosure(ref mut c) => &mut c.nested,
&mut VtableObject(ref mut d) => &mut d.nested,
&mut VtableFnPointer(ref mut d) => &mut d.nested,
}
}

Expand All @@ -578,18 +599,25 @@ impl<'tcx, N> Vtable<'tcx, N> {
VtableImpl(i) => VtableImpl(VtableImplData {
impl_def_id: i.impl_def_id,
substs: i.substs,
nested: i.nested.into_iter().map(f).collect()
nested: i.nested.into_iter().map(f).collect(),
}),
VtableParam(n) => VtableParam(n.into_iter().map(f).collect()),
VtableBuiltin(i) => VtableBuiltin(VtableBuiltinData {
nested: i.nested.into_iter().map(f).collect()
nested: i.nested.into_iter().map(f).collect(),
}),
VtableObject(o) => VtableObject(VtableObjectData {
upcast_trait_ref: o.upcast_trait_ref,
vtable_base: o.vtable_base,
nested: o.nested.into_iter().map(f).collect(),
}),
VtableObject(o) => VtableObject(o),
VtableDefaultImpl(d) => VtableDefaultImpl(VtableDefaultImplData {
trait_def_id: d.trait_def_id,
nested: d.nested.into_iter().map(f).collect()
nested: d.nested.into_iter().map(f).collect(),
}),
VtableFnPointer(p) => VtableFnPointer(VtableFnPointerData {
fn_ty: p.fn_ty,
nested: p.nested.into_iter().map(f).collect(),
}),
VtableFnPointer(f) => VtableFnPointer(f),
VtableClosure(c) => VtableClosure(VtableClosureData {
closure_def_id: c.closure_def_id,
substs: c.substs,
Expand Down
18 changes: 11 additions & 7 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use super::PredicateObligation;
use super::SelectionContext;
use super::SelectionError;
use super::VtableClosureData;
use super::VtableFnPointerData;
use super::VtableImplData;
use super::util;

Expand Down Expand Up @@ -158,7 +159,7 @@ enum ProjectionTyCandidate<'tcx> {
Closure(VtableClosureData<'tcx, PredicateObligation<'tcx>>),

// fn pointer return type
FnPointer(Ty<'tcx>),
FnPointer(VtableFnPointerData<'tcx, PredicateObligation<'tcx>>),
}

struct ProjectionTyCandidateSet<'tcx> {
Expand Down Expand Up @@ -873,9 +874,9 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
candidate_set.vec.push(
ProjectionTyCandidate::Closure(data));
}
super::VtableFnPointer(fn_type) => {
super::VtableFnPointer(data) => {
candidate_set.vec.push(
ProjectionTyCandidate::FnPointer(fn_type));
ProjectionTyCandidate::FnPointer(data));
}
super::VtableParam(..) => {
// This case tell us nothing about the value of an
Expand Down Expand Up @@ -941,19 +942,22 @@ fn confirm_candidate<'cx, 'gcx, 'tcx>(
confirm_closure_candidate(selcx, obligation, closure_vtable)
}

ProjectionTyCandidate::FnPointer(fn_type) => {
confirm_fn_pointer_candidate(selcx, obligation, fn_type)
ProjectionTyCandidate::FnPointer(fn_pointer_vtable) => {
confirm_fn_pointer_candidate(selcx, obligation, fn_pointer_vtable)
}
}
}

fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
fn_type: Ty<'tcx>)
fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
{
let fn_type = selcx.infcx().shallow_resolve(fn_type);
// FIXME(#32730) propagate obligations (fn pointer vtable nested obligations ONLY come from
// unification in inference)
assert!(fn_pointer_vtable.nested.is_empty());
let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
let sig = fn_type.fn_sig();
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
}
Expand Down
Loading

0 comments on commit 2c55f77

Please sign in to comment.