diff --git a/src/ast.rs b/src/ast.rs index 030e874..f025cb5 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -65,6 +65,8 @@ pub enum Use { pub enum Pat { /// Matches anything without binding Ignore, + /// Matches nothing, ever + Never, /// Matches nothing; used for macro substitution MetId(String), /// Matches anything, and binds it to a name @@ -84,6 +86,8 @@ pub enum Pat { /// Operators on lists of patterns #[derive(Clone, Debug, PartialEq, Eq)] pub enum PatOp { + /// Changes the visibility mode to "public" + Pub, /// Changes the binding mode to "mutable" Mut, /// Matches the dereference of a pointer (`&pat`) @@ -541,6 +545,7 @@ impl Display for Pat { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Ignore => "_".fmt(f), + Self::Never => "!".fmt(f), Self::Lit(literal) => literal.fmt(f), Self::MetId(name) => write!(f, "`{name}"), Self::Name(name) => name.fmt(f), @@ -569,6 +574,7 @@ impl Display for Pat { impl Display for PatOp { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(match self { + Self::Pub => "pub ", Self::Mut => "mut ", Self::Ref => "&", Self::Rest => "..", diff --git a/src/ast/macro_matcher.rs b/src/ast/macro_matcher.rs index ae94b22..4f36d8e 100644 --- a/src/ast/macro_matcher.rs +++ b/src/ast/macro_matcher.rs @@ -180,6 +180,8 @@ impl Match for Pat { (Pat::MetId(name), _) => sub.add_pat(name.clone(), expr), (Pat::Ignore, Pat::Ignore) => true, (Pat::Ignore, _) => false, + (Pat::Never, Pat::Never) => true, + (Pat::Never, _) => false, (Pat::Name(pat), Pat::Name(expr)) => pat == expr, (Pat::Name(_), _) => false, (Pat::Path(_), Pat::Path(_)) => true, @@ -197,7 +199,7 @@ impl Match for Pat { fn apply(&mut self, sub: &Subst) { match self { - Pat::Ignore | Pat::Name(_) | Pat::Path(_) | Pat::Lit(_) => {} + Pat::Ignore | Pat::Never | Pat::Name(_) | Pat::Path(_) | Pat::Lit(_) => {} Pat::MetId(id) => { if let Some(expr) = sub.pat.get(id) { *self = expr.clone() diff --git a/src/parser.rs b/src/parser.rs index 0a04a47..54bdd06 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -359,8 +359,10 @@ impl<'t> Parse<'t> for Pat { Pat::Lit(p.parse(())?) } TKind::Bar => p.consume().parse(level)?, + TKind::Bang => p.consume().then(Pat::Never), TKind::Amp => Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?]), TKind::Mut => Pat::Op(PatOp::Mut, vec![p.consume().parse(level)?]), + TKind::Public => Pat::Op(PatOp::Pub, vec![p.consume().parse(level)?]), TKind::AmpAmp => Pat::Op( PatOp::Ref, vec![Pat::Op(PatOp::Ref, vec![p.consume().parse(PPrec::Max)?])],