Skip to content

Commit 5c3ec91

Browse files
committed
rustc: don't resolve Instances which would produce malformed shims.
1 parent 138f85d commit 5c3ec91

File tree

2 files changed

+88
-32
lines changed

2 files changed

+88
-32
lines changed

src/librustc/ty/instance.rs

+67-20
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
66
use rustc_hir::def::Namespace;
77
use rustc_hir::def_id::{CrateNum, DefId};
88
use rustc_macros::HashStable;
9+
use rustc_span::sym;
910
use rustc_target::spec::abi::Abi;
1011

1112
use std::fmt;
@@ -40,6 +41,11 @@ pub enum InstanceDef<'tcx> {
4041

4142
/// `<fn() as FnTrait>::call_*`
4243
/// `DefId` is `FnTrait::call_*`.
44+
///
45+
/// NB: the (`fn` pointer) type must be monomorphic for MIR shims to work.
46+
// FIXME(eddyb) support generating shims for a "shallow type",
47+
// e.g. `fn(_, _) -> _` instead of requiring a fully monomorphic
48+
// `fn(Foo, Bar) -> Baz` etc.
4349
FnPtrShim(DefId, Ty<'tcx>),
4450

4551
/// `<dyn Trait as Trait>::fn`, "direct calls" of which are implicitly
@@ -55,9 +61,19 @@ pub enum InstanceDef<'tcx> {
5561
},
5662

5763
/// `drop_in_place::<T>; None` for empty drop glue.
64+
///
65+
/// NB: the type must be monomorphic for MIR shims to work.
66+
// FIXME(eddyb) support generating shims for a "shallow type",
67+
// e.g. `Foo<_>` or `[_]` instead of requiring a fully monomorphic
68+
// `Foo<Bar>` or `[String]` etc.
5869
DropGlue(DefId, Option<Ty<'tcx>>),
5970

6071
///`<T as Clone>::clone` shim.
72+
///
73+
/// NB: the type must be monomorphic for MIR shims to work.
74+
// FIXME(eddyb) support generating shims for a "shallow type",
75+
// e.g. `Foo<_>` or `[_]` instead of requiring a fully monomorphic
76+
// `Foo<Bar>` or `[String]` etc.
6177
CloneShim(DefId, Ty<'tcx>),
6278
}
6379

@@ -282,21 +298,28 @@ impl<'tcx> Instance<'tcx> {
282298
debug!(" => intrinsic");
283299
ty::InstanceDef::Intrinsic(def_id)
284300
}
285-
_ => {
286-
if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
287-
let ty = substs.type_at(0);
288-
if ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) {
289-
debug!(" => nontrivial drop glue");
290-
ty::InstanceDef::DropGlue(def_id, Some(ty))
291-
} else {
292-
debug!(" => trivial drop glue");
293-
ty::InstanceDef::DropGlue(def_id, None)
301+
ty::FnDef(def_id, substs)
302+
if Some(def_id) == tcx.lang_items().drop_in_place_fn() =>
303+
{
304+
let ty = substs.type_at(0);
305+
306+
if ty.needs_drop(tcx, param_env) {
307+
// `DropGlue` requires a monomorphic aka concrete type.
308+
if ty.needs_subst() {
309+
return None;
294310
}
311+
312+
debug!(" => nontrivial drop glue");
313+
ty::InstanceDef::DropGlue(def_id, Some(ty))
295314
} else {
296-
debug!(" => free item");
297-
ty::InstanceDef::Item(def_id)
315+
debug!(" => trivial drop glue");
316+
ty::InstanceDef::DropGlue(def_id, None)
298317
}
299318
}
319+
_ => {
320+
debug!(" => free item");
321+
ty::InstanceDef::Item(def_id)
322+
}
300323
};
301324
Some(Instance { def: def, substs: substs })
302325
};
@@ -457,20 +480,44 @@ fn resolve_associated_item<'tcx>(
457480
trait_closure_kind,
458481
))
459482
}
460-
traits::VtableFnPointer(ref data) => Some(Instance {
461-
def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
462-
substs: rcvr_substs,
463-
}),
483+
traits::VtableFnPointer(ref data) => {
484+
// `FnPtrShim` requires a monomorphic aka concrete type.
485+
if data.fn_ty.needs_subst() {
486+
return None;
487+
}
488+
489+
Some(Instance {
490+
def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
491+
substs: rcvr_substs,
492+
})
493+
}
464494
traits::VtableObject(ref data) => {
465495
let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
466496
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
467497
}
468498
traits::VtableBuiltin(..) => {
469-
if tcx.lang_items().clone_trait().is_some() {
470-
Some(Instance {
471-
def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
472-
substs: rcvr_substs,
473-
})
499+
if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() {
500+
// FIXME(eddyb) use lang items for methods instead of names.
501+
let name = tcx.item_name(def_id);
502+
if name == sym::clone {
503+
let self_ty = trait_ref.self_ty();
504+
505+
// `CloneShim` requires a monomorphic aka concrete type.
506+
if self_ty.needs_subst() {
507+
return None;
508+
}
509+
510+
Some(Instance {
511+
def: ty::InstanceDef::CloneShim(def_id, self_ty),
512+
substs: rcvr_substs,
513+
})
514+
} else {
515+
assert_eq!(name, sym::clone_from);
516+
517+
// Use the default `fn clone_from` from `trait Clone`.
518+
let substs = tcx.erase_regions(&rcvr_substs);
519+
Some(ty::Instance::new(def_id, substs))
520+
}
474521
} else {
475522
None
476523
}

src/librustc_mir/shim.rs

+21-12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use rustc::mir::*;
22
use rustc::ty::layout::VariantIdx;
33
use rustc::ty::query::Providers;
44
use rustc::ty::subst::{InternalSubsts, Subst};
5-
use rustc::ty::{self, Ty, TyCtxt};
5+
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
66
use rustc_hir as hir;
77
use rustc_hir::def_id::DefId;
88

99
use rustc_index::vec::{Idx, IndexVec};
1010

11-
use rustc_span::{sym, Span};
11+
use rustc_span::Span;
1212
use rustc_target::spec::abi::Abi;
1313

1414
use std::fmt;
@@ -39,6 +39,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
3939
None,
4040
),
4141
ty::InstanceDef::FnPtrShim(def_id, ty) => {
42+
// FIXME(eddyb) support generating shims for a "shallow type",
43+
// e.g. `Foo<_>` or `[_]` instead of requiring a fully monomorphic
44+
// `Foo<Bar>` or `[String]` etc.
45+
assert!(!ty.needs_subst());
46+
4247
let trait_ = tcx.trait_of_item(def_id).unwrap();
4348
let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
4449
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
@@ -80,17 +85,21 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
8085
None,
8186
)
8287
}
83-
ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty),
88+
ty::InstanceDef::DropGlue(def_id, ty) => {
89+
// FIXME(eddyb) support generating shims for a "shallow type",
90+
// e.g. `Foo<_>` or `[_]` instead of requiring a fully monomorphic
91+
// `Foo<Bar>` or `[String]` etc.
92+
assert!(!ty.needs_subst());
93+
94+
build_drop_shim(tcx, def_id, ty)
95+
}
8496
ty::InstanceDef::CloneShim(def_id, ty) => {
85-
let name = tcx.item_name(def_id);
86-
if name == sym::clone {
87-
build_clone_shim(tcx, def_id, ty)
88-
} else if name == sym::clone_from {
89-
debug!("make_shim({:?}: using default trait implementation", instance);
90-
return tcx.optimized_mir(def_id);
91-
} else {
92-
bug!("builtin clone shim {:?} not supported", instance)
93-
}
97+
// FIXME(eddyb) support generating shims for a "shallow type",
98+
// e.g. `Foo<_>` or `[_]` instead of requiring a fully monomorphic
99+
// `Foo<Bar>` or `[String]` etc.
100+
assert!(!ty.needs_subst());
101+
102+
build_clone_shim(tcx, def_id, ty)
94103
}
95104
ty::InstanceDef::Virtual(..) => {
96105
bug!("InstanceDef::Virtual ({:?}) is for direct calls only", instance)

0 commit comments

Comments
 (0)