about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2020-02-12 17:24:32 +0100
committerCamille GILLOT <gillot.camille@gmail.com>2020-02-13 18:53:21 +0100
commit0e652c550711b301086b8f5ead2f6c90418fe7a1 (patch)
tree3c451c0cd7eb9f665c6fa1b2c153d722d1c50968
parentbe493fe8cc40c3d3f6030a1313c1ff747fce770d (diff)
downloadrust-0e652c550711b301086b8f5ead2f6c90418fe7a1.tar.gz
rust-0e652c550711b301086b8f5ead2f6c90418fe7a1.zip
Move resolve_instance to rustc_ty.
-rw-r--r--Cargo.lock1
-rw-r--r--src/librustc/ty/instance.rs143
-rw-r--r--src/librustc/ty/mod.rs1
-rw-r--r--src/librustc_interface/callbacks.rs1
-rw-r--r--src/librustc_ty/Cargo.toml1
-rw-r--r--src/librustc_ty/instance.rs136
-rw-r--r--src/librustc_ty/lib.rs1
7 files changed, 161 insertions, 123 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 149f02b4b8c..007a7521290 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4123,6 +4123,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_hir",
  "rustc_span",
+ "rustc_target",
 ]
 
 [[package]]
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 335953fc41e..332fd0bf46f 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -1,12 +1,11 @@
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::middle::lang_items::DropInPlaceFnLangItem;
-use crate::traits;
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
+use rustc_data_structures::AtomicRef;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_macros::HashStable;
-use rustc_target::spec::abi::Abi;
 
 use std::fmt;
 
@@ -263,45 +262,7 @@ impl<'tcx> Instance<'tcx> {
         def_id: DefId,
         substs: SubstsRef<'tcx>,
     ) -> Option<Instance<'tcx>> {
-        debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
-        let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
-            debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
-            let item = tcx.associated_item(def_id);
-            resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
-        } else {
-            let ty = tcx.type_of(def_id);
-            let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, &ty);
-
-            let def = match item_type.kind {
-                ty::FnDef(..)
-                    if {
-                        let f = item_type.fn_sig(tcx);
-                        f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic
-                    } =>
-                {
-                    debug!(" => intrinsic");
-                    ty::InstanceDef::Intrinsic(def_id)
-                }
-                _ => {
-                    if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
-                        let ty = substs.type_at(0);
-                        if ty.needs_drop(tcx, param_env.with_reveal_all()) {
-                            debug!(" => nontrivial drop glue");
-                            ty::InstanceDef::DropGlue(def_id, Some(ty))
-                        } else {
-                            debug!(" => trivial drop glue");
-                            ty::InstanceDef::DropGlue(def_id, None)
-                        }
-                    } else {
-                        debug!(" => free item");
-                        ty::InstanceDef::Item(def_id)
-                    }
-                }
-            };
-            Some(Instance { def: def, substs: substs })
-        };
-        debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
-        result
+        (*RESOLVE_INSTANCE)(tcx, param_env, def_id, substs)
     }
 
     pub fn resolve_for_fn_ptr(
@@ -398,88 +359,6 @@ impl<'tcx> Instance<'tcx> {
     }
 }
 
-fn resolve_associated_item<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    trait_item: &ty::AssocItem,
-    param_env: ty::ParamEnv<'tcx>,
-    trait_id: DefId,
-    rcvr_substs: SubstsRef<'tcx>,
-) -> Option<Instance<'tcx>> {
-    let def_id = trait_item.def_id;
-    debug!(
-        "resolve_associated_item(trait_item={:?}, \
-            param_env={:?}, \
-            trait_id={:?}, \
-            rcvr_substs={:?})",
-        def_id, param_env, trait_id, rcvr_substs
-    );
-
-    let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
-    let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
-
-    // Now that we know which impl is being used, we can dispatch to
-    // the actual function:
-    match vtbl {
-        traits::VtableImpl(impl_data) => {
-            let (def_id, substs) =
-                traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data);
-
-            let resolved_item = tcx.associated_item(def_id);
-
-            // Since this is a trait item, we need to see if the item is either a trait default item
-            // or a specialization because we can't resolve those unless we can `Reveal::All`.
-            // NOTE: This should be kept in sync with the similar code in
-            // `rustc::traits::project::assemble_candidates_from_impls()`.
-            let eligible = if !resolved_item.defaultness.is_default() {
-                true
-            } else if param_env.reveal == traits::Reveal::All {
-                !trait_ref.needs_subst()
-            } else {
-                false
-            };
-
-            if !eligible {
-                return None;
-            }
-
-            let substs = tcx.erase_regions(&substs);
-            Some(ty::Instance::new(def_id, substs))
-        }
-        traits::VtableGenerator(generator_data) => Some(Instance {
-            def: ty::InstanceDef::Item(generator_data.generator_def_id),
-            substs: generator_data.substs,
-        }),
-        traits::VtableClosure(closure_data) => {
-            let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
-            Some(Instance::resolve_closure(
-                tcx,
-                closure_data.closure_def_id,
-                closure_data.substs,
-                trait_closure_kind,
-            ))
-        }
-        traits::VtableFnPointer(ref data) => Some(Instance {
-            def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
-            substs: rcvr_substs,
-        }),
-        traits::VtableObject(ref data) => {
-            let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
-            Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
-        }
-        traits::VtableBuiltin(..) => {
-            if tcx.lang_items().clone_trait().is_some() {
-                Some(Instance {
-                    def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
-                    substs: rcvr_substs,
-                })
-            } else {
-                None
-            }
-        }
-        traits::VtableAutoImpl(..) | traits::VtableParam(..) | traits::VtableTraitAlias(..) => None,
-    }
-}
-
 fn needs_fn_once_adapter_shim(
     actual_closure_kind: ty::ClosureKind,
     trait_closure_kind: ty::ClosureKind,
@@ -512,3 +391,21 @@ fn needs_fn_once_adapter_shim(
         (ty::ClosureKind::FnMut, _) | (ty::ClosureKind::FnOnce, _) => Err(()),
     }
 }
+
+fn resolve_instance_default(
+    _tcx: TyCtxt<'tcx>,
+    _param_env: ty::ParamEnv<'tcx>,
+    _def_id: DefId,
+    _substs: SubstsRef<'tcx>,
+) -> Option<Instance<'tcx>> {
+    unimplemented!()
+}
+
+pub static RESOLVE_INSTANCE: AtomicRef<
+    for<'tcx> fn(
+        TyCtxt<'tcx>,
+        ty::ParamEnv<'tcx>,
+        DefId,
+        SubstsRef<'tcx>,
+    ) -> Option<Instance<'tcx>>,
+> = AtomicRef::new(&(resolve_instance_default as _));
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 2bda99e6d20..04e8c0c38d7 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -83,6 +83,7 @@ pub use self::context::{
     CtxtInterners, GeneratorInteriorTypeCause, GlobalCtxt, Lift, TypeckTables,
 };
 
+pub use self::instance::RESOLVE_INSTANCE;
 pub use self::instance::{Instance, InstanceDef};
 
 pub use self::trait_def::TraitDef;
diff --git a/src/librustc_interface/callbacks.rs b/src/librustc_interface/callbacks.rs
index 803e8958572..7c8e682e9fb 100644
--- a/src/librustc_interface/callbacks.rs
+++ b/src/librustc_interface/callbacks.rs
@@ -58,4 +58,5 @@ pub fn setup_callbacks() {
     rustc_span::SPAN_DEBUG.swap(&(span_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
     rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
     TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_)));
+    rustc::ty::RESOLVE_INSTANCE.swap(&(rustc_ty::instance::resolve_instance as _));
 }
diff --git a/src/librustc_ty/Cargo.toml b/src/librustc_ty/Cargo.toml
index fb0d93fe5eb..52606e5fdfe 100644
--- a/src/librustc_ty/Cargo.toml
+++ b/src/librustc_ty/Cargo.toml
@@ -14,3 +14,4 @@ rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_span = { path = "../librustc_span" }
+rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
new file mode 100644
index 00000000000..66f189a5d97
--- /dev/null
+++ b/src/librustc_ty/instance.rs
@@ -0,0 +1,136 @@
+use rustc::traits;
+use rustc::ty::subst::SubstsRef;
+use rustc::ty::{self, Instance, TyCtxt, TypeFoldable};
+use rustc_hir::def_id::DefId;
+use rustc_target::spec::abi::Abi;
+
+use log::debug;
+
+pub fn resolve_instance<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    def_id: DefId,
+    substs: SubstsRef<'tcx>,
+) -> Option<Instance<'tcx>> {
+    debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
+    let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
+        debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
+        let item = tcx.associated_item(def_id);
+        resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
+    } else {
+        let ty = tcx.type_of(def_id);
+        let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, &ty);
+
+        let def = match item_type.kind {
+            ty::FnDef(..)
+                if {
+                    let f = item_type.fn_sig(tcx);
+                    f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic
+                } =>
+            {
+                debug!(" => intrinsic");
+                ty::InstanceDef::Intrinsic(def_id)
+            }
+            _ => {
+                if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
+                    let ty = substs.type_at(0);
+                    if ty.needs_drop(tcx, param_env.with_reveal_all()) {
+                        debug!(" => nontrivial drop glue");
+                        ty::InstanceDef::DropGlue(def_id, Some(ty))
+                    } else {
+                        debug!(" => trivial drop glue");
+                        ty::InstanceDef::DropGlue(def_id, None)
+                    }
+                } else {
+                    debug!(" => free item");
+                    ty::InstanceDef::Item(def_id)
+                }
+            }
+        };
+        Some(Instance { def: def, substs: substs })
+    };
+    debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
+    result
+}
+
+fn resolve_associated_item<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_item: &ty::AssocItem,
+    param_env: ty::ParamEnv<'tcx>,
+    trait_id: DefId,
+    rcvr_substs: SubstsRef<'tcx>,
+) -> Option<Instance<'tcx>> {
+    let def_id = trait_item.def_id;
+    debug!(
+        "resolve_associated_item(trait_item={:?}, \
+            param_env={:?}, \
+            trait_id={:?}, \
+            rcvr_substs={:?})",
+        def_id, param_env, trait_id, rcvr_substs
+    );
+
+    let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
+    let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
+
+    // Now that we know which impl is being used, we can dispatch to
+    // the actual function:
+    match vtbl {
+        traits::VtableImpl(impl_data) => {
+            let (def_id, substs) =
+                traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data);
+
+            let resolved_item = tcx.associated_item(def_id);
+
+            // Since this is a trait item, we need to see if the item is either a trait default item
+            // or a specialization because we can't resolve those unless we can `Reveal::All`.
+            // NOTE: This should be kept in sync with the similar code in
+            // `rustc::traits::project::assemble_candidates_from_impls()`.
+            let eligible = if !resolved_item.defaultness.is_default() {
+                true
+            } else if param_env.reveal == traits::Reveal::All {
+                !trait_ref.needs_subst()
+            } else {
+                false
+            };
+
+            if !eligible {
+                return None;
+            }
+
+            let substs = tcx.erase_regions(&substs);
+            Some(ty::Instance::new(def_id, substs))
+        }
+        traits::VtableGenerator(generator_data) => Some(Instance {
+            def: ty::InstanceDef::Item(generator_data.generator_def_id),
+            substs: generator_data.substs,
+        }),
+        traits::VtableClosure(closure_data) => {
+            let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
+            Some(Instance::resolve_closure(
+                tcx,
+                closure_data.closure_def_id,
+                closure_data.substs,
+                trait_closure_kind,
+            ))
+        }
+        traits::VtableFnPointer(ref data) => Some(Instance {
+            def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
+            substs: rcvr_substs,
+        }),
+        traits::VtableObject(ref data) => {
+            let index = traits::get_vtable_index_of_object_method(tcx, data, def_id);
+            Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs })
+        }
+        traits::VtableBuiltin(..) => {
+            if tcx.lang_items().clone_trait().is_some() {
+                Some(Instance {
+                    def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
+                    substs: rcvr_substs,
+                })
+            } else {
+                None
+            }
+        }
+        traits::VtableAutoImpl(..) | traits::VtableParam(..) | traits::VtableTraitAlias(..) => None,
+    }
+}
diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs
index 7eef19b94e4..f9ee4e20d27 100644
--- a/src/librustc_ty/lib.rs
+++ b/src/librustc_ty/lib.rs
@@ -17,6 +17,7 @@ extern crate log;
 use rustc::ty::query::Providers;
 
 mod common_traits;
+pub mod instance;
 mod needs_drop;
 mod ty;