aboutsummaryrefslogtreecommitdiff
path: root/syntax/qualified.rs
diff options
context:
space:
mode:
Diffstat (limited to 'syntax/qualified.rs')
-rw-r--r--syntax/qualified.rs52
1 files changed, 35 insertions, 17 deletions
diff --git a/syntax/qualified.rs b/syntax/qualified.rs
index 96f07c19..5f182fa9 100644
--- a/syntax/qualified.rs
+++ b/syntax/qualified.rs
@@ -1,5 +1,5 @@
use syn::ext::IdentExt;
-use syn::parse::{ParseStream, Result};
+use syn::parse::{Error, ParseStream, Result};
use syn::{Ident, LitStr, Token};
pub struct QualifiedName {
@@ -8,21 +8,8 @@ pub struct QualifiedName {
impl QualifiedName {
pub fn parse_unquoted(input: ParseStream) -> Result<Self> {
- let mut segments = Vec::new();
- let mut trailing_punct = true;
- let leading_colons: Option<Token![::]> = input.parse()?;
- while trailing_punct && input.peek(Ident::peek_any) {
- let ident = Ident::parse_any(input)?;
- segments.push(ident);
- let colons: Option<Token![::]> = input.parse()?;
- trailing_punct = colons.is_some();
- }
- if segments.is_empty() && leading_colons.is_none() {
- return Err(input.error("expected path"));
- } else if trailing_punct {
- return Err(input.error("expected path segment"));
- }
- Ok(QualifiedName { segments })
+ let allow_raw = true;
+ parse_unquoted(input, allow_raw)
}
pub fn parse_quoted_or_unquoted(input: ParseStream) -> Result<Self> {
@@ -32,10 +19,41 @@ impl QualifiedName {
let segments = Vec::new();
Ok(QualifiedName { segments })
} else {
- lit.parse_with(Self::parse_unquoted)
+ lit.parse_with(|input: ParseStream| {
+ let allow_raw = false;
+ parse_unquoted(input, allow_raw)
+ })
}
} else {
Self::parse_unquoted(input)
}
}
}
+
+fn parse_unquoted(input: ParseStream, allow_raw: bool) -> Result<QualifiedName> {
+ let mut segments = Vec::new();
+ let mut trailing_punct = true;
+ let leading_colons: Option<Token![::]> = input.parse()?;
+ while trailing_punct && input.peek(Ident::peek_any) {
+ let mut ident = Ident::parse_any(input)?;
+ if let Some(unraw) = ident.to_string().strip_prefix("r#") {
+ if !allow_raw {
+ let msg = format!(
+ "raw identifier `{}` is not allowed in a quoted namespace; use `{}`, or remove quotes",
+ ident, unraw,
+ );
+ return Err(Error::new(ident.span(), msg));
+ }
+ ident = Ident::new(unraw, ident.span());
+ }
+ segments.push(ident);
+ let colons: Option<Token![::]> = input.parse()?;
+ trailing_punct = colons.is_some();
+ }
+ if segments.is_empty() && leading_colons.is_none() {
+ return Err(input.error("expected path"));
+ } else if trailing_punct {
+ return Err(input.error("expected path segment"));
+ }
+ Ok(QualifiedName { segments })
+}