Skip to content

Commit 134c4a0

Browse files
committed
Auto merge of #39628 - arielb1:shimmir, r=eddyb
Translate shims using MIR This removes one large remaining part of old trans.
2 parents 244f893 + 5dc8548 commit 134c4a0

File tree

88 files changed

+2797
-3169
lines changed

Some content is hidden

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

88 files changed

+2797
-3169
lines changed

src/libcore/intrinsics.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,13 @@
4646
issue = "0")]
4747
#![allow(missing_docs)]
4848

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

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

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

630+
#[cfg(stage0)]
625631
/// Executes the destructor (if any) of the pointed-to value.
626632
///
627633
/// This has two use cases:

src/libcore/ptr.rs

+29
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,38 @@ pub use intrinsics::copy;
3737
#[stable(feature = "rust1", since = "1.0.0")]
3838
pub use intrinsics::write_bytes;
3939

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

44+
#[cfg(not(stage0))]
45+
/// Executes the destructor (if any) of the pointed-to value.
46+
///
47+
/// This has two use cases:
48+
///
49+
/// * It is *required* to use `drop_in_place` to drop unsized types like
50+
/// trait objects, because they can't be read out onto the stack and
51+
/// dropped normally.
52+
///
53+
/// * It is friendlier to the optimizer to do this over `ptr::read` when
54+
/// dropping manually allocated memory (e.g. when writing Box/Rc/Vec),
55+
/// as the compiler doesn't need to prove that it's sound to elide the
56+
/// copy.
57+
///
58+
/// # Undefined Behavior
59+
///
60+
/// This has all the same safety problems as `ptr::read` with respect to
61+
/// invalid pointers, types, and double drops.
62+
#[stable(feature = "drop_in_place", since = "1.8.0")]
63+
#[lang="drop_in_place"]
64+
#[inline]
65+
#[allow(unconditional_recursion)]
66+
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
67+
// Code here does not matter - this is replaced by the
68+
// real drop glue by the compiler.
69+
drop_in_place(to_drop);
70+
}
71+
4372
/// Creates a null raw pointer.
4473
///
4574
/// # Examples

src/librustc/dep_graph/dep_node.rs

+5
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub enum DepNode<D: Clone + Debug> {
8989
// things read/modify that MIR.
9090
MirKrate,
9191
Mir(D),
92+
MirShim(Vec<D>),
9293

9394
BorrowCheckKrate,
9495
BorrowCheck(D),
@@ -258,6 +259,10 @@ impl<D: Clone + Debug> DepNode<D> {
258259
IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
259260
MatchCheck(ref d) => op(d).map(MatchCheck),
260261
Mir(ref d) => op(d).map(Mir),
262+
MirShim(ref def_ids) => {
263+
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
264+
def_ids.map(MirShim)
265+
}
261266
BorrowCheck(ref d) => op(d).map(BorrowCheck),
262267
RvalueCheck(ref d) => op(d).map(RvalueCheck),
263268
StabilityCheck(ref d) => op(d).map(StabilityCheck),

src/librustc/middle/lang_items.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ language_item_table! {
335335

336336
ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
337337
BoxFreeFnLangItem, "box_free", box_free_fn;
338-
StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
338+
DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn;
339339

340340
StartFnLangItem, "start", start_fn;
341341

@@ -355,8 +355,6 @@ language_item_table! {
355355
ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime;
356356
InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime;
357357

358-
NoCopyItem, "no_copy_bound", no_copy_bound;
359-
360358
NonZeroItem, "non_zero", non_zero;
361359

362360
DebugTraitLangItem, "debug_trait", debug_trait;

src/librustc/mir/mod.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccesso
1717
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
1818
use hir::def::CtorKind;
1919
use hir::def_id::DefId;
20-
use ty::subst::Substs;
20+
use ty::subst::{Subst, Substs};
2121
use ty::{self, AdtDef, ClosureSubsts, Region, Ty};
2222
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
2323
use util::ppaux;
@@ -982,6 +982,22 @@ impl<'tcx> Debug for Operand<'tcx> {
982982
}
983983
}
984984

985+
impl<'tcx> Operand<'tcx> {
986+
pub fn item<'a>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
987+
def_id: DefId,
988+
substs: &'tcx Substs<'tcx>,
989+
span: Span)
990+
-> Self
991+
{
992+
Operand::Constant(Constant {
993+
span: span,
994+
ty: tcx.item_type(def_id).subst(tcx, substs),
995+
literal: Literal::Item { def_id, substs }
996+
})
997+
}
998+
999+
}
1000+
9851001
///////////////////////////////////////////////////////////////////////////
9861002
/// Rvalues
9871003

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
4040
pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
4141
pub use self::select::{MethodMatchedData}; // intentionally don't export variants
4242
pub use self::specialize::{OverlapError, specialization_graph, specializes, translate_substs};
43-
pub use self::specialize::{SpecializesCache, find_method};
43+
pub use self::specialize::{SpecializesCache, find_associated_item};
4444
pub use self::util::elaborate_predicates;
4545
pub use self::util::supertraits;
4646
pub use self::util::Supertraits;

src/librustc/traits/specialize/mod.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ use traits::{self, Reveal, ObligationCause};
2929
use ty::{self, TyCtxt, TypeFoldable};
3030
use syntax_pos::DUMMY_SP;
3131

32-
use syntax::ast;
33-
3432
pub mod specialization_graph;
3533

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

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

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

123122
let ancestors = trait_def.ancestors(impl_data.impl_def_id);
124-
match ancestors.defs(tcx, name, ty::AssociatedKind::Method).next() {
123+
match ancestors.defs(tcx, item.name, item.kind).next() {
125124
Some(node_item) => {
126125
let substs = tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
127126
let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
@@ -137,7 +136,7 @@ pub fn find_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
137136
(node_item.item.def_id, substs)
138137
}
139138
None => {
140-
bug!("method {:?} not found in {:?}", name, impl_data.impl_def_id)
139+
bug!("{:?} not found in {:?}", item, impl_data.impl_def_id)
141140
}
142141
}
143142
}

src/librustc/ty/context.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,15 @@ impl<T, R> InternIteratorElement<T, R> for T {
14691469
}
14701470
}
14711471

1472+
impl<'a, T, R> InternIteratorElement<T, R> for &'a T
1473+
where T: Clone + 'a
1474+
{
1475+
type Output = R;
1476+
fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
1477+
f(&iter.cloned().collect::<AccumulateVec<[_; 8]>>())
1478+
}
1479+
}
1480+
14721481
impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
14731482
type Output = Result<R, E>;
14741483
fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {

src/librustc/ty/instance.rs

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use dep_graph::DepNode;
12+
use hir::def_id::DefId;
13+
use ty::{self, Ty, TypeFoldable, Substs};
14+
use util::ppaux;
15+
16+
use std::borrow::Cow;
17+
use std::fmt;
18+
use syntax::ast;
19+
20+
21+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
22+
pub struct Instance<'tcx> {
23+
pub def: InstanceDef<'tcx>,
24+
pub substs: &'tcx Substs<'tcx>,
25+
}
26+
27+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
28+
pub enum InstanceDef<'tcx> {
29+
Item(DefId),
30+
Intrinsic(DefId),
31+
// <fn() as FnTrait>::call_*
32+
// def-id is FnTrait::call_*
33+
FnPtrShim(DefId, Ty<'tcx>),
34+
// <Trait as Trait>::fn
35+
Virtual(DefId, usize),
36+
// <[mut closure] as FnOnce>::call_once
37+
ClosureOnceShim { call_once: DefId },
38+
// drop_in_place::<T>; None for empty drop glue.
39+
DropGlue(DefId, Option<Ty<'tcx>>),
40+
}
41+
42+
impl<'tcx> InstanceDef<'tcx> {
43+
#[inline]
44+
pub fn def_id(&self) -> DefId {
45+
match *self {
46+
InstanceDef::Item(def_id) |
47+
InstanceDef::FnPtrShim(def_id, _) |
48+
InstanceDef::Virtual(def_id, _) |
49+
InstanceDef::Intrinsic(def_id, ) |
50+
InstanceDef::ClosureOnceShim { call_once: def_id }
51+
=> def_id,
52+
InstanceDef::DropGlue(def_id, _) => def_id
53+
}
54+
}
55+
56+
#[inline]
57+
pub fn def_ty<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
58+
tcx.item_type(self.def_id())
59+
}
60+
61+
#[inline]
62+
pub fn attrs<'a>(&self, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Cow<'tcx, [ast::Attribute]> {
63+
tcx.get_attrs(self.def_id())
64+
}
65+
66+
pub(crate) fn dep_node(&self) -> DepNode<DefId> {
67+
// HACK: def-id binning, project-style; someone replace this with
68+
// real on-demand.
69+
let ty = match self {
70+
&InstanceDef::FnPtrShim(_, ty) => Some(ty),
71+
&InstanceDef::DropGlue(_, ty) => ty,
72+
_ => None
73+
}.into_iter();
74+
75+
DepNode::MirShim(
76+
Some(self.def_id()).into_iter().chain(
77+
ty.flat_map(|t| t.walk()).flat_map(|t| match t.sty {
78+
ty::TyAdt(adt_def, _) => Some(adt_def.did),
79+
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
80+
_ => None,
81+
})
82+
).collect()
83+
)
84+
}
85+
}
86+
87+
impl<'tcx> fmt::Display for Instance<'tcx> {
88+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89+
ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
90+
match self.def {
91+
InstanceDef::Item(_) => Ok(()),
92+
InstanceDef::Intrinsic(_) => {
93+
write!(f, " - intrinsic")
94+
}
95+
InstanceDef::Virtual(_, num) => {
96+
write!(f, " - shim(#{})", num)
97+
}
98+
InstanceDef::FnPtrShim(_, ty) => {
99+
write!(f, " - shim({:?})", ty)
100+
}
101+
InstanceDef::ClosureOnceShim { .. } => {
102+
write!(f, " - shim")
103+
}
104+
InstanceDef::DropGlue(_, ty) => {
105+
write!(f, " - shim({:?})", ty)
106+
}
107+
}
108+
}
109+
}
110+
111+
impl<'a, 'b, 'tcx> Instance<'tcx> {
112+
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
113+
-> Instance<'tcx> {
114+
assert!(substs.is_normalized_for_trans() && !substs.has_escaping_regions(),
115+
"substs of instance {:?} not normalized for trans: {:?}",
116+
def_id, substs);
117+
Instance { def: InstanceDef::Item(def_id), substs: substs }
118+
}
119+
120+
pub fn mono(tcx: ty::TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
121+
Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
122+
}
123+
124+
#[inline]
125+
pub fn def_id(&self) -> DefId {
126+
self.def.def_id()
127+
}
128+
}

0 commit comments

Comments
 (0)