From 34329d6f6c73a6f0080e169007d099a40db3aea1 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Sat, 29 Oct 2022 16:19:57 +0300 Subject: [PATCH] introduce AstConv::probe_adt --- .../rustc_hir_analysis/src/astconv/mod.rs | 22 +++++++++++++------ compiler/rustc_hir_analysis/src/collect.rs | 5 +++++ .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 13 ++++++----- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 17 +++++++++----- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index bcb695cc8e3..df6600626a3 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -106,9 +106,12 @@ fn projected_ty_from_poly_trait_ref( poly_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Ty<'tcx>; - fn normalize_ty_2(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { - ty - } + /// Returns `AdtDef` if `ty` is an ADT. + /// Note that `ty` might be a projection type that needs normalization. + /// This used to get the enum variants in scope of the type. + /// For example, `Self::A` could refer to an associated type + /// or to an enum variant depending on the result of this function. + fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option>; /// Invoked when we encounter an error from some prior pass /// (e.g., resolve) that is translated into a ty-error. This is @@ -1805,7 +1808,7 @@ pub fn associated_path_to_ty( // Check if we have an enum variant. let mut variant_resolution = None; - if let ty::Adt(adt_def, adt_substs) = self.normalize_ty_2(span, qself_ty).kind() { + if let Some(adt_def) = self.probe_adt(span, qself_ty) { if adt_def.is_enum() { let variant_def = adt_def .variants() @@ -1907,6 +1910,10 @@ pub fn associated_path_to_ty( let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else { continue; }; + let ty::Adt(_, adt_substs) = qself_ty.kind() else { + // FIXME(inherent_associated_types) + bug!("unimplemented: non-adt self of inherent assoc ty"); + }; let item_substs = self.create_substs_for_associated_item( span, assoc_ty_did, @@ -2262,6 +2269,7 @@ pub fn def_ids_for_value_path_segments( self_ty: Option>, kind: DefKind, def_id: DefId, + span: Span, ) -> Vec { // We need to extract the type parameters supplied by the user in // the path `path`. Due to the current setup, this is a bit of a @@ -2329,8 +2337,8 @@ pub fn def_ids_for_value_path_segments( // Case 2. Reference to a variant constructor. DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => { - let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap()); - let (generics_def_id, index) = if let Some(adt_def) = adt_def { + let (generics_def_id, index) = if let Some(self_ty) = self_ty { + let adt_def = self.probe_adt(span, self_ty).unwrap(); debug_assert!(adt_def.is_enum()); (adt_def.did(), last) } else if last >= 1 && segments[last - 1].args.is_some() { @@ -2426,7 +2434,7 @@ pub fn res_to_ty( assert_eq!(opt_self_ty, None); let path_segs = - self.def_ids_for_value_path_segments(path.segments, None, kind, def_id); + self.def_ids_for_value_path_segments(path.segments, None, kind, def_id, span); let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); self.prohibit_generics( diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index fd54aec480a..b7f259668a1 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -505,6 +505,11 @@ fn projected_ty_from_poly_trait_ref( } } + fn probe_adt(&self, _span: Span, ty: Ty<'tcx>) -> Option> { + // FIXME(#103640): Should we handle the case where `ty` is a projection? + ty.ty_adt_def() + } + fn set_tainted_by_errors(&self, _: ErrorGuaranteed) { // There's no obvious place to track this, so just let it go. } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 3e05f67b74b..6c2dfaf4413 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1007,9 +1007,10 @@ pub fn instantiate_value_path( Res::Def(kind, def_id) => >::def_ids_for_value_path_segments( self, segments, - self_ty.map(|ty| ty.normalized), + self_ty.map(|ty| ty.raw), kind, def_id, + span, ), _ => bug!("instantiate_value_path on {:?}", res), }; @@ -1122,7 +1123,8 @@ pub fn instantiate_value_path( .unwrap_or(false); let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res { - let ty = self.normalize_ty_2(span, tcx.at(span).type_of(impl_def_id)); + let ty = tcx.at(span).type_of(impl_def_id); + let ty = self.normalize(span, ty); match *ty.kind() { ty::Adt(adt_def, substs) if adt_def.has_ctor() => { let variant = adt_def.non_enum_variant(); @@ -1238,10 +1240,9 @@ fn inferred_kind( // If we have a default, then we it doesn't matter that we're not // inferring the type arguments: we provide the default where any // is missing. - let default = tcx.bound_type_of(param.def_id); - self.fcx - .normalize_ty_2(self.span, default.subst(tcx, substs.unwrap())) - .into() + let default = + tcx.bound_type_of(param.def_id).subst(tcx, substs.unwrap()); + self.fcx.normalize(self.span, default).into() } else { // If no type arguments were provided, we have to infer them. // This case also occurs as a result of some malformed input, e.g. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index d7e53a0aa04..6347b9a69a0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -297,11 +297,14 @@ fn projected_ty_from_poly_trait_ref( self.tcx().mk_projection(item_def_id, item_substs) } - fn normalize_ty_2(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { - if ty.has_escaping_bound_vars() { - ty // FIXME: normalization and escaping regions - } else { - self.normalize(span, ty) + fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option> { + match ty.kind() { + ty::Adt(adt_def, _) => Some(*adt_def), + // FIXME(#104767): Should we handle bound regions here? + ty::Alias(ty::Projection, _) if !ty.has_escaping_bound_vars() => { + self.normalize(span, ty).ty_adt_def() + } + _ => None, } } @@ -310,7 +313,9 @@ fn set_tainted_by_errors(&self, e: ErrorGuaranteed) { } fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) { - self.write_ty(hir_id, self.normalize_ty_2(span, ty)) + // FIXME: normalization and escaping regions + let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty }; + self.write_ty(hir_id, ty) } } -- 2.44.0