Skip to content

Commit

Permalink
Update anon_const_type_of based on ConstArg refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
camelid committed Jun 14, 2024
1 parent ba97288 commit 26fed7d
Showing 1 changed file with 58 additions and 28 deletions.
86 changes: 58 additions & 28 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,59 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
let parent_node_id = tcx.parent_hir_id(hir_id);
let parent_node = tcx.hir_node(parent_node_id);

match parent_node {
// Anon consts "inside" the type system.
Node::ConstArg(&ConstArg {
hir_id: arg_hir_id,
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
..
}) if anon_hir_id == hir_id => const_arg_anon_type_of(tcx, arg_hir_id, def_id, span),

// Anon consts outside the type system.
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
if asm.operands.iter().any(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const }
| hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
_ => false,
}) =>
{
tcx.typeck(def_id).node_type(hir_id)
}
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
}

_ => Ty::new_error_with_message(
tcx,
span,
format!("unexpected anon const parent in type_of(): {parent_node:?}"),
),
}
}

fn const_arg_anon_type_of<'tcx>(
tcx: TyCtxt<'tcx>,
arg_hir_id: HirId,
anon_def_id: LocalDefId,
span: Span,
) -> Ty<'tcx> {
use hir::*;
use rustc_middle::ty::Ty;

let parent_node_id = tcx.parent_hir_id(arg_hir_id);
let parent_node = tcx.hir_node(parent_node_id);

let (generics, arg_idx) = match parent_node {
// Easy case: arrays repeat expressions.
Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. })
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
if constant.hir_id() == hir_id =>
if constant.hir_id() == arg_hir_id =>
{
return tcx.types.usize;
}
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == hir_id => {
let ty = tcx.typeck(def_id).node_type(e.hir_id);
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == arg_hir_id => {
let ty = tcx.typeck(anon_def_id).node_type(tcx.local_def_id_to_hir_id(anon_def_id));
let ty = tcx.fold_regions(ty, |r, _| {
if r.is_erased() { ty::Region::new_error_misc(tcx) } else { r }
});
Expand All @@ -56,24 +99,11 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
tcx.dcx().emit_err(TypeofReservedKeywordUsed { span, ty, opt_sugg });
return ty;
}
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
if asm.operands.iter().any(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const }
| hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
_ => false,
}) =>
{
return tcx.typeck(def_id).node_type(hir_id);
}
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
return tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx);
}
Node::GenericParam(&GenericParam {
def_id: param_def_id,
kind: GenericParamKind::Const { default: Some(ct), .. },
..
}) if ct.hir_id == hir_id => {
}) if ct.hir_id == arg_hir_id => {
return tcx
.type_of(param_def_id)
.no_bound_vars()
Expand Down Expand Up @@ -104,7 +134,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
// to a ty::Alias(ty::Projection, `<Self as Foo>::Assoc<3>`).
let item_def_id = tcx
.hir()
.parent_owner_iter(hir_id)
.parent_owner_iter(arg_hir_id)
.find(|(_, node)| matches!(node, OwnerNode::Item(_)))
.unwrap()
.0
Expand All @@ -124,7 +154,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
args.args
.iter()
.filter(|arg| arg.is_ty_or_const())
.position(|arg| arg.hir_id() == hir_id)
.position(|arg| arg.hir_id() == arg_hir_id)
})
.unwrap_or_else(|| {
bug!("no arg matching AnonConst in segment");
Expand All @@ -145,7 +175,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
ExprKind::MethodCall(segment, ..) | ExprKind::Path(QPath::TypeRelative(_, segment)),
..
}) => {
let body_owner = tcx.hir().enclosing_body_owner(hir_id);
let body_owner = tcx.hir().enclosing_body_owner(arg_hir_id);
let tables = tcx.typeck(body_owner);
// This may fail in case the method/path does not actually exist.
// As there is no relevant param for `def_id`, we simply return
Expand All @@ -163,10 +193,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
args.args
.iter()
.filter(|arg| arg.is_ty_or_const())
.position(|arg| arg.hir_id() == hir_id)
.position(|arg| arg.hir_id() == arg_hir_id)
})
.unwrap_or_else(|| {
bug!("no arg matching AnonConst in segment");
bug!("no arg matching ConstArg in segment");
});

(tcx.generics_of(type_dependent_def), idx)
Expand All @@ -185,18 +215,18 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
| ExprKind::Struct(&QPath::Resolved(_, path), ..),
..
}) => {
let body_owner = tcx.hir().enclosing_body_owner(hir_id);
let body_owner = tcx.hir().enclosing_body_owner(arg_hir_id);
let _tables = tcx.typeck(body_owner);
&*path
}
Node::Pat(pat) => {
if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) {
if let Some(path) = get_path_containing_arg_in_pat(pat, arg_hir_id) {
path
} else {
return Ty::new_error_with_message(
tcx,
span,
format!("unable to find const parent for {hir_id} in pat {pat:?}"),
format!("unable to find const parent for {arg_hir_id} in pat {pat:?}"),
);
}
}
Expand All @@ -217,14 +247,14 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
args.args
.iter()
.filter(|arg| arg.is_ty_or_const())
.position(|arg| arg.hir_id() == hir_id)
.position(|arg| arg.hir_id() == arg_hir_id)
.map(|index| (index, seg))
.or_else(|| {
args.constraints
.iter()
.copied()
.filter_map(AssocItemConstraint::ct)
.position(|ct| ct.hir_id == hir_id)
.position(|ct| ct.hir_id == arg_hir_id)
.map(|idx| (idx, seg))
})
}) else {
Expand All @@ -249,7 +279,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
return Ty::new_error_with_message(
tcx,
span,
format!("unexpected const parent in type_of(): {parent_node:?}"),
format!("unexpected const arg parent in type_of(): {parent_node:?}"),
);
}
};
Expand Down

0 comments on commit 26fed7d

Please sign in to comment.