Skip to content

Commit 8ffa35c

Browse files
committed
Allow const paths with generics/qself under mgca
1 parent a296ff8 commit 8ffa35c

File tree

4 files changed

+65
-28
lines changed

4 files changed

+65
-28
lines changed

compiler/rustc_ast/src/ast.rs

-26
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,6 @@ impl Path {
122122
pub fn is_global(&self) -> bool {
123123
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
124124
}
125-
126-
/// Does this path have no arguments, and if allow_multi_segment is false, is it a single segment?
127-
pub fn is_potential_trivial_const_arg(&self, allow_multi_segment: bool) -> bool {
128-
(allow_multi_segment || self.segments.len() == 1)
129-
&& self.segments.iter().all(|seg| seg.args.is_none())
130-
}
131125
}
132126

133127
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
@@ -1175,26 +1169,6 @@ pub struct Expr {
11751169
}
11761170

11771171
impl Expr {
1178-
// FIXME: update docs
1179-
/// Could this expr be either `N`, or `{ N }`, where `N` is a const parameter.
1180-
///
1181-
/// If this is not the case, name resolution does not resolve `N` when using
1182-
/// `min_const_generics` as more complex expressions are not supported.
1183-
///
1184-
/// Does not ensure that the path resolves to a const param, the caller should check this.
1185-
/// This also does not consider macros, so it's only correct after macro-expansion.
1186-
pub fn is_potential_trivial_const_arg(&self, allow_multi_segment: bool) -> bool {
1187-
let this = self.maybe_unwrap_block();
1188-
1189-
if let ExprKind::Path(None, path) = &this.kind
1190-
&& path.is_potential_trivial_const_arg(allow_multi_segment)
1191-
{
1192-
true
1193-
} else {
1194-
false
1195-
}
1196-
}
1197-
11981172
/// Returns an expression with (when possible) *one* outter brace removed
11991173
pub fn maybe_unwrap_block(&self) -> &Expr {
12001174
if let ExprKind::Block(block, None) = &self.kind

compiler/rustc_ast/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub mod util {
2626
pub mod case;
2727
pub mod classify;
2828
pub mod comments;
29+
mod const_args;
2930
pub mod literal;
3031
pub mod parser;
3132
pub mod unicode;
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use std::ops::ControlFlow;
2+
3+
use crate::visit::{Visitor, walk_anon_const};
4+
use crate::{DUMMY_NODE_ID, Expr, ExprKind, Path};
5+
6+
impl Expr {
7+
// FIXME: update docs
8+
/// Could this expr be either `N`, or `{ N }`, where `N` is a const parameter.
9+
///
10+
/// If this is not the case, name resolution does not resolve `N` when using
11+
/// `min_const_generics` as more complex expressions are not supported.
12+
///
13+
/// Does not ensure that the path resolves to a const param, the caller should check this.
14+
/// This also does not consider macros, so it's only correct after macro-expansion.
15+
pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
16+
let this = self.maybe_unwrap_block();
17+
if allow_mgca_arg {
18+
MGCATrivialConstArgVisitor::new().visit_expr(this).is_continue()
19+
} else {
20+
if let ExprKind::Path(None, path) = &this.kind
21+
&& path.is_potential_trivial_const_arg(allow_mgca_arg)
22+
{
23+
true
24+
} else {
25+
false
26+
}
27+
}
28+
}
29+
}
30+
31+
impl Path {
32+
// FIXME: add docs
33+
#[tracing::instrument(level = "debug", ret)]
34+
pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
35+
if allow_mgca_arg {
36+
MGCATrivialConstArgVisitor::new().visit_path(self, DUMMY_NODE_ID).is_continue()
37+
} else {
38+
self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
39+
}
40+
}
41+
}
42+
43+
pub(crate) struct MGCATrivialConstArgVisitor {}
44+
45+
impl MGCATrivialConstArgVisitor {
46+
pub(crate) fn new() -> Self {
47+
Self {}
48+
}
49+
}
50+
51+
impl<'ast> Visitor<'ast> for MGCATrivialConstArgVisitor {
52+
type Result = ControlFlow<()>;
53+
54+
fn visit_anon_const(&mut self, c: &'ast crate::AnonConst) -> Self::Result {
55+
let expr = c.value.maybe_unwrap_block();
56+
match &expr.kind {
57+
ExprKind::Path(_, _) => {}
58+
_ => return ControlFlow::Break(()),
59+
}
60+
walk_anon_const(self, c)
61+
}
62+
}

tests/ui/const-generics/mgca/assoc-const.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
#![feature(min_generic_const_args)]
44
#![allow(incomplete_features)]
55

6-
pub trait Tr {
6+
pub trait Tr<X> {
77
#[type_const]
88
const SIZE: usize;
99
}
1010

11-
fn mk_array<T: Tr>(_x: T) -> [(); T::SIZE] {
11+
fn mk_array<T: Tr<bool>>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {
1212
[(); T::SIZE]
1313
}
1414

0 commit comments

Comments
 (0)