Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 36 additions & 12 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2815,6 +2815,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> hir::ConstArg<'hir> {
let tcx = self.tcx;

// 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 = if let ExprKind::Block(block, _) = &anon.value.kind
&& let [stmt] = block.stmts.as_slice()
&& let StmtKind::Expr(expr) = &stmt.kind
&& let ExprKind::Path(..) = &expr.kind
{
expr
} else {
&anon.value
};

// We cannot change parsing depending on feature gates available,
// we can only require feature gates to be active as a delayed check.
// Thus we just parse anon consts generally and make the real decision
Expand All @@ -2830,22 +2842,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: lowered_anon.span,
}
}
MgcaDisambiguation::Direct
if self.direct_const_arg_has_primitive_fallback_path(&expr) =>
{
// Primitive associated constants rely on expression fallback
self.create_def(anon.id, None, DefKind::AnonConst, span);
let lowered_anon = self.lower_anon_const_to_anon_const(anon, span);
ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Anon(lowered_anon),
span: lowered_anon.span,
}
}
MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value),
};
}

// 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 = if let ExprKind::Block(block, _) = &anon.value.kind
&& let [stmt] = block.stmts.as_slice()
&& let StmtKind::Expr(expr) = &stmt.kind
&& let ExprKind::Path(..) = &expr.kind
{
expr
} else {
&anon.value
};

let maybe_res =
self.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
if let ExprKind::Path(qself, path) = &expr.kind
Expand Down Expand Up @@ -2877,6 +2889,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn direct_const_arg_has_primitive_fallback_path(&self, expr: &Expr) -> bool {
let ExprKind::Path(None, path) = &expr.kind else {
return false;
};

self.get_partial_res(expr.id).is_some_and(|partial_res| {
matches!(partial_res.base_res(), Res::PrimTy(_))
&& partial_res.unresolved_segments() > 0
&& partial_res.unresolved_segments() == path.segments.len() - 1
})
}

/// See [`hir::ConstArg`] for when to use this function vs
/// [`Self::lower_anon_const_to_const_arg`].
fn lower_anon_const_to_anon_const(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ check-pass

#![feature(min_generic_const_args)]
#![allow(incomplete_features)]

struct TakesU8<const N: u8>;
struct TakesI8<const N: i8>;

type _U8Max = TakesU8<{ u8::MAX }>;
type _U8Min = TakesU8<{ u8::MIN }>;
type _I8Max = TakesI8<{ i8::MAX }>;
type _I8Min = TakesI8<{ i8::MIN }>;

fn main() {}
Loading