Skip to content

Commit

Permalink
Allow qualified path on struct construction expr and pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jan 16, 2023
1 parent 9965b86 commit ba69d2f
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 40 deletions.
41 changes: 23 additions & 18 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,7 @@ ast_struct! {
#[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
pub struct ExprStruct #full {
pub attrs: Vec<Attribute>,
pub qself: Option<QSelf>,
pub path: Path,
pub brace_token: token::Brace,
pub fields: Punctuated<FieldValue, Token![,]>,
Expand Down Expand Up @@ -1737,12 +1738,11 @@ pub(crate) mod parsing {

#[cfg(feature = "full")]
fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
let begin = input.fork();
let expr: ExprPath = input.parse()?;
let (qself, path) = path::parsing::qpath(input, true)?;

if expr.qself.is_none() && input.peek(Token![!]) && !input.peek(Token![!=]) {
if qself.is_none() && input.peek(Token![!]) && !input.peek(Token![!=]) {
let mut contains_arguments = false;
for segment in &expr.path.segments {
for segment in &path.segments {
match segment.arguments {
PathArguments::None => {}
PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
Expand All @@ -1757,7 +1757,7 @@ pub(crate) mod parsing {
return Ok(Expr::Macro(ExprMacro {
attrs: Vec::new(),
mac: Macro {
path: expr.path,
path,
bang_token,
delimiter,
tokens,
Expand All @@ -1767,14 +1767,13 @@ pub(crate) mod parsing {
}

if allow_struct.0 && input.peek(token::Brace) {
let expr_struct = expr_struct_helper(input, expr.path)?;
if expr.qself.is_some() {
Ok(Expr::Verbatim(verbatim::between(begin, input)))
} else {
Ok(Expr::Struct(expr_struct))
}
expr_struct_helper(input, qself, path).map(Expr::Struct)
} else {
Ok(Expr::Path(expr))
Ok(Expr::Path(ExprPath {
attrs: Vec::new(),
qself,
path,
}))
}
}

Expand Down Expand Up @@ -2602,13 +2601,17 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprStruct {
fn parse(input: ParseStream) -> Result<Self> {
let path: Path = input.parse()?;
expr_struct_helper(input, path)
let (qself, path) = path::parsing::qpath(input, true)?;
expr_struct_helper(input, qself, path)
}
}

#[cfg(feature = "full")]
fn expr_struct_helper(input: ParseStream, path: Path) -> Result<ExprStruct> {
fn expr_struct_helper(
input: ParseStream,
qself: Option<QSelf>,
path: Path,
) -> Result<ExprStruct> {
let content;
let brace_token = braced!(content in input);

Expand All @@ -2617,8 +2620,9 @@ pub(crate) mod parsing {
if content.peek(Token![..]) {
return Ok(ExprStruct {
attrs: Vec::new(),
brace_token,
qself,
path,
brace_token,
fields,
dot2_token: Some(content.parse()?),
rest: if content.is_empty() {
Expand All @@ -2639,8 +2643,9 @@ pub(crate) mod parsing {

Ok(ExprStruct {
attrs: Vec::new(),
brace_token,
qself,
path,
brace_token,
fields,
dot2_token: None,
rest: None,
Expand Down Expand Up @@ -3387,7 +3392,7 @@ pub(crate) mod printing {
impl ToTokens for ExprStruct {
fn to_tokens(&self, tokens: &mut TokenStream) {
outer_attrs_to_tokens(&self.attrs, tokens);
self.path.to_tokens(tokens);
path::printing::print_path(tokens, &self.qself, &self.path);
self.brace_token.surround(tokens, |tokens| {
self.fields.to_tokens(tokens);
if let Some(dot2_token) = &self.dot2_token {
Expand Down
3 changes: 3 additions & 0 deletions src/gen/clone.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/gen/debug.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src/gen/eq.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/gen/fold.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/gen/hash.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/gen/visit.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/gen/visit_mut.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 19 additions & 16 deletions src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ ast_struct! {
#[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
pub struct PatStruct {
pub attrs: Vec<Attribute>,
pub qself: Option<QSelf>,
pub path: Path,
pub brace_token: token::Brace,
pub fields: Punctuated<FieldPat, Token![,]>,
Expand All @@ -235,6 +236,7 @@ ast_struct! {
#[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
pub struct PatTupleStruct {
pub attrs: Vec<Attribute>,
pub qself: Option<QSelf>,
pub path: Path,
pub pat: PatTuple,
}
Expand Down Expand Up @@ -464,19 +466,9 @@ pub mod parsing {
}

if input.peek(token::Brace) {
let pat = pat_struct(begin.fork(), input, path)?;
if qself.is_some() {
Ok(Pat::Verbatim(verbatim::between(begin, input)))
} else {
Ok(pat)
}
pat_struct(begin.fork(), input, qself, path)
} else if input.peek(token::Paren) {
let pat = pat_tuple_struct(input, path)?;
if qself.is_some() {
Ok(Pat::Verbatim(verbatim::between(begin, input)))
} else {
Ok(Pat::TupleStruct(pat))
}
pat_tuple_struct(input, qself, path).map(Pat::TupleStruct)
} else if input.peek(Token![..]) {
pat_range(input, qself, path)
} else {
Expand Down Expand Up @@ -521,15 +513,25 @@ pub mod parsing {
})
}

fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
fn pat_tuple_struct(
input: ParseStream,
qself: Option<QSelf>,
path: Path,
) -> Result<PatTupleStruct> {
Ok(PatTupleStruct {
attrs: Vec::new(),
qself,
path,
pat: input.call(pat_tuple)?,
})
}

fn pat_struct(begin: ParseBuffer, input: ParseStream, path: Path) -> Result<Pat> {
fn pat_struct(
begin: ParseBuffer,
input: ParseStream,
qself: Option<QSelf>,
path: Path,
) -> Result<Pat> {
let content;
let brace_token = braced!(content in input);

Expand All @@ -556,6 +558,7 @@ pub mod parsing {

Ok(Pat::Struct(PatStruct {
attrs: Vec::new(),
qself,
path,
brace_token,
fields,
Expand Down Expand Up @@ -817,7 +820,7 @@ mod printing {
impl ToTokens for PatStruct {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.path.to_tokens(tokens);
path::printing::print_path(tokens, &self.qself, &self.path);
self.brace_token.surround(tokens, |tokens| {
self.fields.to_tokens(tokens);
// NOTE: We need a comma before the dot2 token if it is present.
Expand All @@ -833,7 +836,7 @@ mod printing {
impl ToTokens for PatTupleStruct {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
self.path.to_tokens(tokens);
path::printing::print_path(tokens, &self.qself, &self.path);
self.pat.to_tokens(tokens);
}
}
Expand Down
Loading

0 comments on commit ba69d2f

Please sign in to comment.