Skip to content

Commit

Permalink
Auto merge of #39628 - arielb1:shimmir, r=eddyb
Browse files Browse the repository at this point in the history
Translate shims using MIR

This removes one large remaining part of old trans.
  • Loading branch information
bors committed Mar 20, 2017
2 parents 244f893 + 5dc8548 commit 134c4a0
Show file tree
Hide file tree
Showing 88 changed files with 2,797 additions and 3,169 deletions.
8 changes: 7 additions & 1 deletion src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@
issue = "0")]
#![allow(missing_docs)]

extern "rust-intrinsic" {
#[cfg(not(stage0))]
#[stable(feature = "drop_in_place", since = "1.8.0")]
#[rustc_deprecated(reason = "no longer an intrinsic - use `ptr::drop_in_place` directly",
since = "1.18.0")]
pub use ptr::drop_in_place;

extern "rust-intrinsic" {
// NB: These intrinsics take raw pointers because they mutate aliased
// memory, which is not valid for either `&` or `&mut`.

Expand Down Expand Up @@ -622,6 +627,7 @@ extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: &T) -> usize;
pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;

#[cfg(stage0)]
/// Executes the destructor (if any) of the pointed-to value.
///
/// This has two use cases:
Expand Down
29 changes: 29 additions & 0 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,38 @@ pub use intrinsics::copy;
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::write_bytes;

#[cfg(stage0)]
#[stable(feature = "drop_in_place", since = "1.8.0")]
pub use intrinsics::drop_in_place;

#[cfg(not(stage0))]
/// Executes the destructor (if any) of the pointed-to value.
///
/// This has two use cases:
///
/// * It is *required* to use `drop_in_place` to drop unsized types like
/// trait objects, because they can't be read out onto the stack and
/// dropped normally.
///
/// * It is friendlier to the optimizer to do this over `ptr::read` when
/// dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
/// as the compiler doesn't need to prove that it's sound to elide the
/// copy.
///
/// # Undefined Behavior
///
/// This has all the same safety problems as `ptr::read` with respect to
/// invalid pointers, types, and double drops.
#[stable(feature = "drop_in_place", since = "1.8.0")]
#[lang="drop_in_place"]
#[inline]
#[allow(unconditional_recursion)]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
// Code here does not matter - this is replaced by the
// real drop glue by the compiler.
drop_in_place(to_drop);
}

/// Creates a null raw pointer.
///
/// # Examples
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub enum DepNode<D: Clone + Debug> {
// things read/modify that MIR.
MirKrate,
Mir(D),
MirShim(Vec<D>),

BorrowCheckKrate,
BorrowCheck(D),
Expand Down Expand Up @@ -258,6 +259,10 @@ impl<D: Clone + Debug> DepNode<D> {
IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
MatchCheck(ref d) => op(d).map(MatchCheck),
Mir(ref d) => op(d).map(Mir),
MirShim(ref def_ids) => {
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
def_ids.map(MirShim)
}
BorrowCheck(ref d) => op(d).map(BorrowCheck),
RvalueCheck(ref d) => op(d).map(RvalueCheck),
StabilityCheck(ref d) => op(d).map(StabilityCheck),
Expand Down
4 changes: 1 addition & 3 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ language_item_table! {

ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
BoxFreeFnLangItem, "box_free", box_free_fn;
StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn;

StartFnLangItem, "start", start_fn;

Expand All @@ -355,8 +355,6 @@ language_item_table! {
ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime;
InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime;

NoCopyItem, "no_copy_bound", no_copy_bound;

NonZeroItem, "non_zero", non_zero;

DebugTraitLangItem, "debug_trait", debug_trait;
Expand Down
18 changes: 17 additions & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccesso
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
use hir::def::CtorKind;
use hir::def_id::DefId;
use ty::subst::Substs;
use ty::subst::{Subst, Substs};
use ty::{self, AdtDef, ClosureSubsts, Region, Ty};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use util::ppaux;
Expand Down Expand Up @@ -982,6 +982,22 @@ impl<'tcx> Debug for Operand<'tcx> {
}
}

impl<'tcx> Operand<'tcx> {
pub fn item<'a>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
substs: &'tcx Substs<'tcx>,
span: Span)
-> Self
{
Operand::Constant(Constant {
span: span,
ty: tcx.item_type(def_id).subst(tcx, substs),
literal: Literal::Item { def_id, substs }
})
}

}

///////////////////////////////////////////////////////////////////////////
/// Rvalues

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
128 changes: 128 additions & 0 deletions src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use dep_graph::DepNode;
use hir::def_id::DefId;
use ty::{self, Ty, TypeFoldable, Substs};
use util::ppaux;

use std::borrow::Cow;
use std::fmt;
use syntax::ast;


#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Instance<'tcx> {
pub def: InstanceDef<'tcx>,
pub substs: &'tcx Substs<'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 },
// drop_in_place::<T>; None for empty drop glue.
DropGlue(DefId, Option<Ty<'tcx>>),
}

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

#[inline]
pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
tcx.item_type(self.def_id())
}

#[inline]
pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> {
tcx.get_attrs(self.def_id())
}

pub(crate) fn dep_node(&self) -> DepNode<DefId> {
// HACK: def-id binning, project-style; someone replace this with
// real on-demand.
let ty = match self {
&InstanceDef::FnPtrShim(_, ty) => Some(ty),
&InstanceDef::DropGlue(_, ty) => ty,
_ => None
}.into_iter();

DepNode::MirShim(
Some(self.def_id()).into_iter().chain(
ty.flat_map(|t| t.walk()).flat_map(|t| match t.sty {
ty::TyAdt(adt_def, _) => Some(adt_def.did),
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
_ => None,
})
).collect()
)
}
}

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(_) => Ok(()),
InstanceDef::Intrinsic(_) => {
write!(f, " - intrinsic")
}
InstanceDef::Virtual(_, num) => {
write!(f, " - shim(#{})", num)
}
InstanceDef::FnPtrShim(_, ty) => {
write!(f, " - shim({:?})", ty)
}
InstanceDef::ClosureOnceShim { .. } => {
write!(f, " - shim")
}
InstanceDef::DropGlue(_, ty) => {
write!(f, " - shim({:?})", ty)
}
}
}
}

impl<'a, 'b, 'tcx> Instance<'tcx> {
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
-> Instance<'tcx> {
assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
"substs of instance {:?} not normalized for trans: {:?}",
def_id, substs);
Instance { def: InstanceDef::Item(def_id), substs: substs }
}

pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
}

#[inline]
pub fn def_id(&self) -> DefId {
self.def.def_id()
}
}
Loading

0 comments on commit 134c4a0

Please sign in to comment.