Skip to content

Commit 4c48ba1

Browse files
Rollup merge of rust-lang#150962 - rm/feed_const_ty, r=BoxyUwU
Remove `FeedConstTy` and provide ty when lowering const arg r? @BoxyUwU edit: BoxyUwU `FeedConstTy` currently only provides the expected type of a const argument *sometimes* (e.g. previously array lengths did not do this). This causes problems with mGCA's directly represented const arguments which always need to know their expected type.
2 parents c8ed8ec + d1c2e5c commit 4c48ba1

File tree

11 files changed

+161
-118
lines changed

11 files changed

+161
-118
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ use rustc_trait_selection::traits::{
4747
use tracing::{debug, instrument};
4848

4949
use crate::errors;
50-
use crate::hir_ty_lowering::{
51-
FeedConstTy, HirTyLowerer, InherentAssocCandidate, RegionInferReason,
52-
};
50+
use crate::hir_ty_lowering::{HirTyLowerer, InherentAssocCandidate, RegionInferReason};
5351

5452
pub(crate) mod dump;
5553
mod generics_of;
@@ -1499,7 +1497,7 @@ fn const_param_default<'tcx>(
14991497

15001498
let ct = icx
15011499
.lowerer()
1502-
.lower_const_arg(default_ct, FeedConstTy::with_type_of(tcx, def_id, identity_args));
1500+
.lower_const_arg(default_ct, tcx.type_of(def_id).instantiate(tcx, identity_args));
15031501
ty::EarlyBinder::bind(ct)
15041502
}
15051503

@@ -1557,7 +1555,7 @@ fn const_of_item<'tcx>(
15571555
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
15581556
let ct = icx
15591557
.lowerer()
1560-
.lower_const_arg(ct_arg, FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args));
1558+
.lower_const_arg(ct_arg, tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args));
15611559
if let Err(e) = icx.check_tainted_by_errors()
15621560
&& !ct.references_error()
15631561
{

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use tracing::{debug, instrument};
2020

2121
use crate::errors;
2222
use crate::hir_ty_lowering::{
23-
AssocItemQSelf, FeedConstTy, GenericsArgsErrExtend, HirTyLowerer, ImpliedBoundsContext,
23+
AssocItemQSelf, GenericsArgsErrExtend, HirTyLowerer, ImpliedBoundsContext,
2424
OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
2525
};
2626

@@ -510,7 +510,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
510510
// Create the generic arguments for the associated type or constant by joining the
511511
// parent arguments (the arguments of the trait) and the own arguments (the ones of
512512
// the associated item itself) and construct an alias type using them.
513-
let alias_term = candidate.map_bound(|trait_ref| {
513+
candidate.map_bound(|trait_ref| {
514514
let item_segment = hir::PathSegment {
515515
ident: constraint.ident,
516516
hir_id: constraint.hir_id,
@@ -528,20 +528,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
528528
debug!(?alias_args);
529529

530530
ty::AliasTerm::new_from_args(tcx, assoc_item.def_id, alias_args)
531-
});
532-
533-
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
534-
if let Some(const_arg) = constraint.ct()
535-
&& let hir::ConstArgKind::Anon(anon_const) = const_arg.kind
536-
{
537-
let ty = alias_term
538-
.map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args));
539-
let ty =
540-
check_assoc_const_binding_type(self, constraint.ident, ty, constraint.hir_id);
541-
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
542-
}
543-
544-
alias_term
531+
})
545532
};
546533

547534
match constraint.kind {
@@ -555,7 +542,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
555542
hir::AssocItemConstraintKind::Equality { term } => {
556543
let term = match term {
557544
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
558-
hir::Term::Const(ct) => self.lower_const_arg(ct, FeedConstTy::No).into(),
545+
hir::Term::Const(ct) => {
546+
let ty = projection_term.map_bound(|alias| {
547+
tcx.type_of(alias.def_id).instantiate(tcx, alias.args)
548+
});
549+
let ty = check_assoc_const_binding_type(
550+
self,
551+
constraint.ident,
552+
ty,
553+
constraint.hir_id,
554+
);
555+
556+
self.lower_const_arg(ct, ty).into()
557+
}
559558
};
560559

561560
// Find any late-bound regions declared in `ty` that are not
@@ -871,7 +870,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
871870
/// probably gate this behind another feature flag.
872871
///
873872
/// [^1]: <https://github.com/rust-lang/project-const-generics/issues/28>.
874-
fn check_assoc_const_binding_type<'tcx>(
873+
pub(crate) fn check_assoc_const_binding_type<'tcx>(
875874
cx: &dyn HirTyLowerer<'tcx>,
876875
assoc_const: Ident,
877876
ty: ty::Binder<'tcx, Ty<'tcx>>,

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 64 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -253,35 +253,6 @@ impl AssocItemQSelf {
253253
}
254254
}
255255

256-
/// In some cases, [`hir::ConstArg`]s that are being used in the type system
257-
/// through const generics need to have their type "fed" to them
258-
/// using the query system.
259-
///
260-
/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
261-
/// desired behavior.
262-
#[derive(Debug, Clone, Copy)]
263-
pub enum FeedConstTy<'tcx> {
264-
/// Feed the type to the (anno) const arg.
265-
WithTy(Ty<'tcx>),
266-
/// Don't feed the type.
267-
No,
268-
}
269-
270-
impl<'tcx> FeedConstTy<'tcx> {
271-
/// The `DefId` belongs to the const param that we are supplying
272-
/// this (anon) const arg to.
273-
///
274-
/// The list of generic args is used to instantiate the parameters
275-
/// used by the type of the const param specified by `DefId`.
276-
pub fn with_type_of(
277-
tcx: TyCtxt<'tcx>,
278-
def_id: DefId,
279-
generic_args: &[ty::GenericArg<'tcx>],
280-
) -> Self {
281-
Self::WithTy(tcx.type_of(def_id).instantiate(tcx, generic_args))
282-
}
283-
}
284-
285256
#[derive(Debug, Clone, Copy)]
286257
enum LowerTypeRelativePathMode {
287258
Type(PermitVariants),
@@ -733,7 +704,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
733704
// Ambig portions of `ConstArg` are handled in the match arm below
734705
.lower_const_arg(
735706
ct.as_unambig_ct(),
736-
FeedConstTy::with_type_of(tcx, param.def_id, preceding_args),
707+
tcx.type_of(param.def_id).instantiate(tcx, preceding_args),
737708
)
738709
.into(),
739710
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
@@ -1269,10 +1240,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12691240
let mut where_bounds = vec![];
12701241
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
12711242
let bound_id = bound.def_id();
1272-
let bound_span = tcx
1273-
.associated_items(bound_id)
1274-
.find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
1275-
.and_then(|item| tcx.hir_span_if_local(item.def_id));
1243+
let assoc_item = tcx.associated_items(bound_id).find_by_ident_and_kind(
1244+
tcx,
1245+
assoc_ident,
1246+
assoc_tag,
1247+
bound_id,
1248+
);
1249+
let bound_span = assoc_item.and_then(|item| tcx.hir_span_if_local(item.def_id));
12761250

12771251
if let Some(bound_span) = bound_span {
12781252
err.span_label(
@@ -1285,7 +1259,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12851259
let term: ty::Term<'_> = match term {
12861260
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
12871261
hir::Term::Const(ct) => {
1288-
self.lower_const_arg(ct, FeedConstTy::No).into()
1262+
let assoc_item =
1263+
assoc_item.expect("assoc_item should be present");
1264+
let projection_term = bound.map_bound(|trait_ref| {
1265+
let item_segment = hir::PathSegment {
1266+
ident: constraint.ident,
1267+
hir_id: constraint.hir_id,
1268+
res: Res::Err,
1269+
args: Some(constraint.gen_args),
1270+
infer_args: false,
1271+
};
1272+
1273+
let alias_args = self.lower_generic_args_of_assoc_item(
1274+
constraint.ident.span,
1275+
assoc_item.def_id,
1276+
&item_segment,
1277+
trait_ref.args,
1278+
);
1279+
ty::AliasTerm::new_from_args(
1280+
tcx,
1281+
assoc_item.def_id,
1282+
alias_args,
1283+
)
1284+
});
1285+
1286+
// FIXME(mgca): code duplication with other places we lower
1287+
// the rhs' of associated const bindings
1288+
let ty = projection_term.map_bound(|alias| {
1289+
tcx.type_of(alias.def_id).instantiate(tcx, alias.args)
1290+
});
1291+
let ty = bounds::check_assoc_const_binding_type(
1292+
self,
1293+
constraint.ident,
1294+
ty,
1295+
constraint.hir_id,
1296+
);
1297+
1298+
self.lower_const_arg(ct, ty).into()
12891299
}
12901300
};
12911301
if term.references_error() {
@@ -2310,16 +2320,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23102320

23112321
/// Lower a [`hir::ConstArg`] to a (type-level) [`ty::Const`](Const).
23122322
#[instrument(skip(self), level = "debug")]
2313-
pub fn lower_const_arg(
2314-
&self,
2315-
const_arg: &hir::ConstArg<'tcx>,
2316-
feed: FeedConstTy<'tcx>,
2317-
) -> Const<'tcx> {
2323+
pub fn lower_const_arg(&self, const_arg: &hir::ConstArg<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
23182324
let tcx = self.tcx();
23192325

2320-
if let FeedConstTy::WithTy(anon_const_type) = feed
2321-
&& let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2322-
{
2326+
if let hir::ConstArgKind::Anon(anon) = &const_arg.kind {
23232327
// FIXME(generic_const_parameter_types): Ideally we remove these errors below when
23242328
// we have the ability to intermix typeck of anon const const args with the parent
23252329
// bodies typeck.
@@ -2329,7 +2333,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23292333
// hir typeck was using equality but mir borrowck wound up using subtyping as that could
23302334
// result in a non-infer in hir typeck but a region variable in borrowck.
23312335
if tcx.features().generic_const_parameter_types()
2332-
&& (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
2336+
&& (ty.has_free_regions() || ty.has_erased_regions())
23332337
{
23342338
let e = self.dcx().span_err(
23352339
const_arg.span,
@@ -2341,7 +2345,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23412345
// We must error if the instantiated type has any inference variables as we will
23422346
// use this type to feed the `type_of` and query results must not contain inference
23432347
// variables otherwise we will ICE.
2344-
if anon_const_type.has_non_region_infer() {
2348+
if ty.has_non_region_infer() {
23452349
let e = self.dcx().span_err(
23462350
const_arg.span,
23472351
"anonymous constants with inferred types are not yet supported",
@@ -2351,7 +2355,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23512355
}
23522356
// We error when the type contains unsubstituted generics since we do not currently
23532357
// give the anon const any of the generics from the parent.
2354-
if anon_const_type.has_non_region_param() {
2358+
if ty.has_non_region_param() {
23552359
let e = self.dcx().span_err(
23562360
const_arg.span,
23572361
"anonymous constants referencing generics are not yet supported",
@@ -2360,12 +2364,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23602364
return ty::Const::new_error(tcx, e);
23612365
}
23622366

2363-
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(anon_const_type));
2367+
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(ty));
23642368
}
23652369

23662370
let hir_id = const_arg.hir_id;
23672371
match const_arg.kind {
2368-
hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, feed, const_arg.span),
2372+
hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, ty, const_arg.span),
23692373
hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
23702374
debug!(?maybe_qself, ?path);
23712375
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
@@ -2389,31 +2393,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23892393
hir::ConstArgKind::TupleCall(qpath, args) => {
23902394
self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span)
23912395
}
2392-
hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, feed),
2396+
hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, ty),
23932397
hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon),
23942398
hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span),
23952399
hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e),
2396-
hir::ConstArgKind::Literal(kind) if let FeedConstTy::WithTy(anon_const_type) = feed => {
2397-
self.lower_const_arg_literal(&kind, anon_const_type, const_arg.span)
2398-
}
2399-
hir::ConstArgKind::Literal(..) => {
2400-
let e = self.dcx().span_err(const_arg.span, "literal of unknown type");
2401-
ty::Const::new_error(tcx, e)
2400+
hir::ConstArgKind::Literal(kind) => {
2401+
self.lower_const_arg_literal(&kind, ty, const_arg.span)
24022402
}
24032403
}
24042404
}
24052405

24062406
fn lower_const_arg_array(
24072407
&self,
24082408
array_expr: &'tcx hir::ConstArgArrayExpr<'tcx>,
2409-
feed: FeedConstTy<'tcx>,
2409+
ty: Ty<'tcx>,
24102410
) -> Const<'tcx> {
24112411
let tcx = self.tcx();
24122412

2413-
let FeedConstTy::WithTy(ty) = feed else {
2414-
return Const::new_error_with_message(tcx, array_expr.span, "unsupported const array");
2415-
};
2416-
24172413
let ty::Array(elem_ty, _) = ty.kind() else {
24182414
return Const::new_error_with_message(
24192415
tcx,
@@ -2425,7 +2421,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24252421
let elems = array_expr
24262422
.elems
24272423
.iter()
2428-
.map(|elem| self.lower_const_arg(elem, FeedConstTy::WithTy(*elem_ty)))
2424+
.map(|elem| self.lower_const_arg(elem, *elem_ty))
24292425
.collect::<Vec<_>>();
24302426

24312427
let valtree = ty::ValTree::from_branches(tcx, elems);
@@ -2508,7 +2504,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25082504
.iter()
25092505
.zip(args)
25102506
.map(|(field_def, arg)| {
2511-
self.lower_const_arg(arg, FeedConstTy::with_type_of(tcx, field_def.did, adt_args))
2507+
self.lower_const_arg(arg, tcx.type_of(field_def.did).instantiate(tcx, adt_args))
25122508
})
25132509
.collect::<Vec<_>>();
25142510

@@ -2527,15 +2523,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25272523
fn lower_const_arg_tup(
25282524
&self,
25292525
exprs: &'tcx [&'tcx hir::ConstArg<'tcx>],
2530-
feed: FeedConstTy<'tcx>,
2526+
ty: Ty<'tcx>,
25312527
span: Span,
25322528
) -> Const<'tcx> {
25332529
let tcx = self.tcx();
25342530

2535-
let FeedConstTy::WithTy(ty) = feed else {
2536-
return Const::new_error_with_message(tcx, span, "const tuple lack type information");
2537-
};
2538-
25392531
let ty::Tuple(tys) = ty.kind() else {
25402532
let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty));
25412533
return Const::new_error(tcx, e);
@@ -2544,7 +2536,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25442536
let exprs = exprs
25452537
.iter()
25462538
.zip(tys.iter())
2547-
.map(|(expr, ty)| self.lower_const_arg(expr, FeedConstTy::WithTy(ty)))
2539+
.map(|(expr, ty)| self.lower_const_arg(expr, ty))
25482540
.collect::<Vec<_>>();
25492541

25502542
let valtree = ty::ValTree::from_branches(tcx, exprs);
@@ -2631,7 +2623,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
26312623

26322624
self.lower_const_arg(
26332625
expr.expr,
2634-
FeedConstTy::with_type_of(tcx, field_def.did, adt_args),
2626+
tcx.type_of(field_def.did).instantiate(tcx, adt_args),
26352627
)
26362628
}
26372629
None => {
@@ -2993,7 +2985,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
29932985
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
29942986
}
29952987
hir::TyKind::Array(ty, length) => {
2996-
let length = self.lower_const_arg(length, FeedConstTy::No);
2988+
let length = self.lower_const_arg(length, tcx.types.usize);
29972989
Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
29982990
}
29992991
hir::TyKind::Infer(()) => {
@@ -3033,8 +3025,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
30333025
// Keep this list of types in sync with the list of types that
30343026
// the `RangePattern` trait is implemented for.
30353027
ty::Int(_) | ty::Uint(_) | ty::Char => {
3036-
let start = self.lower_const_arg(start, FeedConstTy::No);
3037-
let end = self.lower_const_arg(end, FeedConstTy::No);
3028+
let start = self.lower_const_arg(start, ty);
3029+
let end = self.lower_const_arg(end, ty);
30383030
Ok(ty::PatternKind::Range { start, end })
30393031
}
30403032
_ => Err(self

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ use rustc_span::{ErrorGuaranteed, Span};
101101
use rustc_trait_selection::traits;
102102

103103
pub use crate::collect::suggest_impl_trait;
104-
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
104+
use crate::hir_ty_lowering::HirTyLowerer;
105105

106106
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
107107

@@ -301,8 +301,8 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
301301
pub fn lower_const_arg_for_rustdoc<'tcx>(
302302
tcx: TyCtxt<'tcx>,
303303
hir_ct: &hir::ConstArg<'tcx>,
304-
feed: FeedConstTy<'tcx>,
304+
ty: Ty<'tcx>,
305305
) -> Const<'tcx> {
306306
let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
307-
collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)
307+
collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, ty)
308308
}

0 commit comments

Comments
 (0)