Skip to content

Commit f31a7da

Browse files
committed
Auto merge of #69100 - cjgillot:resolve_instance, r=Zoxc
Move resolve_instance to rustc_ty. r? @Zoxc
2 parents 21ed505 + 0e652c5 commit f31a7da

File tree

7 files changed

+161
-123
lines changed

7 files changed

+161
-123
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4124,6 +4124,7 @@ dependencies = [
41244124
"rustc_data_structures",
41254125
"rustc_hir",
41264126
"rustc_span",
4127+
"rustc_target",
41274128
]
41284129

41294130
[[package]]

src/librustc/ty/instance.rs

+20-123
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
22
use crate::middle::lang_items::DropInPlaceFnLangItem;
3-
use crate::traits;
43
use crate::ty::print::{FmtPrinter, Printer};
54
use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
5+
use rustc_data_structures::AtomicRef;
66
use rustc_hir::def::Namespace;
77
use rustc_hir::def_id::{CrateNum, DefId};
88
use rustc_macros::HashStable;
9-
use rustc_target::spec::abi::Abi;
109

1110
use std::fmt;
1211

@@ -263,45 +262,7 @@ impl<'tcx> Instance<'tcx> {
263262
def_id: DefId,
264263
substs: SubstsRef<'tcx>,
265264
) -> Option<Instance<'tcx>> {
266-
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
267-
let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
268-
debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
269-
let item = tcx.associated_item(def_id);
270-
resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
271-
} else {
272-
let ty = tcx.type_of(def_id);
273-
let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, &ty);
274-
275-
let def = match item_type.kind {
276-
ty::FnDef(..)
277-
if {
278-
let f = item_type.fn_sig(tcx);
279-
f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic
280-
} =>
281-
{
282-
debug!(" => intrinsic");
283-
ty::InstanceDef::Intrinsic(def_id)
284-
}
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, param_env.with_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)
294-
}
295-
} else {
296-
debug!(" => free item");
297-
ty::InstanceDef::Item(def_id)
298-
}
299-
}
300-
};
301-
Some(Instance { def: def, substs: substs })
302-
};
303-
debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
304-
result
265+
(*RESOLVE_INSTANCE)(tcx, param_env, def_id, substs)
305266
}
306267

307268
pub fn resolve_for_fn_ptr(
@@ -398,88 +359,6 @@ impl<'tcx> Instance<'tcx> {
398359
}
399360
}
400361

401-
fn resolve_associated_item<'tcx>(
402-
tcx: TyCtxt<'tcx>,
403-
trait_item: &ty::AssocItem,
404-
param_env: ty::ParamEnv<'tcx>,
405-
trait_id: DefId,
406-
rcvr_substs: SubstsRef<'tcx>,
407-
) -> Option<Instance<'tcx>> {
408-
let def_id = trait_item.def_id;
409-
debug!(
410-
"resolve_associated_item(trait_item={:?}, \
411-
param_env={:?}, \
412-
trait_id={:?}, \
413-
rcvr_substs={:?})",
414-
def_id, param_env, trait_id, rcvr_substs
415-
);
416-
417-
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
418-
let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
419-
420-
// Now that we know which impl is being used, we can dispatch to
421-
// the actual function:
422-
match vtbl {
423-
traits::VtableImpl(impl_data) => {
424-
let (def_id, substs) =
425-
traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data);
426-
427-
let resolved_item = tcx.associated_item(def_id);
428-
429-
// Since this is a trait item, we need to see if the item is either a trait default item
430-
// or a specialization because we can't resolve those unless we can `Reveal::All`.
431-
// NOTE: This should be kept in sync with the similar code in
432-
// `rustc::traits::project::assemble_candidates_from_impls()`.
433-
let eligible = if !resolved_item.defaultness.is_default() {
434-
true
435-
} else if param_env.reveal == traits::Reveal::All {
436-
!trait_ref.needs_subst()
437-
} else {
438-
false
439-
};
440-
441-
if !eligible {
442-
return None;
443-
}
444-
445-
let substs = tcx.erase_regions(&substs);
446-
Some(ty::Instance::new(def_id, substs))
447-
}
448-
traits::VtableGenerator(generator_data) => Some(Instance {
449-
def: ty::InstanceDef::Item(generator_data.generator_def_id),
450-
substs: generator_data.substs,
451-
}),
452-
traits::VtableClosure(closure_data) => {
453-
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
454-
Some(Instance::resolve_closure(
455-
tcx,
456-
closure_data.closure_def_id,
457-
closure_data.substs,
458-
trait_closure_kind,
459-
))
460-
}
461-
traits::VtableFnPointer(ref data) => Some(Instance {
462-
def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
463-
substs: rcvr_substs,
464-
}),
465-
traits::VtableObject(ref data) => {
466-
let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
467-
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
468-
}
469-
traits::VtableBuiltin(..) => {
470-
if tcx.lang_items().clone_trait().is_some() {
471-
Some(Instance {
472-
def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
473-
substs: rcvr_substs,
474-
})
475-
} else {
476-
None
477-
}
478-
}
479-
traits::VtableAutoImpl(..) | traits::VtableParam(..) | traits::VtableTraitAlias(..) => None,
480-
}
481-
}
482-
483362
fn needs_fn_once_adapter_shim(
484363
actual_closure_kind: ty::ClosureKind,
485364
trait_closure_kind: ty::ClosureKind,
@@ -512,3 +391,21 @@ fn needs_fn_once_adapter_shim(
512391
(ty::ClosureKind::FnMut, _) | (ty::ClosureKind::FnOnce, _) => Err(()),
513392
}
514393
}
394+
395+
fn resolve_instance_default(
396+
_tcx: TyCtxt<'tcx>,
397+
_param_env: ty::ParamEnv<'tcx>,
398+
_def_id: DefId,
399+
_substs: SubstsRef<'tcx>,
400+
) -> Option<Instance<'tcx>> {
401+
unimplemented!()
402+
}
403+
404+
pub static RESOLVE_INSTANCE: AtomicRef<
405+
for<'tcx> fn(
406+
TyCtxt<'tcx>,
407+
ty::ParamEnv<'tcx>,
408+
DefId,
409+
SubstsRef<'tcx>,
410+
) -> Option<Instance<'tcx>>,
411+
> = AtomicRef::new(&(resolve_instance_default as _));

src/librustc/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub use self::context::{
8383
CtxtInterners, GeneratorInteriorTypeCause, GlobalCtxt, Lift, TypeckTables,
8484
};
8585

86+
pub use self::instance::RESOLVE_INSTANCE;
8687
pub use self::instance::{Instance, InstanceDef};
8788

8889
pub use self::trait_def::TraitDef;

src/librustc_interface/callbacks.rs

+1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ pub fn setup_callbacks() {
5858
rustc_span::SPAN_DEBUG.swap(&(span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
5959
rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
6060
TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_)));
61+
rustc::ty::RESOLVE_INSTANCE.swap(&(rustc_ty::instance::resolve_instance as _));
6162
}

src/librustc_ty/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ rustc = { path = "../librustc" }
1414
rustc_data_structures = { path = "../librustc_data_structures" }
1515
rustc_hir = { path = "../librustc_hir" }
1616
rustc_span = { path = "../librustc_span" }
17+
rustc_target = { path = "../librustc_target" }

src/librustc_ty/instance.rs

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
use rustc::traits;
2+
use rustc::ty::subst::SubstsRef;
3+
use rustc::ty::{self, Instance, TyCtxt, TypeFoldable};
4+
use rustc_hir::def_id::DefId;
5+
use rustc_target::spec::abi::Abi;
6+
7+
use log::debug;
8+
9+
pub fn resolve_instance<'tcx>(
10+
tcx: TyCtxt<'tcx>,
11+
param_env: ty::ParamEnv<'tcx>,
12+
def_id: DefId,
13+
substs: SubstsRef<'tcx>,
14+
) -> Option<Instance<'tcx>> {
15+
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
16+
let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
17+
debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
18+
let item = tcx.associated_item(def_id);
19+
resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
20+
} else {
21+
let ty = tcx.type_of(def_id);
22+
let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, &ty);
23+
24+
let def = match item_type.kind {
25+
ty::FnDef(..)
26+
if {
27+
let f = item_type.fn_sig(tcx);
28+
f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic
29+
} =>
30+
{
31+
debug!(" => intrinsic");
32+
ty::InstanceDef::Intrinsic(def_id)
33+
}
34+
_ => {
35+
if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
36+
let ty = substs.type_at(0);
37+
if ty.needs_drop(tcx, param_env.with_reveal_all()) {
38+
debug!(" => nontrivial drop glue");
39+
ty::InstanceDef::DropGlue(def_id, Some(ty))
40+
} else {
41+
debug!(" => trivial drop glue");
42+
ty::InstanceDef::DropGlue(def_id, None)
43+
}
44+
} else {
45+
debug!(" => free item");
46+
ty::InstanceDef::Item(def_id)
47+
}
48+
}
49+
};
50+
Some(Instance { def: def, substs: substs })
51+
};
52+
debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
53+
result
54+
}
55+
56+
fn resolve_associated_item<'tcx>(
57+
tcx: TyCtxt<'tcx>,
58+
trait_item: &ty::AssocItem,
59+
param_env: ty::ParamEnv<'tcx>,
60+
trait_id: DefId,
61+
rcvr_substs: SubstsRef<'tcx>,
62+
) -> Option<Instance<'tcx>> {
63+
let def_id = trait_item.def_id;
64+
debug!(
65+
"resolve_associated_item(trait_item={:?}, \
66+
param_env={:?}, \
67+
trait_id={:?}, \
68+
rcvr_substs={:?})",
69+
def_id, param_env, trait_id, rcvr_substs
70+
);
71+
72+
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
73+
let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
74+
75+
// Now that we know which impl is being used, we can dispatch to
76+
// the actual function:
77+
match vtbl {
78+
traits::VtableImpl(impl_data) => {
79+
let (def_id, substs) =
80+
traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data);
81+
82+
let resolved_item = tcx.associated_item(def_id);
83+
84+
// Since this is a trait item, we need to see if the item is either a trait default item
85+
// or a specialization because we can't resolve those unless we can `Reveal::All`.
86+
// NOTE: This should be kept in sync with the similar code in
87+
// `rustc::traits::project::assemble_candidates_from_impls()`.
88+
let eligible = if !resolved_item.defaultness.is_default() {
89+
true
90+
} else if param_env.reveal == traits::Reveal::All {
91+
!trait_ref.needs_subst()
92+
} else {
93+
false
94+
};
95+
96+
if !eligible {
97+
return None;
98+
}
99+
100+
let substs = tcx.erase_regions(&substs);
101+
Some(ty::Instance::new(def_id, substs))
102+
}
103+
traits::VtableGenerator(generator_data) => Some(Instance {
104+
def: ty::InstanceDef::Item(generator_data.generator_def_id),
105+
substs: generator_data.substs,
106+
}),
107+
traits::VtableClosure(closure_data) => {
108+
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
109+
Some(Instance::resolve_closure(
110+
tcx,
111+
closure_data.closure_def_id,
112+
closure_data.substs,
113+
trait_closure_kind,
114+
))
115+
}
116+
traits::VtableFnPointer(ref data) => Some(Instance {
117+
def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
118+
substs: rcvr_substs,
119+
}),
120+
traits::VtableObject(ref data) => {
121+
let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
122+
Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
123+
}
124+
traits::VtableBuiltin(..) => {
125+
if tcx.lang_items().clone_trait().is_some() {
126+
Some(Instance {
127+
def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
128+
substs: rcvr_substs,
129+
})
130+
} else {
131+
None
132+
}
133+
}
134+
traits::VtableAutoImpl(..) | traits::VtableParam(..) | traits::VtableTraitAlias(..) => None,
135+
}
136+
}

src/librustc_ty/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern crate log;
1717
use rustc::ty::query::Providers;
1818

1919
mod common_traits;
20+
pub mod instance;
2021
mod needs_drop;
2122
mod ty;
2223

0 commit comments

Comments
 (0)