summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/collect/type_of.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/collect/type_of.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs198
1 files changed, 121 insertions, 77 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 2bbdbe3a1..ae62119b1 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -1,7 +1,8 @@
use rustc_errors::{Applicability, StashKey};
use rustc_hir as hir;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::HirId;
+use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
@@ -388,86 +389,62 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
}
},
- Node::Item(item) => {
- match item.kind {
- ItemKind::Static(ty, .., body_id) => {
- if is_suggestable_infer_ty(ty) {
- infer_placeholder_type(
- tcx,
- def_id,
- body_id,
- ty.span,
- item.ident,
- "static variable",
- )
- } else {
- icx.to_ty(ty)
- }
- }
- ItemKind::Const(ty, _, body_id) => {
- if is_suggestable_infer_ty(ty) {
- infer_placeholder_type(
- tcx, def_id, body_id, ty.span, item.ident, "constant",
- )
- } else {
- icx.to_ty(ty)
- }
- }
- ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
- ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
- spans if spans.len() > 0 => {
- let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf {
- span: spans.into(),
- note: (),
- });
- Ty::new_error(tcx, guar)
- }
- _ => icx.to_ty(*self_ty),
- },
- ItemKind::Fn(..) => {
- let args = ty::GenericArgs::identity_for_item(tcx, def_id);
- Ty::new_fn_def(tcx, def_id.to_def_id(), args)
- }
- ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
- let def = tcx.adt_def(def_id);
- let args = ty::GenericArgs::identity_for_item(tcx, def_id);
- Ty::new_adt(tcx, def, args)
+ Node::Item(item) => match item.kind {
+ ItemKind::Static(ty, .., body_id) => {
+ if is_suggestable_infer_ty(ty) {
+ infer_placeholder_type(
+ tcx,
+ def_id,
+ body_id,
+ ty.span,
+ item.ident,
+ "static variable",
+ )
+ } else {
+ icx.to_ty(ty)
}
- ItemKind::OpaqueTy(OpaqueTy {
- origin: hir::OpaqueTyOrigin::TyAlias { .. },
- ..
- }) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
- // Opaque types desugared from `impl Trait`.
- ItemKind::OpaqueTy(&OpaqueTy {
- origin:
- hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
- in_trait,
- ..
- }) => {
- if in_trait && !tcx.defaultness(owner).has_value() {
- span_bug!(
- tcx.def_span(def_id),
- "tried to get type of this RPITIT with no definition"
- );
- }
- opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
+ }
+ ItemKind::Const(ty, _, body_id) => {
+ if is_suggestable_infer_ty(ty) {
+ infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
+ } else {
+ icx.to_ty(ty)
}
- ItemKind::Trait(..)
- | ItemKind::TraitAlias(..)
- | ItemKind::Macro(..)
- | ItemKind::Mod(..)
- | ItemKind::ForeignMod { .. }
- | ItemKind::GlobalAsm(..)
- | ItemKind::ExternCrate(..)
- | ItemKind::Use(..) => {
- span_bug!(
- item.span,
- "compute_type_of_item: unexpected item type: {:?}",
- item.kind
- );
+ }
+ ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
+ ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
+ spans if spans.len() > 0 => {
+ let guar = tcx
+ .sess
+ .emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
+ Ty::new_error(tcx, guar)
}
+ _ => icx.to_ty(*self_ty),
+ },
+ ItemKind::Fn(..) => {
+ let args = ty::GenericArgs::identity_for_item(tcx, def_id);
+ Ty::new_fn_def(tcx, def_id.to_def_id(), args)
}
- }
+ ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
+ let def = tcx.adt_def(def_id);
+ let args = ty::GenericArgs::identity_for_item(tcx, def_id);
+ Ty::new_adt(tcx, def, args)
+ }
+ ItemKind::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
+ |CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
+ |ty| ty.instantiate_identity(),
+ ),
+ ItemKind::Trait(..)
+ | ItemKind::TraitAlias(..)
+ | ItemKind::Macro(..)
+ | ItemKind::Mod(..)
+ | ItemKind::ForeignMod { .. }
+ | ItemKind::GlobalAsm(..)
+ | ItemKind::ExternCrate(..)
+ | ItemKind::Use(..) => {
+ span_bug!(item.span, "compute_type_of_item: unexpected item type: {:?}", item.kind);
+ }
+ },
Node::ForeignItem(foreign_item) => match foreign_item.kind {
ForeignItemKind::Fn(..) => {
@@ -514,6 +491,51 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
ty::EarlyBinder::bind(output)
}
+pub(super) fn type_of_opaque(
+ tcx: TyCtxt<'_>,
+ def_id: DefId,
+) -> Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
+ if let Some(def_id) = def_id.as_local() {
+ use rustc_hir::*;
+
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+ Ok(ty::EarlyBinder::bind(match tcx.hir().get(hir_id) {
+ Node::Item(item) => match item.kind {
+ ItemKind::OpaqueTy(OpaqueTy {
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
+ ..
+ }) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
+ // Opaque types desugared from `impl Trait`.
+ ItemKind::OpaqueTy(&OpaqueTy {
+ origin:
+ hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
+ in_trait,
+ ..
+ }) => {
+ if in_trait && !tcx.defaultness(owner).has_value() {
+ span_bug!(
+ tcx.def_span(def_id),
+ "tried to get type of this RPITIT with no definition"
+ );
+ }
+ opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
+ }
+ _ => {
+ span_bug!(item.span, "type_of_opaque: unexpected item type: {:?}", item.kind);
+ }
+ },
+
+ x => {
+ bug!("unexpected sort of node in type_of_opaque(): {:?}", x);
+ }
+ }))
+ } else {
+ // Foreign opaque type will go through the foreign provider
+ // and load the type from metadata.
+ Ok(tcx.type_of(def_id))
+ }
+}
+
fn infer_placeholder_type<'a>(
tcx: TyCtxt<'a>,
def_id: LocalDefId,
@@ -601,3 +623,25 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
.emit();
}
}
+
+pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
+ use hir::intravisit::Visitor;
+ if tcx.features().lazy_type_alias {
+ return true;
+ }
+ struct HasTait {
+ has_type_alias_impl_trait: bool,
+ }
+ impl<'tcx> Visitor<'tcx> for HasTait {
+ fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
+ if let hir::TyKind::OpaqueDef(..) = t.kind {
+ self.has_type_alias_impl_trait = true;
+ } else {
+ hir::intravisit::walk_ty(self, t);
+ }
+ }
+ }
+ let mut has_tait = HasTait { has_type_alias_impl_trait: false };
+ has_tait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0);
+ has_tait.has_type_alias_impl_trait
+}