Skip to content

Commit f65f506

Browse files
committed
Remove opt_const_param_of.
1 parent b275d2c commit f65f506

File tree

3 files changed

+94
-182
lines changed

3 files changed

+94
-182
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
5555
pub fn provide(providers: &mut Providers) {
5656
resolve_bound_vars::provide(providers);
5757
*providers = Providers {
58-
opt_const_param_of: type_of::opt_const_param_of,
5958
type_of: type_of::type_of,
6059
item_bounds: item_bounds::item_bounds,
6160
explicit_item_bounds: item_bounds::explicit_item_bounds,

compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 94 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_errors::{Applicability, StashKey};
22
use rustc_hir as hir;
3-
use rustc_hir::def_id::{DefId, LocalDefId};
3+
use rustc_hir::def_id::LocalDefId;
44
use rustc_hir::intravisit;
55
use rustc_hir::intravisit::Visitor;
66
use rustc_hir::{HirId, Node};
@@ -16,22 +16,81 @@ use super::ItemCtxt;
1616
use super::{bad_placeholder, is_suggestable_infer_ty};
1717
use crate::errors::UnconstrainedOpaqueType;
1818

19-
/// Computes the relevant generic parameter for a potential generic const argument.
20-
///
21-
/// This should be called using the query `tcx.opt_const_param_of`.
22-
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
19+
fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
2320
use hir::*;
2421
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
2522

26-
match tcx.hir().get(hir_id) {
27-
Node::AnonConst(_) => (),
28-
_ => return None,
29-
};
23+
let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() };
3024

3125
let parent_node_id = tcx.hir().parent_id(hir_id);
3226
let parent_node = tcx.hir().get(parent_node_id);
3327

3428
let (generics, arg_idx) = match parent_node {
29+
// Easy case: arrays repeat expressions.
30+
Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
31+
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
32+
if constant.hir_id() == hir_id =>
33+
{
34+
return tcx.types.usize
35+
}
36+
Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => {
37+
return tcx.typeck(def_id).node_type(e.hir_id)
38+
}
39+
Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. })
40+
if anon_const.hir_id == hir_id =>
41+
{
42+
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
43+
return substs.as_inline_const().ty()
44+
}
45+
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
46+
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
47+
if asm.operands.iter().any(|(op, _op_sp)| match op {
48+
hir::InlineAsmOperand::Const { anon_const }
49+
| hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
50+
_ => false,
51+
}) =>
52+
{
53+
return tcx.typeck(def_id).node_type(hir_id)
54+
}
55+
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
56+
return tcx
57+
.adt_def(tcx.hir().get_parent_item(hir_id))
58+
.repr()
59+
.discr_type()
60+
.to_ty(tcx)
61+
}
62+
Node::GenericParam(&GenericParam {
63+
def_id: param_def_id,
64+
kind: GenericParamKind::Const { default: Some(ct), .. },
65+
..
66+
}) if ct.hir_id == hir_id => {
67+
return tcx.type_of(param_def_id)
68+
.no_bound_vars()
69+
.expect("const parameter types cannot be generic")
70+
}
71+
72+
Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
73+
if let Node::TraitRef(trait_ref) = tcx.hir().get(
74+
tcx.hir().parent_id(binding_id)
75+
) =>
76+
{
77+
let Some(trait_def_id) = trait_ref.trait_def_id() else {
78+
return tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find trait");
79+
};
80+
let assoc_items = tcx.associated_items(trait_def_id);
81+
let assoc_item = assoc_items.find_by_name_and_kind(
82+
tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(),
83+
);
84+
return if let Some(assoc_item) = assoc_item {
85+
tcx.type_of(assoc_item.def_id)
86+
.no_bound_vars()
87+
.expect("const parameter types cannot be generic")
88+
} else {
89+
// FIXME(associated_const_equality): add a useful error message here.
90+
tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find associated const on trait")
91+
}
92+
}
93+
3594
// This match arm is for when the def_id appears in a GAT whose
3695
// path can't be resolved without typechecking e.g.
3796
//
@@ -86,11 +145,10 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
86145
(generics, arg_index)
87146
} else {
88147
// I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU
89-
tcx.sess.delay_span_bug(
148+
return tcx.ty_error_with_message(
90149
tcx.def_span(def_id),
91150
"unexpected non-GAT usage of an anon const",
92151
);
93-
return None;
94152
}
95153
}
96154
Node::Expr(&Expr {
@@ -103,7 +161,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
103161
// This may fail in case the method/path does not actually exist.
104162
// As there is no relevant param for `def_id`, we simply return
105163
// `None` here.
106-
let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?;
164+
let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else {
165+
return tcx.ty_error_with_message(
166+
tcx.def_span(def_id),
167+
&format!("unable to find type-dependent def for {:?}", parent_node_id),
168+
);
169+
};
107170
let idx = segment
108171
.args
109172
.and_then(|args| {
@@ -140,19 +203,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
140203
if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) {
141204
path
142205
} else {
143-
tcx.sess.delay_span_bug(
206+
return tcx.ty_error_with_message(
144207
tcx.def_span(def_id),
145208
&format!("unable to find const parent for {} in pat {:?}", hir_id, pat),
146209
);
147-
return None;
148210
}
149211
}
150212
_ => {
151-
tcx.sess.delay_span_bug(
213+
return tcx.ty_error_with_message(
152214
tcx.def_span(def_id),
153215
&format!("unexpected const parent path {:?}", parent_node),
154216
);
155-
return None;
156217
}
157218
};
158219

@@ -171,32 +232,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
171232
.position(|ct| ct.hir_id == hir_id)
172233
.map(|idx| (idx, seg)))
173234
}) else {
174-
tcx.sess.delay_span_bug(
235+
return tcx.ty_error_with_message(
175236
tcx.def_span(def_id),
176237
"no arg matching AnonConst in path",
177238
);
178-
return None;
179239
};
180240

181241
let generics = match tcx.res_generics_def_id(segment.res) {
182242
Some(def_id) => tcx.generics_of(def_id),
183243
None => {
184-
tcx.sess.delay_span_bug(
244+
return tcx.ty_error_with_message(
185245
tcx.def_span(def_id),
186246
&format!("unexpected anon const res {:?} in path: {:?}", segment.res, path),
187247
);
188-
return None;
189248
}
190249
};
191250

192251
(generics, arg_index)
193252
}
194-
_ => return None,
253+
254+
_ => return tcx.ty_error_with_message(
255+
tcx.def_span(def_id),
256+
&format!("unexpected const parent in type_of(): {parent_node:?}"),
257+
),
195258
};
196259

197260
debug!(?parent_node);
198261
debug!(?generics, ?arg_idx);
199-
generics
262+
if let Some(param_def_id) = generics
200263
.params
201264
.iter()
202265
.filter(|param| param.kind.is_ty_or_const())
@@ -211,6 +274,14 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
211274
}
212275
_ => None,
213276
})
277+
{
278+
tcx.type_of(param_def_id).no_bound_vars().expect("const parameter types cannot be generic")
279+
} else {
280+
return tcx.ty_error_with_message(
281+
tcx.def_span(def_id),
282+
&format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"),
283+
);
284+
}
214285
}
215286

216287
fn get_path_containing_arg_in_pat<'hir>(
@@ -415,142 +486,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
415486
tcx.typeck(def_id).node_type(hir_id)
416487
}
417488

418-
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
419-
// We defer to `type_of` of the corresponding parameter
420-
// for generic arguments.
421-
tcx.type_of(param).subst_identity()
422-
}
423-
Node::AnonConst(_) => {
424-
let parent_node = tcx.hir().get_parent(hir_id);
425-
match parent_node {
426-
Node::Ty(Ty { kind: TyKind::Array(_, constant), .. })
427-
| Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
428-
if constant.hir_id() == hir_id =>
429-
{
430-
tcx.types.usize
431-
}
432-
Node::Ty(Ty { kind: TyKind::Typeof(e), .. }) if e.hir_id == hir_id => {
433-
tcx.typeck(def_id).node_type(e.hir_id)
434-
}
435-
436-
Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. })
437-
if anon_const.hir_id == hir_id =>
438-
{
439-
let substs = InternalSubsts::identity_for_item(tcx, def_id);
440-
substs.as_inline_const().ty()
441-
}
442-
443-
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
444-
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
445-
if asm.operands.iter().any(|(op, _op_sp)| match op {
446-
hir::InlineAsmOperand::Const { anon_const }
447-
| hir::InlineAsmOperand::SymFn { anon_const } => {
448-
anon_const.hir_id == hir_id
449-
}
450-
_ => false,
451-
}) =>
452-
{
453-
tcx.typeck(def_id).node_type(hir_id)
454-
}
455-
456-
Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
457-
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
458-
}
459-
460-
Node::TypeBinding(TypeBinding {
461-
hir_id: binding_id,
462-
kind: TypeBindingKind::Equality { term: Term::Const(e) },
463-
ident,
464-
..
465-
}) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
466-
&& e.hir_id == hir_id =>
467-
{
468-
let Some(trait_def_id) = trait_ref.trait_def_id() else {
469-
return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
470-
};
471-
let assoc_items = tcx.associated_items(trait_def_id);
472-
let assoc_item = assoc_items.find_by_name_and_kind(
473-
tcx,
474-
*ident,
475-
ty::AssocKind::Const,
476-
def_id.to_def_id(),
477-
);
478-
if let Some(assoc_item) = assoc_item {
479-
tcx.type_of(assoc_item.def_id)
480-
.no_bound_vars()
481-
.expect("const parameter types cannot be generic")
482-
} else {
483-
// FIXME(associated_const_equality): add a useful error message here.
484-
tcx.ty_error_with_message(
485-
DUMMY_SP,
486-
"Could not find associated const on trait",
487-
)
488-
}
489-
}
490-
491-
Node::TypeBinding(TypeBinding {
492-
hir_id: binding_id,
493-
gen_args,
494-
kind,
495-
ident,
496-
..
497-
}) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
498-
&& let Some((idx, _)) =
499-
gen_args.args.iter().enumerate().find(|(_, arg)| {
500-
if let GenericArg::Const(ct) = arg {
501-
ct.value.hir_id == hir_id
502-
} else {
503-
false
504-
}
505-
}) =>
506-
{
507-
let Some(trait_def_id) = trait_ref.trait_def_id() else {
508-
return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
509-
};
510-
let assoc_items = tcx.associated_items(trait_def_id);
511-
let assoc_item = assoc_items.find_by_name_and_kind(
512-
tcx,
513-
*ident,
514-
match kind {
515-
// I think `<A: T>` type bindings requires that `A` is a type
516-
TypeBindingKind::Constraint { .. }
517-
| TypeBindingKind::Equality { term: Term::Ty(..) } => {
518-
ty::AssocKind::Type
519-
}
520-
TypeBindingKind::Equality { term: Term::Const(..) } => {
521-
ty::AssocKind::Const
522-
}
523-
},
524-
def_id.to_def_id(),
525-
);
526-
if let Some(assoc_item) = assoc_item
527-
&& let param = &tcx.generics_of(assoc_item.def_id).params[idx]
528-
&& matches!(param.kind, ty::GenericParamDefKind::Const { .. })
529-
{
530-
tcx.type_of(param.def_id)
531-
.no_bound_vars()
532-
.expect("const parameter types cannot be generic")
533-
} else {
534-
// FIXME(associated_const_equality): add a useful error message here.
535-
tcx.ty_error_with_message(
536-
DUMMY_SP,
537-
"Could not find const param on associated item",
538-
)
539-
}
540-
}
541-
542-
Node::GenericParam(&GenericParam {
543-
def_id: param_def_id,
544-
kind: GenericParamKind::Const { default: Some(ct), .. },
545-
..
546-
}) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(),
547-
548-
x => tcx.ty_error_with_message(
549-
DUMMY_SP,
550-
&format!("unexpected const parent in type_of(): {x:?}"),
551-
),
552-
}
553-
}
489+
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
554490

555491
Node::GenericParam(param) => match &param.kind {
556492
GenericParamKind::Type { default: Some(ty), .. }

compiler/rustc_middle/src/query/mod.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -127,29 +127,6 @@ rustc_queries! {
127127
desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
128128
}
129129

130-
/// Computes the `DefId` of the corresponding const parameter in case the `key` is a
131-
/// const argument and returns `None` otherwise.
132-
///
133-
/// ```ignore (incomplete)
134-
/// let a = foo::<7>();
135-
/// // ^ Calling `opt_const_param_of` for this argument,
136-
///
137-
/// fn foo<const N: usize>()
138-
/// // ^ returns this `DefId`.
139-
///
140-
/// fn bar() {
141-
/// // ^ While calling `opt_const_param_of` for other bodies returns `None`.
142-
/// }
143-
/// ```
144-
// It looks like caching this query on disk actually slightly
145-
// worsened performance in #74376.
146-
//
147-
// Once const generics are more prevalently used, we might want to
148-
// consider only caching calls returning `Some`.
149-
query opt_const_param_of(key: LocalDefId) -> Option<DefId> {
150-
desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
151-
}
152-
153130
/// Given the def_id of a const-generic parameter, computes the associated default const
154131
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
155132
query const_param_default(param: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {

0 commit comments

Comments
 (0)