1
Fork 0

Rollup merge of #129246 - BoxyUwU:feature_gate_const_arg_path, r=cjgillot

Retroactively feature gate `ConstArgKind::Path`

This puts the lowering introduced by #125915 under a feature gate until we fix the regressions introduced by it. Alternative to whole sale reverting the PR since it didn't seem like a very clean revert and I think this is generally a step in the right direction and don't want to get stuck landing and reverting the PR over and over :)

cc #129137 ``@camelid,`` tests taken from there. beta is branching soon so I think it makes sense to not try and rush that fix through since it wont have much time to bake and if it has issues we can't simply revert it on beta.

Fixes #128016
This commit is contained in:
Matthias Krüger 2024-08-24 22:14:12 +02:00 committed by GitHub
commit c0bedb9e5e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 425 additions and 206 deletions

View file

@ -220,7 +220,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let parent_def_id = self.current_def_id_parent;
let node_id = self.next_node_id();
// HACK(min_generic_const_args): see lower_anon_const
if !expr.is_potential_trivial_const_arg() {
if !self.tcx.features().const_arg_path
|| !expr.is_potential_trivial_const_arg()
{
self.create_def(
parent_def_id,
node_id,

View file

@ -387,7 +387,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let node_id = self.next_node_id();
// HACK(min_generic_const_args): see lower_anon_const
if !arg.is_potential_trivial_const_arg() {
if !self.tcx.features().const_arg_path || !arg.is_potential_trivial_const_arg() {
// Add a definition for the in-band const def.
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
}

View file

@ -2358,7 +2358,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: Span,
) -> &'hir hir::ConstArg<'hir> {
let ct_kind = match res {
Res::Def(DefKind::ConstParam, _) => {
Res::Def(DefKind::ConstParam, _) if self.tcx.features().const_arg_path => {
let qpath = self.lower_qpath(
ty_id,
&None,
@ -2433,7 +2433,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
debug!("res={:?}", maybe_res);
// FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
if let Some(res) = maybe_res
if self.tcx.features().const_arg_path
&& let Some(res) = maybe_res
&& let Res::Def(DefKind::ConstParam, _) = res
&& let ExprKind::Path(qself, path) = &expr.kind
{
@ -2464,7 +2465,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// See [`hir::ConstArg`] for when to use this function vs
/// [`Self::lower_anon_const_to_const_arg`].
fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
if c.value.is_potential_trivial_const_arg() {
if self.tcx.features().const_arg_path && c.value.is_potential_trivial_const_arg() {
// HACK(min_generic_const_args): see DefCollector::visit_anon_const
// Over there, we guess if this is a bare param and only create a def if
// we think it's not. However we may can guess wrong (see there for example)

View file

@ -193,6 +193,8 @@ declare_features! (
(unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
/// Allows identifying the `compiler_builtins` crate.
(internal, compiler_builtins, "1.13.0", None),
/// Gating for a new desugaring of const arguments of usages of const parameters
(internal, const_arg_path, "1.81.0", None),
/// Allows writing custom MIR
(internal, custom_mir, "1.65.0", None),
/// Outputs useful `assert!` messages

View file

@ -240,7 +240,7 @@ impl<'tcx> Const<'tcx> {
let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic");
match Self::try_from_lit(tcx, ty, expr) {
match Self::try_from_lit_or_param(tcx, ty, expr) {
Some(v) => v,
None => ty::Const::new_unevaluated(
tcx,
@ -281,7 +281,11 @@ impl<'tcx> Const<'tcx> {
}
#[instrument(skip(tcx), level = "debug")]
fn try_from_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option<Self> {
fn try_from_lit_or_param(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
) -> Option<Self> {
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
let expr = match &expr.kind {
@ -291,6 +295,22 @@ impl<'tcx> Const<'tcx> {
_ => expr,
};
if let hir::ExprKind::Path(
qpath @ hir::QPath::Resolved(
_,
&hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
),
) = expr.kind
{
if tcx.features().const_arg_path {
span_bug!(
expr.span,
"try_from_lit: received const param which shouldn't be possible"
);
}
return Some(Const::from_param(tcx, qpath, expr.hir_id));
};
let lit_input = match expr.kind {
hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
@ -318,14 +338,6 @@ impl<'tcx> Const<'tcx> {
}
}
if let hir::ExprKind::Path(hir::QPath::Resolved(
_,
&hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
)) = expr.kind
{
span_bug!(expr.span, "try_from_lit: received const param which shouldn't be possible")
}
None
}

View file

@ -314,13 +314,15 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
}
fn visit_anon_const(&mut self, constant: &'a AnonConst) {
// HACK(min_generic_const_args): don't create defs for anon consts if we think they will
// later be turned into ConstArgKind::Path's. because this is before resolve is done, we
// may accidentally identify a construction of a unit struct as a param and not create a
// def. we'll then create a def later in ast lowering in this case. the parent of nested
// items will be messed up, but that's ok because there can't be any if we're just looking
// for bare idents.
if constant.value.is_potential_trivial_const_arg() {
if self.resolver.tcx.features().const_arg_path
&& constant.value.is_potential_trivial_const_arg()
{
// HACK(min_generic_const_args): don't create defs for anon consts if we think they will
// later be turned into ConstArgKind::Path's. because this is before resolve is done, we
// may accidentally identify a construction of a unit struct as a param and not create a
// def. we'll then create a def later in ast lowering in this case. the parent of nested
// items will be messed up, but that's ok because there can't be any if we're just looking
// for bare idents.
visit::walk_anon_const(self, constant)
} else {
let def =

View file

@ -595,6 +595,7 @@ symbols! {
conservative_impl_trait,
console,
const_allocate,
const_arg_path,
const_async_blocks,
const_closures,
const_compare_raw_pointers,