Skip to content

Commit 34329d6

Browse files
committed
introduce AstConv::probe_adt
1 parent d227506 commit 34329d6

File tree

4 files changed

+38
-19
lines changed

4 files changed

+38
-19
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,12 @@ pub trait AstConv<'tcx> {
106106
poly_trait_ref: ty::PolyTraitRef<'tcx>,
107107
) -> Ty<'tcx>;
108108

109-
fn normalize_ty_2(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
110-
ty
111-
}
109+
/// Returns `AdtDef` if `ty` is an ADT.
110+
/// Note that `ty` might be a projection type that needs normalization.
111+
/// This used to get the enum variants in scope of the type.
112+
/// For example, `Self::A` could refer to an associated type
113+
/// or to an enum variant depending on the result of this function.
114+
fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
112115

113116
/// Invoked when we encounter an error from some prior pass
114117
/// (e.g., resolve) that is translated into a ty-error. This is
@@ -1805,7 +1808,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
18051808

18061809
// Check if we have an enum variant.
18071810
let mut variant_resolution = None;
1808-
if let ty::Adt(adt_def, adt_substs) = self.normalize_ty_2(span, qself_ty).kind() {
1811+
if let Some(adt_def) = self.probe_adt(span, qself_ty) {
18091812
if adt_def.is_enum() {
18101813
let variant_def = adt_def
18111814
.variants()
@@ -1907,6 +1910,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
19071910
let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else {
19081911
continue;
19091912
};
1913+
let ty::Adt(_, adt_substs) = qself_ty.kind() else {
1914+
// FIXME(inherent_associated_types)
1915+
bug!("unimplemented: non-adt self of inherent assoc ty");
1916+
};
19101917
let item_substs = self.create_substs_for_associated_item(
19111918
span,
19121919
assoc_ty_did,
@@ -2262,6 +2269,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22622269
self_ty: Option<Ty<'tcx>>,
22632270
kind: DefKind,
22642271
def_id: DefId,
2272+
span: Span,
22652273
) -> Vec<PathSeg> {
22662274
// We need to extract the type parameters supplied by the user in
22672275
// the path `path`. Due to the current setup, this is a bit of a
@@ -2329,8 +2337,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23292337

23302338
// Case 2. Reference to a variant constructor.
23312339
DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
2332-
let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
2333-
let (generics_def_id, index) = if let Some(adt_def) = adt_def {
2340+
let (generics_def_id, index) = if let Some(self_ty) = self_ty {
2341+
let adt_def = self.probe_adt(span, self_ty).unwrap();
23342342
debug_assert!(adt_def.is_enum());
23352343
(adt_def.did(), last)
23362344
} else if last >= 1 && segments[last - 1].args.is_some() {
@@ -2426,7 +2434,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24262434
assert_eq!(opt_self_ty, None);
24272435

24282436
let path_segs =
2429-
self.def_ids_for_value_path_segments(path.segments, None, kind, def_id);
2437+
self.def_ids_for_value_path_segments(path.segments, None, kind, def_id, span);
24302438
let generic_segs: FxHashSet<_> =
24312439
path_segs.iter().map(|PathSeg(_, index)| index).collect();
24322440
self.prohibit_generics(

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,11 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
505505
}
506506
}
507507

508+
fn probe_adt(&self, _span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
509+
// FIXME(#103640): Should we handle the case where `ty` is a projection?
510+
ty.ty_adt_def()
511+
}
512+
508513
fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
509514
// There's no obvious place to track this, so just let it go.
510515
}

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,9 +1007,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10071007
Res::Def(kind, def_id) => <dyn AstConv<'_>>::def_ids_for_value_path_segments(
10081008
self,
10091009
segments,
1010-
self_ty.map(|ty| ty.normalized),
1010+
self_ty.map(|ty| ty.raw),
10111011
kind,
10121012
def_id,
1013+
span,
10131014
),
10141015
_ => bug!("instantiate_value_path on {:?}", res),
10151016
};
@@ -1122,7 +1123,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11221123
.unwrap_or(false);
11231124

11241125
let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
1125-
let ty = self.normalize_ty_2(span, tcx.at(span).type_of(impl_def_id));
1126+
let ty = tcx.at(span).type_of(impl_def_id);
1127+
let ty = self.normalize(span, ty);
11261128
match *ty.kind() {
11271129
ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
11281130
let variant = adt_def.non_enum_variant();
@@ -1238,10 +1240,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12381240
// If we have a default, then we it doesn't matter that we're not
12391241
// inferring the type arguments: we provide the default where any
12401242
// is missing.
1241-
let default = tcx.bound_type_of(param.def_id);
1242-
self.fcx
1243-
.normalize_ty_2(self.span, default.subst(tcx, substs.unwrap()))
1244-
.into()
1243+
let default =
1244+
tcx.bound_type_of(param.def_id).subst(tcx, substs.unwrap());
1245+
self.fcx.normalize(self.span, default).into()
12451246
} else {
12461247
// If no type arguments were provided, we have to infer them.
12471248
// This case also occurs as a result of some malformed input, e.g.

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,14 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
297297
self.tcx().mk_projection(item_def_id, item_substs)
298298
}
299299

300-
fn normalize_ty_2(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
301-
if ty.has_escaping_bound_vars() {
302-
ty // FIXME: normalization and escaping regions
303-
} else {
304-
self.normalize(span, ty)
300+
fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
301+
match ty.kind() {
302+
ty::Adt(adt_def, _) => Some(*adt_def),
303+
// FIXME(#104767): Should we handle bound regions here?
304+
ty::Alias(ty::Projection, _) if !ty.has_escaping_bound_vars() => {
305+
self.normalize(span, ty).ty_adt_def()
306+
}
307+
_ => None,
305308
}
306309
}
307310

@@ -310,7 +313,9 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
310313
}
311314

312315
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
313-
self.write_ty(hir_id, self.normalize_ty_2(span, ty))
316+
// FIXME: normalization and escaping regions
317+
let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
318+
self.write_ty(hir_id, ty)
314319
}
315320
}
316321

0 commit comments

Comments
 (0)