diff options
| author | bors <bors@rust-lang.org> | 2024-07-19 08:44:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-19 08:44:51 +0000 |
| commit | 8c3a94a1c79c67924558a4adf7fb6d98f5f0f741 (patch) | |
| tree | 38c82dbbb0ab3f8513f0965761bb13006c8f433e /compiler/rustc_hir/src/intravisit.rs | |
| parent | 3d68afc9e821b00d59058abc9bda670b07639955 (diff) | |
| parent | c8457e60e8a1bbade7f8aa34d3646c392a4237b6 (diff) | |
| download | rust-8c3a94a1c79c67924558a4adf7fb6d98f5f0f741.tar.gz rust-8c3a94a1c79c67924558a4adf7fb6d98f5f0f741.zip | |
Auto merge of #125915 - camelid:const-arg-refactor, r=BoxyUwU
Represent type-level consts with new-and-improved `hir::ConstArg` ### Summary This is a step toward `min_generic_const_exprs`. We now represent all const generic arguments using an enum that differentiates between const *paths* (temporarily just bare const params) and arbitrary anon consts that may perform computations. This will enable us to cleanly implement the `min_generic_const_args` plan of allowing the use of generics in paths used as const args, while disallowing their use in arbitrary anon consts. Here is a summary of the salient aspects of this change: - Add `current_def_id_parent` to `LoweringContext` This is needed to track anon const parents properly once we implement `ConstArgKind::Path` (which requires moving anon const def-creation outside of `DefCollector`). - Create `hir::ConstArgKind` enum with `Path` and `Anon` variants. Use it in the existing `hir::ConstArg` struct, replacing the previous `hir::AnonConst` field. - Use `ConstArg` for all instances of const args. Specifically, use it instead of `AnonConst` for assoc item constraints, array lengths, and const param defaults. - Some `ast::AnonConst`s now have their `DefId`s created in rustc_ast_lowering rather than `DefCollector`. This is because in some cases they will end up becoming a `ConstArgKind::Path` instead, which has no `DefId`. We have to solve this in a hacky way where we guess whether the `AnonConst` could end up as a path const since we can't know for sure until after name resolution (`N` could refer to a free const or a nullary struct). If it has no chance as being a const param, then we create a `DefId` in `DefCollector` -- otherwise we decide during ast_lowering. This will have to be updated once all path consts use `ConstArgKind::Path`. - We explicitly use `ConstArgHasType` for array lengths, rather than implicitly relying on anon const type feeding -- this is due to the addition of `ConstArgKind::Path`. - Some tests have their outputs changed, but the changes are for the most part minor (including removing duplicate or almost-duplicate errors). One test now ICEs, but it is for an incomplete, unstable feature and is now tracked at https://github.com/rust-lang/rust/issues/127009. ### Followup items post-merge - Use `ConstArgKind::Path` for all const paths, not just const params. - Fix (no github dont close this issue) #127009 - If a path in generic args doesn't resolve as a type, try to resolve as a const instead (do this in rustc_resolve). Then remove the special-casing from `rustc_ast_lowering`, so that all params will automatically be lowered as `ConstArgKind::Path`. - (?) Consider making `const_evaluatable_unchecked` a hard error, or at least trying it in crater r? `@BoxyUwU`
Diffstat (limited to 'compiler/rustc_hir/src/intravisit.rs')
| -rw-r--r-- | compiler/rustc_hir/src/intravisit.rs | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9bb3245ae05..c202ee41e31 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -347,6 +347,9 @@ pub trait Visitor<'v>: Sized { fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result { walk_inline_const(self, c) } + fn visit_const_arg(&mut self, c: &'v ConstArg<'v>) -> Self::Result { + walk_const_arg(self, c) + } fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result { walk_expr(self, ex) } @@ -364,7 +367,7 @@ pub trait Visitor<'v>: Sized { fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result { walk_generic_param(self, p) } - fn visit_const_param_default(&mut self, _param: HirId, ct: &'v AnonConst) -> Self::Result { + fn visit_const_param_default(&mut self, _param: HirId, ct: &'v ConstArg<'v>) -> Self::Result { walk_const_param_default(self, ct) } fn visit_generics(&mut self, g: &'v Generics<'v>) -> Self::Result { @@ -708,7 +711,7 @@ pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen<'v> match len { // FIXME: Use `visit_infer` here. ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id), - ArrayLen::Body(c) => visitor.visit_anon_const(c), + ArrayLen::Body(c) => visitor.visit_const_arg(c), } } @@ -725,6 +728,17 @@ pub fn walk_inline_const<'v, V: Visitor<'v>>( visitor.visit_nested_body(constant.body) } +pub fn walk_const_arg<'v, V: Visitor<'v>>( + visitor: &mut V, + const_arg: &'v ConstArg<'v>, +) -> V::Result { + try_visit!(visitor.visit_id(const_arg.hir_id)); + match &const_arg.kind { + ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, const_arg.hir_id, qpath.span()), + ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), + } +} + pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result { try_visit!(visitor.visit_id(expression.hir_id)); match expression.kind { @@ -928,9 +942,9 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>( pub fn walk_const_param_default<'v, V: Visitor<'v>>( visitor: &mut V, - ct: &'v AnonConst, + ct: &'v ConstArg<'v>, ) -> V::Result { - visitor.visit_anon_const(ct) + visitor.visit_const_arg(ct) } pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) -> V::Result { @@ -1216,7 +1230,7 @@ pub fn walk_generic_arg<'v, V: Visitor<'v>>( match generic_arg { GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt), GenericArg::Type(ty) => visitor.visit_ty(ty), - GenericArg::Const(ct) => visitor.visit_anon_const(&ct.value), + GenericArg::Const(ct) => visitor.visit_const_arg(ct), GenericArg::Infer(inf) => visitor.visit_infer(inf), } } @@ -1278,7 +1292,7 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>( match constraint.kind { AssocItemConstraintKind::Equality { ref term } => match term { Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)), - Term::Const(ref c) => try_visit!(visitor.visit_anon_const(c)), + Term::Const(ref c) => try_visit!(visitor.visit_const_arg(c)), }, AssocItemConstraintKind::Bound { bounds } => { walk_list!(visitor, visit_param_bound, bounds) |
