Skip to content

Commit

Permalink
resolve instances to ty::Instance directly
Browse files Browse the repository at this point in the history
This removes the duplication between collector, callee, and (eventually)
MIRI.
  • Loading branch information
arielb1 committed Mar 18, 2017
1 parent bf80fec commit aac5ba5
Show file tree
Hide file tree
Showing 15 changed files with 389 additions and 495 deletions.
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Expand Up @@ -40,7 +40,7 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
pub use self::select::{MethodMatchedData}; // intentionally don't export variants
pub use self::specialize::{OverlapError, specialization_graph, specializes, translate_substs};
pub use self::specialize::{SpecializesCache, find_method};
pub use self::specialize::{SpecializesCache, find_associated_item};
pub use self::util::elaborate_predicates;
pub use self::util::supertraits;
pub use self::util::Supertraits;
Expand Down
25 changes: 12 additions & 13 deletions src/librustc/traits/specialize/mod.rs
Expand Up @@ -29,8 +29,6 @@ use traits::{self, Reveal, ObligationCause};
use ty::{self, TyCtxt, TypeFoldable};
use syntax_pos::DUMMY_SP;

use syntax::ast;

pub mod specialization_graph;

/// Information pertinent to an overlapping impl error.
Expand Down Expand Up @@ -106,22 +104,23 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
}

/// Given a selected impl described by `impl_data`, returns the
/// definition and substitions for the method with the name `name`,
/// and trait method substitutions `substs`, in that impl, a less
/// specialized impl, or the trait default, whichever applies.
pub fn find_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
name: ast::Name,
substs: &'tcx Substs<'tcx>,
impl_data: &super::VtableImplData<'tcx, ()>)
-> (DefId, &'tcx Substs<'tcx>)
{
/// definition and substitions for the method with the name `name`
/// the kind `kind`, and trait method substitutions `substs`, in
/// that impl, a less specialized impl, or the trait default,
/// whichever applies.
pub fn find_associated_item<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
item: &ty::AssociatedItem,
substs: &'tcx Substs<'tcx>,
impl_data: &super::VtableImplData<'tcx, ()>,
) -> (DefId, &'tcx Substs<'tcx>) {
assert!(!substs.needs_infer());

let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
let trait_def = tcx.lookup_trait_def(trait_def_id);

let ancestors = trait_def.ancestors(impl_data.impl_def_id);
match ancestors.defs(tcx, name, ty::AssociatedKind::Method).next() {
match ancestors.defs(tcx, item.name, item.kind).next() {
Some(node_item) => {
let substs = tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
Expand All @@ -137,7 +136,7 @@ pub fn find_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
(node_item.item.def_id, substs)
}
None => {
bug!("method {:?} not found in {:?}", name, impl_data.impl_def_id)
bug!("{:?} not found in {:?}", item, impl_data.impl_def_id)
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/ty/context.rs
Expand Up @@ -1469,6 +1469,15 @@ impl<T, R> InternIteratorElement<T, R> for T {
}
}

impl<'a, T, R> InternIteratorElement<T, R> for &'a T
where T: Clone + 'a
{
type Output = R;
fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
f(&iter.cloned().collect::<AccumulateVec<[_; 8]>>())
}
}

impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
type Output = Result<R, E>;
fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
Expand Down
34 changes: 28 additions & 6 deletions src/librustc/ty/instance.rs
Expand Up @@ -27,17 +27,30 @@ pub struct Instance<'tcx> {
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum InstanceDef<'tcx> {
Item(DefId),
Intrinsic(DefId),
// <fn() as FnTrait>::call_*
// def-id is FnTrait::call_*
FnPtrShim(DefId, Ty<'tcx>),
// <Trait as Trait>::fn
Virtual(DefId, usize),
// <[mut closure] as FnOnce>::call_once
ClosureOnceShim {
call_once: DefId,
closure_did: DefId
},
}

impl<'tcx> InstanceDef<'tcx> {
#[inline]
pub fn def_id(&self) -> DefId {
match *self {
InstanceDef::Item(def_id) |
InstanceDef::FnPtrShim(def_id, _)
=> def_id
InstanceDef::FnPtrShim(def_id, _) |
InstanceDef::Virtual(def_id, _) |
InstanceDef::Intrinsic(def_id, ) |
InstanceDef::ClosureOnceShim {
call_once: def_id, closure_did: _
} => def_id
}
}

Expand Down Expand Up @@ -73,14 +86,23 @@ impl<'tcx> InstanceDef<'tcx> {

impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
match self.def {
InstanceDef::Item(def) => {
ppaux::parameterized(f, self.substs, def, &[])
InstanceDef::Item(_) => Ok(()),
InstanceDef::Intrinsic(_) => {
write!(f, " - intrinsic")
}
InstanceDef::FnPtrShim(def, ty) => {
ppaux::parameterized(f, self.substs, def, &[])?;
InstanceDef::Virtual(_, num) => {
write!(f, " - shim(#{})", num)
}
InstanceDef::FnPtrShim(_, ty) => {
write!(f, " - shim({:?})", ty)
}
InstanceDef::ClosureOnceShim {
call_once: _, closure_did
} => {
write!(f, " - shim({:?})", closure_did)
}
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/ty/util.rs
Expand Up @@ -408,8 +408,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
})
}


}

pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/shim.rs
Expand Up @@ -41,6 +41,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
ty::InstanceDef::FnPtrShim(_, ty) => {
build_fn_ptr_shim(tcx, ty, instance.def_ty(tcx))
}
_ => bug!("unknown shim kind")
};
debug!("make_shim({:?}) = {:?}", instance, result);

Expand Down
24 changes: 1 addition & 23 deletions src/librustc_trans/base.rs
Expand Up @@ -36,9 +36,7 @@ use llvm::{Linkage, ValueRef, Vector, get_param};
use llvm;
use rustc::hir::def_id::LOCAL_CRATE;
use middle::lang_items::StartFnLangItem;
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::adjustment::CustomCoerceUnsized;
use rustc::dep_graph::{AssertDepGraphSafe, DepNode, WorkProduct};
use rustc::hir::map as hir_map;
use rustc::util::common::time;
Expand All @@ -54,7 +52,6 @@ use common::{C_bool, C_bytes_in_context, C_i32, C_uint};
use collector::{self, TransItemCollectionMode};
use common::{C_struct_in_context, C_u64, C_undef};
use common::CrateContext;
use common::{fulfill_obligation};
use common::{type_is_zero_size, val_ty};
use common;
use consts;
Expand All @@ -80,7 +77,7 @@ use std::ffi::{CStr, CString};
use std::rc::Rc;
use std::str;
use std::i32;
use syntax_pos::{Span, DUMMY_SP};
use syntax_pos::Span;
use syntax::attr;
use rustc::hir;
use rustc::ty::layout::{self, Layout};
Expand Down Expand Up @@ -313,25 +310,6 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
}
}

pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx>,
source_ty: Ty<'tcx>,
target_ty: Ty<'tcx>)
-> CustomCoerceUnsized {
let trait_ref = ty::Binder(ty::TraitRef {
def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(),
substs: scx.tcx().mk_substs_trait(source_ty, &[target_ty])
});

match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
scx.tcx().custom_coerce_unsized_kind(impl_def_id)
}
vtable => {
bug!("invalid CoerceUnsized vtable: {:?}", vtable);
}
}
}

pub fn cast_shift_expr_rhs(
cx: &Builder, op: hir::BinOp_, lhs: ValueRef, rhs: ValueRef
) -> ValueRef {
Expand Down

0 comments on commit aac5ba5

Please sign in to comment.