diff --git a/Cargo.lock b/Cargo.lock index 5a48fcdc..e4957000 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1554,6 +1554,7 @@ version = "0.1.0" dependencies = [ "derive_more", "pest_typed", + "rpl_config", "rpl_constraints", "rpl_meta", "rpl_parser", @@ -1564,6 +1565,7 @@ dependencies = [ name = "rpl_driver" version = "0.1.0" dependencies = [ + "rpl_config", "rpl_constraints", "rpl_context", "rpl_match", @@ -1673,6 +1675,10 @@ version = "0.1.0" [[package]] name = "rpl_resolve" version = "0.1.0" +dependencies = [ + "rpl_context", + "rpl_meta", +] [[package]] name = "rpl_utils" diff --git a/crates/rpl_config/src/lib.rs b/crates/rpl_config/src/lib.rs index 0b889a65..a92ab410 100644 --- a/crates/rpl_config/src/lib.rs +++ b/crates/rpl_config/src/lib.rs @@ -2,10 +2,13 @@ use std::path::{Path, PathBuf}; use serde::Deserialize; +mod ops; mod patterns; mod run; mod util; +pub use ops::RawOpInstance; + #[derive(Debug, thiserror::Error)] pub enum ConfigError { #[error("failed to read {path}: {source}")] @@ -46,9 +49,11 @@ pub enum ConfigError { } #[derive(Debug, Deserialize)] -struct RplConfig { - run: Option, - patterns: Option, +pub struct RplConfig { + pub(crate) run: Option, + pub(crate) patterns: Option, + #[serde(default)] + pub ops: std::collections::HashMap>, } #[derive(Debug)] @@ -72,3 +77,22 @@ pub fn load_config(manifest_path: Option<&Path>, selected_groups: &[String]) -> inline_mir, }) } + +/// Load the raw op-group instances from `rpl.toml` in the current directory +/// (or adjacent to `manifest_path` if given). +/// +/// Returns an empty map when no `rpl.toml` exists or when the file contains +/// no `[ops]` table. Errors during config file reading are surfaced as +/// `Err(ConfigError)`. +pub fn load_raw_ops( + manifest_path: Option<&Path>, +) -> Result>, ConfigError> { + let base_dir = util::resolve_base_dir(manifest_path)?; + let config_path = base_dir.join("rpl.toml"); + if config_path.exists() { + let config = util::read_config(&config_path)?; + Ok(config.ops) + } else { + Ok(std::collections::HashMap::new()) + } +} diff --git a/crates/rpl_config/src/ops.rs b/crates/rpl_config/src/ops.rs new file mode 100644 index 00000000..62635152 --- /dev/null +++ b/crates/rpl_config/src/ops.rs @@ -0,0 +1,57 @@ +use std::collections::BTreeMap; + +use serde::Deserialize; + +/// One instance of an op-group as declared in `rpl.toml`. +/// +/// All values are stored as raw strings; substitution happens later in `rpl_context`. +#[derive(Debug, Clone)] +pub struct RawOpInstance { + /// Existential type-placeholder names declared via `type = [...]`. + pub free: Vec, + /// Every other key/value pair (op-level meta-var bindings + op-name bindings). + pub bindings: BTreeMap, +} + +impl<'de> Deserialize<'de> for RawOpInstance { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let mut raw: BTreeMap = BTreeMap::deserialize(deserializer)?; + + let free = match raw.remove("type") { + None => Vec::new(), + Some(toml::Value::Array(arr)) => arr + .into_iter() + .map(|v| match v { + toml::Value::String(s) => Ok(s), + other => Err(serde::de::Error::custom(format!( + "ops 'type' entries must be strings, got {other:?}" + ))), + }) + .collect::, D::Error>>()?, + Some(other) => { + return Err(serde::de::Error::custom(format!( + "ops 'type' must be an array of strings, got {other:?}" + ))); + }, + }; + + let mut bindings = BTreeMap::new(); + for (k, v) in raw { + match v { + toml::Value::String(s) => { + bindings.insert(k, s); + }, + other => { + return Err(serde::de::Error::custom(format!( + "ops binding '{k}' must be a string, got {other:?}" + ))); + }, + } + } + + Ok(RawOpInstance { free, bindings }) + } +} diff --git a/crates/rpl_config/src/patterns.rs b/crates/rpl_config/src/patterns.rs index f7ea2507..7c0ffa91 100644 --- a/crates/rpl_config/src/patterns.rs +++ b/crates/rpl_config/src/patterns.rs @@ -149,6 +149,19 @@ pub(crate) fn resolve_patterns_env( None => return Ok(None), }; + // An empty paths vector here can arise when `rpl.toml` exists but contains + // no `[patterns]` table (e.g. only `[run]` or `[[ops.]]`) and the + // caller did not pass `--patterns`. In that case `resolve_patterns` takes + // the vacuous-true branch of `selected_groups.iter().all(is_remote_spec)` + // and returns `Some(ResolvedPatterns { paths: vec![] })`. Joining zero + // paths yields the empty string, which would propagate to the child + // process as `RPL_PATS=""` and trip + // `rpl_meta::cli E100: Cannot locate RPL pattern file ""`. Map empty to + // `None` here so the child falls back to the built-in pattern set. + if resolved.paths.is_empty() { + return Ok(None); + } + let mut entries = Vec::with_capacity(resolved.paths.len()); for path in resolved.paths { if path.to_str().is_none() { diff --git a/crates/rpl_config/tests/ops_loading.rs b/crates/rpl_config/tests/ops_loading.rs new file mode 100644 index 00000000..c2352522 --- /dev/null +++ b/crates/rpl_config/tests/ops_loading.rs @@ -0,0 +1,39 @@ +use rpl_config::{RawOpInstance, RplConfig}; + +const TOML: &str = r#" +[[patterns.local]] +name = "g" +path = ["patterns/foo.rpl"] + +[[ops.sync]] +type = ["$1"] +T = "std::sync::Mutex<$1>" +U = "std::sync::MutexGuard<$1>" +lock = "$T::lock" +unlock = "$U::drop" + +[[ops.sync]] +type = ["$1"] +T = "parking_lot::Mutex<$1>" +U = "parking_lot::MutexGuard<$1>" +lock = "$T::lock" +unlock = "$U::drop" +"#; + +#[test] +fn loads_two_sync_instances() { + let cfg: RplConfig = toml::from_str(TOML).expect("parse"); + let sync_instances = cfg.ops.get("sync").expect("sync key present"); + assert_eq!(sync_instances.len(), 2); + let i0: &RawOpInstance = &sync_instances[0]; + assert_eq!(i0.free, vec!["$1".to_string()]); + assert_eq!(i0.bindings.get("T").unwrap(), "std::sync::Mutex<$1>"); + assert_eq!(i0.bindings.get("lock").unwrap(), "$T::lock"); +} + +#[test] +fn type_key_is_not_in_bindings() { + let cfg: RplConfig = toml::from_str(TOML).expect("parse"); + let i0 = &cfg.ops["sync"][0]; + assert!(!i0.bindings.contains_key("type")); +} diff --git a/crates/rpl_context/Cargo.toml b/crates/rpl_context/Cargo.toml index 54962007..a14952f0 100644 --- a/crates/rpl_context/Cargo.toml +++ b/crates/rpl_context/Cargo.toml @@ -10,11 +10,15 @@ edition.workspace = true [dependencies] derive_more.workspace = true pest_typed.workspace = true +rpl_config.workspace = true rpl_meta.workspace = true rpl_parser.workspace = true rpl_constraints.workspace = true sync-arena.workspace = true +[dev-dependencies] +rpl_config.workspace = true + [features] [package.metadata.rust-analyzer] diff --git a/crates/rpl_context/src/context.rs b/crates/rpl_context/src/context.rs index ca5d0c55..831f8b41 100644 --- a/crates/rpl_context/src/context.rs +++ b/crates/rpl_context/src/context.rs @@ -203,7 +203,7 @@ impl<'pcx> PatCtxt<'pcx> { ) { let pattern = self.new_pattern(); // FIXME: process utils - let (utils, patts, diags) = collect_blocks(main); + let (utils, patts, ops, diags) = collect_blocks(main); let symbol_tables = &mctx.symbol_tables.get(id).unwrap(); { @@ -217,6 +217,22 @@ impl<'pcx> PatCtxt<'pcx> { ); }); } + { + for ops_block in &ops { + let wf_errors = pattern.add_ops_block(with_path(mctx.get_active_path(), ops_block)); + for err in &wf_errors { + warn!("ops well-formedness: {}", err); + } + } + // R6: op-level meta-vars (declared in `ops { ... }`) must not leak + // into pattern-block bodies. Implemented but previously never + // invoked — the rule was unenforced. Surface violations as + // warnings here, alongside R1–R3. + let r6_errors = pat::check_r6_patt_vs_ops(&ops, &patts); + for err in &r6_errors { + warn!("ops well-formedness (R6): {}", err); + } + } { let patt_items = patts.iter().flat_map(|patt| patt.get_matched().3.iter_matched()); let patt_symbol_tables = &symbol_tables.patt_symbol_tables; @@ -237,6 +253,12 @@ impl<'pcx> PatCtxt<'pcx> { } } + // R4/R5 post-lowering use-site checks + referenced_op_groups population. + pattern.check_and_populate_op_refs(); + for err in pattern.op_ref_errors() { + warn!("op-ref use-site: {}", err); + } + let mut patterns = self.rpl_patterns.lock(); debug_assert_eq!(patterns.next_index(), id); patterns.push(pattern); diff --git a/crates/rpl_context/src/pat/mir/mod.rs b/crates/rpl_context/src/pat/mir/mod.rs index 0ac18845..8bd6a5a7 100644 --- a/crates/rpl_context/src/pat/mir/mod.rs +++ b/crates/rpl_context/src/pat/mir/mod.rs @@ -875,6 +875,11 @@ pub enum Operand<'pcx> { Move(Place<'pcx>), Constant(ConstOperand<'pcx>), FnPat(Symbol), + /// Reference to an operation `$group::$op` declared in the `ops` block. + OpRef { + group: Symbol, + op: Symbol, + }, } impl<'pcx> Operand<'pcx> { @@ -929,19 +934,25 @@ impl<'pcx> Operand<'pcx> { ) -> Self { let p = op.path; match op.inner.deref() { - Choice5::_0(copy_) => Self::from_copy(WithPath::new(p, copy_.get_matched().1), pcx, fn_sym_tab), - Choice5::_1(move_) => Self::from_move(WithPath::new(p, move_.get_matched().1), pcx, fn_sym_tab), - Choice5::_2(type_path) => Self::Constant(ConstOperand::from_type_path( + Choice6::_0(copy_) => Self::from_copy(WithPath::new(p, copy_.get_matched().1), pcx, fn_sym_tab), + Choice6::_1(move_) => Self::from_move(WithPath::new(p, move_.get_matched().1), pcx, fn_sym_tab), + Choice6::_2(type_path) => Self::Constant(ConstOperand::from_type_path( WithPath::new(p, type_path), pcx, fn_sym_tab, )), - Choice5::_3(lang_item) => Self::Constant(ConstOperand::from_lang_item( + Choice6::_3(lang_item) => Self::Constant(ConstOperand::from_lang_item( WithPath::new(p, lang_item), pcx, fn_sym_tab, )), - Choice5::_4(meta_var) => Self::from_meta_var(meta_var), + Choice6::_4(op_ref) => { + let (group_meta, op_meta) = op_ref.MetaVariable(); + let group = Symbol::intern(group_meta.span.as_str().trim_start_matches('$')); + let op = Symbol::intern(op_meta.span.as_str().trim_start_matches('$')); + Self::OpRef { group, op } + }, + Choice6::_5(meta_var) => Self::from_meta_var(meta_var), } } } @@ -1569,3 +1580,74 @@ impl BasicBlockData<'_> { pub(crate) fn with_path(path: &'_ std::path::Path, inner: T) -> WithPath<'_, T> { WithPath { path, inner } } + +#[cfg(test)] +mod tests { + use rustc_span::Symbol; + + use super::Operand; + + #[test] + fn op_ref_constructs_and_matches() { + rustc_span::create_session_if_not_set_then(rustc_span::edition::LATEST_STABLE_EDITION, |_| { + let group = Symbol::intern("sync"); + let op = Symbol::intern("lock"); + let operand: Operand<'_> = Operand::OpRef { group, op }; + match operand { + Operand::OpRef { group: g, op: o } => { + assert_eq!(g.as_str(), "sync"); + assert_eq!(o.as_str(), "lock"); + }, + _ => panic!("expected OpRef variant"), + } + }); + } + + /// Verify that `Operand::from_fn_op` strips the leading `$` when lowering an + /// `OpRef` (`$group::$op`) from the parser, so the stored symbols are bare + /// and will match the keys used by `OpGroup.name` / Task 7's resolver lookup. + /// + /// This test uses the simplified extraction form (parse → access OpRef node → + /// apply the same `trim_start_matches('$')` as `from_fn_op` does) rather than + /// calling `from_fn_op` directly, because `from_fn_op` requires a `PatCtxt` + /// that cannot be constructed in a unit test. The test would have FAILED + /// before the fix because `group_meta.span.as_str()` returned `"$sync"` and + /// `op_meta.span.as_str()` returned `"$lock"`. + #[test] + fn op_ref_lowers_with_bare_symbols() { + use pest_typed::TypedParser as _; + use rpl_parser::parser::{Grammar, pairs}; + + let parsed = + Grammar::try_parse::("$sync::$lock").expect("$sync::$lock must parse as MirFnOperand"); + + // `MirFnOperand` is `Choice6`; variant `_4` is `OpRef`. + let op_ref = parsed + .OpRef() + .expect("$sync::$lock must lower to the OpRef variant of MirFnOperand"); + + let (group_meta, op_meta) = op_ref.MetaVariable(); + + // Replicate the exact logic from `from_fn_op`'s `Choice6::_4` arm. + let group_raw = group_meta.span.as_str(); + let op_raw = op_meta.span.as_str(); + + // Before the fix both of these would be "$sync" / "$lock". + let group_bare = group_raw.trim_start_matches('$'); + let op_bare = op_raw.trim_start_matches('$'); + + assert_eq!(group_bare, "sync", "group symbol must be bare (no $ prefix)"); + assert_eq!(op_bare, "lock", "op symbol must be bare (no $ prefix)"); + + // Also assert the raw span really does start with `$`, confirming that + // the trim is necessary (i.e., the test would have caught the bug). + assert!( + group_raw.starts_with('$'), + "parser span must include the $ sigil; got {group_raw:?}" + ); + assert!( + op_raw.starts_with('$'), + "parser span must include the $ sigil; got {op_raw:?}" + ); + } +} diff --git a/crates/rpl_context/src/pat/mir/pretty.rs b/crates/rpl_context/src/pat/mir/pretty.rs index 1b1e5ef4..f25bcca3 100644 --- a/crates/rpl_context/src/pat/mir/pretty.rs +++ b/crates/rpl_context/src/pat/mir/pretty.rs @@ -211,6 +211,7 @@ impl Operand<'_> { Self::Move(place) => write!(f, "(move {place:?})"), Self::Constant(konst) => write!(f, "{konst:?}"), Self::FnPat(fn_pat) => write!(f, "${fn_pat}"), + Self::OpRef { group, op } => write!(f, "${group}::{op}"), } } } @@ -223,6 +224,7 @@ impl fmt::Debug for Operand<'_> { Self::Move(place) => write!(f, "move {place:?}"), Self::Constant(konst) => write!(f, "const {konst:?}"), Self::FnPat(fn_pat) => write!(f, "const ${fn_pat}"), + Self::OpRef { group, op } => write!(f, "${group}::{op}"), } } } diff --git a/crates/rpl_context/src/pat/mir/visitor.rs b/crates/rpl_context/src/pat/mir/visitor.rs index 316c3c2e..c0cc3e6f 100644 --- a/crates/rpl_context/src/pat/mir/visitor.rs +++ b/crates/rpl_context/src/pat/mir/visitor.rs @@ -198,6 +198,10 @@ pub trait PatternVisitor<'pcx>: Sized { ), Operand::Constant(const_operand) => self.visit_const_operand(const_operand), &Operand::FnPat(fn_pat) => self.visit_fn_pat(fn_pat), + // OpRef is a function-position operand (`$group::$op`); it carries + // no sub-operands or types to visit. R4/R5 checks in ops_uses.rs + // handle validation separately; the visitor just traverses past it. + Operand::OpRef { .. } => {}, } } fn super_statement(&mut self, statement: &StatementKind<'pcx>, location: Location) { diff --git a/crates/rpl_context/src/pat/mod.rs b/crates/rpl_context/src/pat/mod.rs index a0073f6d..fa3ea236 100644 --- a/crates/rpl_context/src/pat/mod.rs +++ b/crates/rpl_context/src/pat/mod.rs @@ -1,3 +1,4 @@ +use std::cell::OnceCell; use std::fmt::Debug; use std::hash::Hash; use std::ops::Deref; @@ -6,14 +7,16 @@ use std::sync::Arc; pub use error::DynamicError; use error::DynamicErrorBuilder; use rpl_constraints::Constraints; +use rpl_constraints::predicates::PredicateConjunction; use rpl_meta::collect_elems_separated_by_comma; use rpl_meta::meta::PattSymbolTables; -use rpl_meta::symbol_table::WithPath; +use rpl_meta::symbol_table::{GetType, MetaVariable, TypeOrPath, WithPath}; +use rpl_meta::utils::self_param_ty; use rpl_parser::generics::{Choice2, Choice3, Choice4}; use rpl_parser::pairs; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir::FnDecl; -use rustc_middle::mir::Body; +use rustc_middle::mir::{Body, Mutability as MirMutability}; use rustc_span::Symbol; use rustc_span::source_map::SourceMap; @@ -27,6 +30,10 @@ mod item; mod matched; mod mir; mod non_local_meta_vars; +mod ops; +pub mod ops_resolved; +pub mod ops_uses; +pub mod ops_wf; mod pretty; mod table; mod ty; @@ -37,6 +44,10 @@ pub use item::*; pub use matched::{Matched, MatchedMap}; pub use mir::*; pub use non_local_meta_vars::*; +pub use ops::*; +pub use ops_resolved::ResolvedOpBindings; +pub use ops_uses::{OpsUseError, check_op_refs}; +pub use ops_wf::{OpsWfError, check_ops_block, check_r6_patt_vs_ops}; pub(crate) use table::TableHead; pub use ty::*; @@ -103,6 +114,15 @@ pub struct RustItems<'pcx> { pub fns: FnPatterns<'pcx>, pub impls: FxHashMap>, pub attr: PatAttr<'pcx>, + /// The set of op-group names referenced by `Operand::OpRef` anywhere in + /// this pattern's function bodies. Populated by + /// [`Pattern::check_and_populate_op_refs`] after lowering completes. + /// + /// Stored in a `OnceCell` so it can be initialised via a shared `&Self` + /// reference (as held by `util_block`, where items are arena-allocated and + /// shared across multiple `PatternOperation`s). Reads before population + /// return an empty set via `get_or_init`. + pub(crate) referenced_op_groups: OnceCell>, } impl<'pcx> RustItems<'pcx> { @@ -114,9 +134,25 @@ impl<'pcx> RustItems<'pcx> { fns: Default::default(), impls: Default::default(), attr, + referenced_op_groups: OnceCell::new(), } } + /// Returns the set of op-group names referenced by `$group::$op` operands + /// anywhere in this pattern's function bodies. + /// + /// This is populated by [`Pattern::check_and_populate_op_refs`] after all + /// pattern items and the ops block have been lowered. The matcher (Task + /// 11) consumes this to know which op-group instances to iterate. + /// + /// If called before population, returns a (durable) empty set via + /// `OnceCell::get_or_init`; subsequent population attempts on an + /// already-initialised cell are silently ignored, which preserves the + /// invariant that the first observed value is the final one. + pub fn referenced_op_groups(&self) -> &FxHashSet { + self.referenced_op_groups.get_or_init(FxHashSet::default) + } + fn add_item( &mut self, pat_name: Option, @@ -356,6 +392,31 @@ impl PatternOperation<'_> { pub fn post_process(&self, iter: impl Iterator) -> impl Iterator { self.attr.post_process(iter) } + + /// Returns the union of op-group names referenced by any operand + /// (positive or negative) of this set-op, recursing into nested + /// `PatternOperation`s. + /// + /// This is consumed by the matcher (Task 11) to know which op-group + /// instances to iterate over for cartesian-product expansion. + pub fn referenced_op_groups(&self) -> FxHashSet { + let mut all = FxHashSet::default(); + for (_name, item, _map) in self.positive.iter().chain(self.negative.iter()) { + match item { + PatternItem::RustItems(rust_items) => { + for &g in rust_items.referenced_op_groups() { + all.insert(g); + } + }, + PatternItem::RPLPatternOperation(inner) => { + for g in inner.referenced_op_groups() { + all.insert(g); + } + }, + } + } + all + } } /// Corresponds to a pattern file in RPL, not a pattern item. @@ -363,7 +424,11 @@ pub struct Pattern<'pcx> { pub pcx: PatCtxt<'pcx>, pub patt_block: FxIndexMap>, // indexed by pat_name pub util_block: FxIndexMap>, // indexed by pat_name + pub ops_block: OpsBlock<'pcx>, diag_block: FxHashMap>, + /// R4/R5 errors discovered during `check_and_populate_op_refs`. + /// Stored here so callers (tests, driver) can inspect them after lowering. + pub(crate) op_ref_errors: Vec, } impl<'pcx> Pattern<'pcx> { @@ -372,10 +437,17 @@ impl<'pcx> Pattern<'pcx> { pcx, patt_block: Default::default(), util_block: Default::default(), + ops_block: OpsBlock::default(), diag_block: Default::default(), + op_ref_errors: Default::default(), } } + /// Returns the R4/R5 use-site errors found during `check_and_populate_op_refs`. + pub fn op_ref_errors(&self) -> &[ops_uses::OpsUseError] { + &self.op_ref_errors + } + pub fn get_diag<'tcx>( &self, pat_name: Symbol, @@ -551,6 +623,145 @@ impl<'pcx> Pattern<'pcx> { }; } + /// Lower an `opsBlock` pest pair into `self.ops_block`. + /// + /// Runs well-formedness checks R1–R3 on the raw parse tree before any + /// lowering so that the `unreachable!()` contracts in `OpsMetaLookup` + /// cannot be triggered by malformed input. Groups that fail a check are + /// skipped; callers should surface the returned errors to the user. + /// + /// For each (valid) `opsItem` in the block we: + /// 1. Extract the group name (bare, no leading `$`). + /// 2. Lower the `MetaVariableDeclList` into `NonLocalMetaVars` using a minimal `GetType` + /// implementation backed by the item's own type-var declarations. + /// 3. Lower each `OpFnDecl` into an `OpSignature` (name, params, ret). + /// 4. Build an `OpGroup` and insert it into `self.ops_block.groups`. + /// + /// Returns the list of well-formedness errors found (if any). + pub fn add_ops_block<'mcx: 'pcx>( + &mut self, + ops_block: WithPath<'mcx, &'mcx pairs::opsBlock<'mcx>>, + ) -> Vec { + // R1–R3: pre-validate before touching any lowering code. + let wf_errors = ops_wf::check_ops_block(ops_block.inner); + // Collect group names that have errors so we can skip them below. + let bad_groups: std::collections::HashSet<&str> = wf_errors.iter().map(|e| e.group.as_str()).collect(); + + let p = ops_block.path; + for item in ops_block.opsItem() { + // -- 1. Group name (bare Identifier, no `$`). + let group_name = Symbol::intern(item.Identifier().span.as_str()); + let _span = item.span; // TODO(task-6): replace DUMMY_SP with a real rustc Span + + // Skip groups that failed R1/R2/R3. + if bad_groups.contains(group_name.as_str()) { + continue; + } + + // -- 2. Pre-scan MetaVariableDeclList to build OpsMetaLookup. + // We need the lookup both for `NonLocalMetaVars::from_meta_decls` + // (const/place var types) and for `Ty::from` on param types + // that reference type meta-variables like `$T`. + let meta_decl_list = item.MetaVariableDeclList(); + let lookup = OpsMetaLookup::from_meta_decl_list(meta_decl_list); + + // -- 3. Lower the MetaVariableDeclList into NonLocalMetaVars. + let meta = + NonLocalMetaVars::from_meta_decls(meta_decl_list.map(|mdl| WithPath::new(p, mdl)), self.pcx, &lookup); + + // -- 4. Lower each OpFnDecl into OpSignature. + let mut ops: FxIndexMap> = FxIndexMap::default(); + for decl in item.OpFnDecl() { + let sig = decl.OpFnSig(); + // Op name: FnName is PlaceHolder | MetaVariable | Identifier. + // In practice op fn names are MetaVariables like `$lock`. + let op_name_raw = sig.FnName().span.as_str(); + let op_name = Symbol::intern(op_name_raw.trim_start_matches('$')); + + // Lower parameters. + let params: Vec> = if let Some(params_pair) = sig.OpFnParamsSeparatedByComma() { + let (first, rest) = params_pair.OpFnParam(); + std::iter::once(first) + .chain(rest) + .filter_map(|param| lower_op_fn_param(p, param, self.pcx, &lookup)) + .collect() + } else { + Vec::new() + }; + + // Lower return type. + // We inline the logic of Ty::from_fn_ret because that function + // takes &FnSymbolTable specifically; here we use our OpsMetaLookup. + let ret = sig.FnRet().map(|fn_ret| { + let (_, placeholder_or_ty) = fn_ret.get_matched(); + match placeholder_or_ty { + Choice2::_0(_) => self.pcx.mk_any_ty(), + Choice2::_1(ty) => Ty::from(WithPath::new(p, ty), self.pcx, &lookup), + } + }); + + let op_sig = OpSignature { + name: op_name, + params, + ret, + span: rustc_span::DUMMY_SP, + }; // TODO(task-6): replace DUMMY_SP with a real rustc Span + ops.insert(op_name, op_sig); + } + + // -- 5. Build OpGroup and insert. + let group = OpGroup { + name: group_name, + meta_vars: meta, + ops, + span: rustc_span::DUMMY_SP, + }; // TODO(task-6): replace DUMMY_SP with a real rustc Span + self.ops_block.groups.insert(group_name, group); + } + wf_errors + } + + /// Run R4/R5 use-site checks on all `RustItems` in `patt_block` and + /// `util_block`, populate `referenced_op_groups` on each `RustItems`, and + /// store discovered errors in `self.op_ref_errors`. + /// + /// Call this **after** both `add_ops_block` and all `add_pattern_item` + /// calls have completed. + /// + /// `referenced_op_groups` is now a `OnceCell`, so population goes through + /// `OnceCell::set` via a shared reference. This works uniformly for + /// `patt_block` (owned `PatternItem`s) and `util_block` (arena-allocated + /// items shared across multiple `PatternOperation`s) — no `unsafe` is + /// needed. A second `set` on an already-initialised cell returns `Err` + /// and is ignored: by construction, each `RustItems` is visited once here + /// and not observed by any reader until after this function returns. + pub fn check_and_populate_op_refs(&mut self) { + let mut all_errors = Vec::new(); + + let process = |rust_items: &RustItems<'pcx>, errors: &mut Vec| { + let mut referenced = FxHashSet::default(); + let errs = ops_uses::check_op_refs(rust_items, &self.ops_block, &mut referenced); + // `set` returns Err iff the cell was already initialised; that + // would indicate this function ran twice, which is a logic bug + // but not a soundness one — silently keep the prior value. + let _ = rust_items.referenced_op_groups.set(referenced); + errors.extend(errs); + }; + + for (_name, item) in &self.patt_block { + if let PatternItem::RustItems(rust_items) = item { + process(rust_items, &mut all_errors); + } + } + for (_name, item_ref) in &self.util_block { + if let PatternItem::RustItems(rust_items) = *item_ref { + process(rust_items, &mut all_errors); + } + } + + self.op_ref_errors = all_errors; + } + pub fn add_diag<'mcx: 'pcx>( &mut self, diag: WithPath<'mcx, &'mcx pairs::diagBlock<'mcx>>, @@ -589,3 +800,150 @@ impl<'pcx> Pattern<'pcx> { } } } + +/// Minimal `GetType` implementation for lowering ops-item signatures. +/// +/// Ops items do not import Rust types or paths — they only use type meta-variables +/// (e.g. `$T`, `$U`) declared in the item's own `MetaVariableDeclList`. +/// This struct is populated by pre-scanning that list and maps each declared +/// type-variable name to its 0-based index. +struct OpsMetaLookup<'i> { + /// (bare_name_with_dollar, index) + type_vars: Vec<(&'i str, usize)>, +} + +impl<'i> OpsMetaLookup<'i> { + /// Build an `OpsMetaLookup` by scanning the `MetaVariableDeclList` of one + /// `opsItem`. Only `$T: type` style (type-kind) declarations are collected; + /// const and place vars are skipped (they would panic if their types + /// contained path identifiers, but that scenario is not supported yet). + /// + /// # Index-counter alignment with `NonLocalMetaVars` + /// + /// `NonLocalMetaVars::from_meta_decls` partitions declarations into three + /// separate buckets (type / const / place) and then pushes each bucket into + /// its own `IndexVec` in three independent passes — so type-var indices in + /// `NonLocalMetaVars` always start at 0 and count only type-kind decls. + /// This function counts `idx` the same way (incrementing only for + /// type-kind decls), so the `MetaVariable::Type(idx, …)` values we emit + /// for downstream consumers are aligned. This is **Path A** from the + /// code-review checklist: the counter is correct as-is and must *not* be + /// changed to be unconditional. + fn from_meta_decl_list(meta_decl_list: Option<&'i pairs::MetaVariableDeclList<'i>>) -> Self { + let mut type_vars = Vec::new(); + if let Some(mdl) = meta_decl_list + && let Some(inner) = mdl.get_matched().1 + { + let decls = collect_elems_separated_by_comma!(inner).collect::>(); + let mut idx = 0usize; + for decl in &decls { + let (ident, _, ty, _) = decl.get_matched(); + if matches!(ty.deref(), Choice3::_0(_)) { + // Type meta-variable: retain name with $ prefix for matching. + // idx counts only type-kind decls — see alignment note above. + type_vars.push((ident.span.as_str(), idx)); + idx += 1; + } + } + } + Self { type_vars } + } +} + +impl<'i> GetType<'i> for OpsMetaLookup<'i> { + fn get_type_or_path( + &self, + ident: &WithPath<'i, &pairs::Identifier<'i>>, + ) -> Result, rpl_meta::RPLMetaError<'i>> { + // Ops signatures must only reference meta-variables declared in their + // MetaVariableDeclList — bare Rust path types are not permitted. + // Reaching this branch means resolver check R1 (Task 6) was not run + // or failed to reject the invalid signature before lowering. + unreachable!( + "internal: ops signatures must use only op-level meta-vars; \ + bare path type `{}` at {:?} should have been rejected by \ + resolver check R1 before lowering", + ident.span.as_str(), + ident.path + ) + } + + fn force_get_meta_var(&self, ident: WithPath<'i, &pairs::MetaVariable<'i>>) -> MetaVariable<'i> { + let name = ident.inner.span.as_str(); + // The meta variable includes the `$` prefix in its span text. + if let Some((_, idx)) = self.type_vars.iter().find(|(n, _)| *n == name) { + MetaVariable::Type(*idx, PredicateConjunction::default()) + } else { + // Reaching this branch means the meta-variable was used in a + // signature but not declared in the ops item's MetaVariableDeclList. + // Resolver check R1 (Task 6) must reject this before lowering. + unreachable!( + "internal: meta-variable `{}` at {:?} is not declared in this \ + ops item; this should have been rejected by resolver check R1 \ + before lowering", + name, ident.path + ) + } + } +} + +/// Lower a single `OpFnParam` into a `Param`, or return `None` for the +/// variadic `..` case (which sets `non_exhaustive` rather than adding a param). +/// +/// Handles the five alternatives of `OpFnParam`: +/// - `SelfParam` → self parameter with auto-inferred type +/// - `NormalParam` → `$name: Type` +/// - `PlaceHolderWithType` → `_: Type` +/// - `Type` → anonymous parameter with inferred type (e.g. `&mut $T`) +/// - `Dot2` → variadic `..`; returns `None` +fn lower_op_fn_param<'mcx, 'pcx: 'mcx>( + p: &'mcx std::path::Path, + param: &'mcx pairs::OpFnParam<'mcx>, + pcx: PatCtxt<'pcx>, + lookup: &OpsMetaLookup<'mcx>, +) -> Option> { + use utils::mutability_from_pair_mutability; + + if let Some(self_param) = param.SelfParam() { + let (ty, mutability) = self_param_ty(self_param); + let ty = Ty::from(WithPath::new(p, ty), pcx, lookup); + return Some(Param { + mutability, + ident: Symbol::intern("self"), + ty, + }); + } + + if let Some(normal) = param.NormalParam() { + let (mutability, ident, _, ty) = normal.get_matched(); + let mutability = mutability_from_pair_mutability(mutability); + let ident = Symbol::intern(ident.span.as_str()); + let ty = Ty::from(WithPath::new(p, ty), pcx, lookup); + return Some(Param { mutability, ident, ty }); + } + + if let Some(place_holder_with_type) = param.PlaceHolderWithType() { + let (mutability, _placeholder, _, ty) = place_holder_with_type.get_matched(); + let mutability = mutability_from_pair_mutability(mutability); + let ty = Ty::from(WithPath::new(p, ty), pcx, lookup); + return Some(Param { + mutability, + ident: Symbol::intern("_"), + ty, + }); + } + + if let Some(ty_only) = param.Type() { + // Bare `Type` parameter: no explicit name, synthesize `_`. + let ty = Ty::from(WithPath::new(p, ty_only), pcx, lookup); + return Some(Param { + mutability: MirMutability::Not, + ident: Symbol::intern("_"), + ty, + }); + } + + // Dot2 / `..` — variadic; callers can set non_exhaustive if needed. + // For ops signatures we simply drop it (no body to match against). + None +} diff --git a/crates/rpl_context/src/pat/ops.rs b/crates/rpl_context/src/pat/ops.rs new file mode 100644 index 00000000..69f8c5c9 --- /dev/null +++ b/crates/rpl_context/src/pat/ops.rs @@ -0,0 +1,40 @@ +use derive_more::derive::Debug; +use rustc_data_structures::fx::FxIndexMap; +use rustc_span::{Span, Symbol}; + +use crate::pat::{NonLocalMetaVars, Param, Ty}; + +/// A single function signature inside an op-group. Body-less. +#[derive(Debug)] +pub struct OpSignature<'pcx> { + pub name: Symbol, + pub params: Vec>, + pub ret: Option>, + pub span: Span, +} + +/// An abstract op group — a parameterized bundle of named MIR signatures. +#[derive(Debug)] +pub struct OpGroup<'pcx> { + pub name: Symbol, + pub meta_vars: NonLocalMetaVars<'pcx>, + pub ops: FxIndexMap>, + pub span: Span, +} + +/// The contents of the `ops { ... }` block. +#[derive(Debug, Default)] +pub struct OpsBlock<'pcx> { + pub groups: FxIndexMap>, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn opsblock_default_is_empty() { + let b = OpsBlock::default(); + assert!(b.groups.is_empty()); + } +} diff --git a/crates/rpl_context/src/pat/ops_resolved.rs b/crates/rpl_context/src/pat/ops_resolved.rs new file mode 100644 index 00000000..62bdb41e --- /dev/null +++ b/crates/rpl_context/src/pat/ops_resolved.rs @@ -0,0 +1,338 @@ +use std::collections::{BTreeMap, BTreeSet}; + +use rustc_data_structures::fx::FxHashMap; +use rustc_span::Symbol; + +use crate::pat::Pattern; + +/// A fully resolved op-group instance. +/// +/// Post-expansion strings are stored rather than typed AST nodes (the deferred-parse +/// path from Task 9 Step 5). This keeps the implementation self-contained and avoids +/// threading a `PatCtxt` through the resolution logic. The matcher (Task 12) will +/// parse each string into a `Ty<'pcx>` or `Path<'pcx>` at match time. +#[derive(Debug, Clone)] +pub struct ResolvedOpInstance { + /// Name of the op-group this instance belongs to. + pub group: Symbol, + /// Existential placeholders (declared via `type = [...]` in TOML), without the `$` prefix. + pub free: BTreeSet, + /// Post-expansion strings for meta-var bindings (e.g. `T` → `"std::sync::Mutex<$1>"`). + pub types: BTreeMap, + /// Post-expansion strings for op-name bindings (e.g. `lock` → `"std::sync::Mutex<$1>::lock"`). + pub paths: BTreeMap, +} + +/// A collection of resolved op-group instances, keyed by group name. +/// +/// Uses `FxHashMap` (rustc's deterministic hasher) so diagnostic ordering and +/// iteration order are stable across runs. +#[derive(Debug, Default)] +pub struct OpsConfig { + pub instances: FxHashMap>, +} + +/// A single (group-name → resolved instance) assignment built from one element +/// of the cartesian product over op-group instance vectors. +/// +/// Passed from the driver's cartesian loop into `CheckMirCtxt` so that the +/// matcher (Task 12) can substitute concrete types/paths for `OpRef` operands. +#[derive(Debug, Clone, Default)] +pub struct ResolvedOpBindings { + pub by_group: FxHashMap, +} + +impl ResolvedOpBindings { + /// Build bindings from parallel slices of group names and cloned instances. + pub fn from_combo(groups: &[Symbol], combo: Vec<&ResolvedOpInstance>) -> Self { + let by_group = groups.iter().copied().zip(combo.into_iter().cloned()).collect(); + ResolvedOpBindings { by_group } + } + + /// The empty binding set — used when a pattern references no op groups. + pub fn empty() -> Self { + ResolvedOpBindings { + by_group: FxHashMap::default(), + } + } + + /// Look up the instance bound to `group`, if any. + pub fn get(&self, group: &Symbol) -> Option<&ResolvedOpInstance> { + self.by_group.get(group) + } +} + +impl OpsConfig { + /// Returns the slice of resolved instances for the named group, or `&[]` if none exist. + pub fn instances_of(&self, group: &str) -> &[ResolvedOpInstance] { + self.instances + .get(&Symbol::intern(group)) + .map(|v| v.as_slice()) + .unwrap_or(&[]) + } +} + +/// A diagnostic emitted during op-instance resolution. +/// +/// Each variant corresponds to one of the C2–C7 checks described in the spec +/// (Section 4, "Config schema and substitution"). +#[derive(Debug)] +pub enum ResolveDiagnostic { + /// C1 / unknown group: the TOML references a group not declared in the `.rpl` file. + UnknownGroup { group: String }, + /// C2 / C3: a meta-var or op binding required by the group is absent from the instance. + MissingBinding { group: String, name: String }, + /// C4: the instance contains a key that is not a declared meta-var or op name. + UnknownKey { group: String, name: String }, + /// C5: after expansion, a `$` remains that is neither in `free` nor a meta-var. + UndeclaredPlaceholder { + group: String, + name: String, + in_value: String, + }, + /// C7: the meta-var bindings form a cycle (did not converge in 16 passes). + Cycle { group: String, names: Vec }, + /// C6: the post-expansion string could not be parsed (placeholder for matcher-time check). + ParseFailure { + group: String, + key: String, + message: String, + }, +} + +/// Resolve raw op instances from `rpl.toml` into a typed [`OpsConfig`]. +/// +/// For each instance, validation checks C2–C7 are run in order. Instances that +/// fail any check are skipped (their diagnostic is pushed into the returned +/// `Vec`). Good instances are collected into the returned +/// [`OpsConfig`]. +/// +/// **Deferred-parse note (Step 5):** binding values are stored as post-expansion +/// strings rather than typed `Ty<'pcx>` / `Path<'pcx>`. C6 (parse-clean check) +/// is therefore deferred to match time; if a string fails to parse there, the +/// matcher will surface a runtime error. +pub fn resolve_ops_config( + pattern: &Pattern<'_>, + raw: &[(String, Vec)], +) -> (OpsConfig, Vec) { + let mut diagnostics = Vec::new(); + let mut instances: FxHashMap> = FxHashMap::default(); + + for (group_name, raw_instances) in raw { + let group_sym = Symbol::intern(group_name); + let group = match pattern.ops_block.groups.get(&group_sym) { + Some(g) => g, + None => { + diagnostics.push(ResolveDiagnostic::UnknownGroup { + group: group_name.clone(), + }); + continue; + }, + }; + + for raw_inst in raw_instances { + match resolve_one(group_name, group, raw_inst) { + Ok(resolved) => { + instances.entry(group_sym).or_default().push(resolved); + }, + Err(diag) => diagnostics.push(diag), + } + } + } + + (OpsConfig { instances }, diagnostics) +} + +// --------------------------------------------------------------------------- +// Internal helpers +// --------------------------------------------------------------------------- + +fn resolve_one( + group_name: &str, + group: &crate::pat::OpGroup<'_>, + raw: &rpl_config::RawOpInstance, +) -> Result { + // C2: every type meta-var declared in the group must have a binding. + for ty_var in &group.meta_vars.ty_vars { + let bare_name = ty_var.name.as_str().trim_start_matches('$'); + if !raw.bindings.contains_key(bare_name) { + return Err(ResolveDiagnostic::MissingBinding { + group: group_name.to_string(), + name: bare_name.to_string(), + }); + } + } + + // C3: every op declared in the group must have a binding. + for op_name in group.ops.keys() { + if !raw.bindings.contains_key(op_name.as_str()) { + return Err(ResolveDiagnostic::MissingBinding { + group: group_name.to_string(), + name: op_name.as_str().to_string(), + }); + } + } + + // C4: no extra keys beyond declared meta-vars and op names. + let known_keys: BTreeSet<&str> = group + .meta_vars + .ty_vars + .iter() + .map(|tv| tv.name.as_str().trim_start_matches('$')) + .chain(group.ops.keys().map(|s| s.as_str())) + .collect(); + + for k in raw.bindings.keys() { + if !known_keys.contains(k.as_str()) { + return Err(ResolveDiagnostic::UnknownKey { + group: group_name.to_string(), + name: k.clone(), + }); + } + } + + // Build the set of meta-var bare names for expansion. + let meta_var_names: BTreeSet = group + .meta_vars + .ty_vars + .iter() + .map(|tv| tv.name.as_str().trim_start_matches('$').to_string()) + .collect(); + + // Free placeholder names from `type = [...]`, stripped of leading `$`. + let free_names: BTreeSet = raw.free.iter().map(|s| s.trim_start_matches('$').to_string()).collect(); + + // C5/C7: fixed-point textual expansion of meta-var `$` references. + // + // Up to 16 passes. If no convergence after 16 → cycle (C7). + // After convergence, any residual `$` whose is a meta-var name + // (i.e. *should* have been substituted away) means there was a cycle even + // before the bound was hit — we treat this as C7 as well. + // Residual `$` whose is in `free_names` are existential placeholders + // (valid). Anything else is C5 (undeclared placeholder). + let mut expanded: BTreeMap = raw.bindings.clone(); + let mut converged = false; + for _iter in 0..16 { + let mut changed = false; + let snapshot: BTreeMap = expanded.clone(); + for (_key, val) in expanded.iter_mut() { + let new_val = expand_one(val, &snapshot, &meta_var_names); + if new_val != *val { + *val = new_val; + changed = true; + } + } + if !changed { + converged = true; + break; + } + } + + if !converged { + return Err(ResolveDiagnostic::Cycle { + group: group_name.to_string(), + names: expanded.keys().cloned().collect(), + }); + } + + // Post-convergence: scan for residual `$` placeholders. + // - In free_names → OK (existential) + // - In meta_var_names → cycle (should have been substituted; see note above) + // - Otherwise → undeclared placeholder (C5) + for (key, val) in &expanded { + for placeholder in collect_placeholders(val) { + if meta_var_names.contains(&placeholder) { + // Still present after convergence → cycle in disguise. + return Err(ResolveDiagnostic::Cycle { + group: group_name.to_string(), + names: vec![key.clone(), placeholder], + }); + } + if !free_names.contains(&placeholder) { + return Err(ResolveDiagnostic::UndeclaredPlaceholder { + group: group_name.to_string(), + name: placeholder, + in_value: val.clone(), + }); + } + } + } + + // Build the output maps. + let mut types: BTreeMap = BTreeMap::new(); + for ty_var in &group.meta_vars.ty_vars { + let bare = ty_var.name.as_str().trim_start_matches('$'); + let s = expanded.get(bare).expect("validated above").clone(); + types.insert(Symbol::intern(bare), s); + } + + let mut paths: BTreeMap = BTreeMap::new(); + for op_name in group.ops.keys() { + let s = expanded.get(op_name.as_str()).expect("validated above").clone(); + paths.insert(*op_name, s); + } + + Ok(ResolvedOpInstance { + group: Symbol::intern(group_name), + free: free_names.iter().map(|s| Symbol::intern(s)).collect(), + types, + paths, + }) +} + +/// Perform one pass of meta-var expansion over `value`. +/// +/// Replaces every `$` token where `` is in `meta_vars` with the +/// corresponding entry from `bindings`. Other `$` tokens (free +/// placeholders, undeclared names) are left intact. +fn expand_one(value: &str, bindings: &BTreeMap, meta_vars: &BTreeSet) -> String { + let mut out = String::with_capacity(value.len()); + let mut chars = value.chars().peekable(); + while let Some(c) = chars.next() { + if c == '$' { + let mut id = String::new(); + while let Some(&nc) = chars.peek() { + if nc.is_alphanumeric() || nc == '_' { + id.push(nc); + chars.next(); + } else { + break; + } + } + if meta_vars.contains(&id) { + // Substitute meta-var → its binding value. + out.push_str(bindings.get(&id).map(String::as_str).unwrap_or("")); + } else { + // Free placeholder or undeclared name — leave as-is. + out.push('$'); + out.push_str(&id); + } + } else { + out.push(c); + } + } + out +} + +/// Collect all `$` placeholder names (without the `$`) in `value`. +fn collect_placeholders(value: &str) -> Vec { + let mut out = Vec::new(); + let mut chars = value.chars().peekable(); + while let Some(c) = chars.next() { + if c == '$' { + let mut id = String::new(); + while let Some(&nc) = chars.peek() { + if nc.is_alphanumeric() || nc == '_' { + id.push(nc); + chars.next(); + } else { + break; + } + } + if !id.is_empty() { + out.push(id); + } + } + } + out +} diff --git a/crates/rpl_context/src/pat/ops_uses.rs b/crates/rpl_context/src/pat/ops_uses.rs new file mode 100644 index 00000000..c557d4f9 --- /dev/null +++ b/crates/rpl_context/src/pat/ops_uses.rs @@ -0,0 +1,149 @@ +/// Post-lowering use-site checks for `ops { ... }` references (R4–R5) and +/// `referenced_op_groups` collection. +/// +/// These checks operate on the already-lowered `Pattern<'pcx>` IR. They run +/// **after** `add_ops_block` and `add_pattern_item` have been called, so the +/// `ops_block.groups` map and all `RustItems`/`FnPatternBody` are in their +/// final state. +/// +/// # Rules +/// +/// | # | Rule | +/// |---|------| +/// | R4 | Every `$group::$op` operand resolves to a declared op group and op. | +/// | R5 | The number of arguments at the call site matches the op signature's arity. | +use rustc_data_structures::fx::FxHashSet; +use rustc_span::Symbol; + +use crate::pat::{BasicBlockData, FnPatternBody, FnPatterns, Operand, OpsBlock, RustItems, TerminatorKind}; + +// --------------------------------------------------------------------------- +// Public error type +// --------------------------------------------------------------------------- + +/// A use-site well-formedness violation for `$group::$op` references. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct OpsUseError { + pub message: String, +} + +impl OpsUseError { + fn new(message: impl Into) -> Self { + Self { + message: message.into(), + } + } +} + +impl std::fmt::Display for OpsUseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message) + } +} + +// --------------------------------------------------------------------------- +// Public entry point +// --------------------------------------------------------------------------- + +/// Walk all function bodies in `items` looking for `Operand::OpRef` call +/// targets. For each one: +/// +/// 1. **(R4a)** Check that `group` is declared in `ops_block.groups`. +/// 2. **(R4b)** Check that `op` is declared within that group. +/// 3. **(R5)** Check that the call-site argument count matches the op signature's parameter count. +/// +/// Also collects every group name referenced by a (potentially invalid) OpRef +/// into `referenced_groups`, which is used to populate +/// `RustItems::referenced_op_groups`. +/// +/// Returns a (possibly empty) list of R4/R5 errors. +pub fn check_op_refs( + items: &RustItems<'_>, + ops_block: &OpsBlock<'_>, + referenced_groups: &mut FxHashSet, +) -> Vec { + let mut errors = Vec::new(); + check_fn_patterns(&items.fns, ops_block, referenced_groups, &mut errors); + errors +} + +// --------------------------------------------------------------------------- +// Internal helpers +// --------------------------------------------------------------------------- + +fn check_fn_patterns( + fns: &FnPatterns<'_>, + ops_block: &OpsBlock<'_>, + referenced_groups: &mut FxHashSet, + errors: &mut Vec, +) { + for fn_pat in fns { + if let Some(body) = fn_pat.body { + check_fn_body(body, ops_block, referenced_groups, errors); + } + } +} + +fn check_fn_body( + body: &FnPatternBody<'_>, + ops_block: &OpsBlock<'_>, + referenced_groups: &mut FxHashSet, + errors: &mut Vec, +) { + for bb_data in body.basic_blocks.iter() { + check_basic_block(bb_data, ops_block, referenced_groups, errors); + } +} + +fn check_basic_block( + bb_data: &BasicBlockData<'_>, + ops_block: &OpsBlock<'_>, + referenced_groups: &mut FxHashSet, + errors: &mut Vec, +) { + // We only need to look at terminators; OpRef appears as the `func` operand + // of a Call terminator (never in a statement rvalue). + if let Some(TerminatorKind::Call { + func: Operand::OpRef { group, op }, + args, + .. + }) = &bb_data.terminator + { + // Record the group name (even if invalid — callers may want the + // full list for diagnostics). + referenced_groups.insert(*group); + + // R4a: group must be declared. + let Some(op_group) = ops_block.groups.get(group) else { + errors.push(OpsUseError::new(format!( + "op group '{}' is not declared", + group.as_str() + ))); + return; + }; + + // R4b: op must be declared within the group. + let Some(op_sig) = op_group.ops.get(op) else { + errors.push(OpsUseError::new(format!( + "op '{}' is not declared in op group '{}'", + op.as_str(), + group.as_str() + ))); + return; + }; + + // R5: arity check. + let expected = op_sig.params.len(); + let got = args.len(); + if expected != got { + errors.push(OpsUseError::new(format!( + "arity mismatch for op '{}::{}': expected {} arg{}, got {}", + group.as_str(), + op.as_str(), + expected, + if expected == 1 { "" } else { "s" }, + got + ))); + } + } +} diff --git a/crates/rpl_context/src/pat/ops_wf.rs b/crates/rpl_context/src/pat/ops_wf.rs new file mode 100644 index 00000000..66e5d561 --- /dev/null +++ b/crates/rpl_context/src/pat/ops_wf.rs @@ -0,0 +1,567 @@ +/// Well-formedness checks for `ops { ... }` blocks (R1–R3). +/// +/// These checks operate on the raw pest parse-tree and must run **before** any +/// lowering function (`NonLocalMetaVars::from_meta_decls`, `Ty::from`, etc.) is +/// called, because the lowering code uses `unreachable!()` contracts that assume +/// the input has already been validated. +/// +/// # Rules +/// +/// | # | Rule | +/// |---|------| +/// | R1 | Every meta-var in an op group's `MetaVariableDeclList` must be of kind `type`. | +/// | R2 | Op signatures may only reference meta-vars that are declared in the same op group. | +/// | R3 | Op signatures must not contain concrete Rust types (concrete paths or primitive types). | +use std::collections::HashSet; +use std::ops::Deref; + +use rpl_meta::collect_elems_separated_by_comma; +use rpl_parser::generics::{Choice2, Choice3, Choice14}; +use rpl_parser::pairs; + +// --------------------------------------------------------------------------- +// Public error type +// --------------------------------------------------------------------------- + +/// A well-formedness violation found in an `ops { ... }` block. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct OpsWfError { + pub group: String, + pub message: String, +} + +impl OpsWfError { + fn new(group: impl Into, message: impl Into) -> Self { + Self { + group: group.into(), + message: message.into(), + } + } +} + +impl std::fmt::Display for OpsWfError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "[ops group '{}'] {}", self.group, self.message) + } +} + +// --------------------------------------------------------------------------- +// Public entry point +// --------------------------------------------------------------------------- + +/// Check every `opsItem` in `block` for R1, R2, and R3 violations. +/// +/// Returns a (possibly empty) list of errors. A non-empty return value means +/// that the corresponding `opsItem`(s) should **not** be lowered. +pub fn check_ops_block(block: &pairs::opsBlock<'_>) -> Vec { + let mut errors = Vec::new(); + for item in block.opsItem() { + check_ops_item(item, &mut errors); + } + errors +} + +// --------------------------------------------------------------------------- +// Per-item checks +// --------------------------------------------------------------------------- + +fn check_ops_item(item: &pairs::opsItem<'_>, errors: &mut Vec) { + let group_name = item.Identifier().span.as_str(); + let meta_decl_list = item.MetaVariableDeclList(); + + // -- R1: collect declared type-var names and flag non-type vars. + let declared_type_vars = collect_declared_type_vars(group_name, meta_decl_list, errors); + + // -- R2 + R3: walk each OpFnDecl signature. + for decl in item.OpFnDecl() { + let sig = decl.OpFnSig(); + check_op_sig(group_name, sig, &declared_type_vars, errors); + } +} + +/// Pre-scan `MetaVariableDeclList`, collect names of `type`-kind vars, and +/// emit R1 errors for any non-`type`-kind var. +/// +/// Returns the list of declared `type`-kind meta-var names (with `$` prefix, +/// as they appear in the source). +fn collect_declared_type_vars<'i>( + group_name: &str, + meta_decl_list: Option<&'i pairs::MetaVariableDeclList<'i>>, + errors: &mut Vec, +) -> Vec<&'i str> { + let mut type_var_names: Vec<&'i str> = Vec::new(); + + let Some(mdl) = meta_decl_list else { + return type_var_names; + }; + let Some(inner) = mdl.get_matched().1 else { + return type_var_names; + }; + + for decl in collect_elems_separated_by_comma!(inner) { + let (ident, _, ty, _) = decl.get_matched(); + let var_name = ident.span.as_str(); // includes `$` + + match ty.deref() { + Choice3::_0(_type_kind) => { + // R1 OK — type-kind meta-var. + type_var_names.push(var_name); + }, + Choice3::_1(_const_kind) => { + // R1 violation: const-kind. + errors.push(OpsWfError::new( + group_name, + format!( + "op-level meta-var '{}' must be of kind 'type' \ + (only 'type' is supported in v1)", + var_name + ), + )); + }, + Choice3::_2(_place_kind) => { + // R1 violation: place-kind. + errors.push(OpsWfError::new( + group_name, + format!( + "op-level meta-var '{}' must be of kind 'type' \ + (only 'type' is supported in v1)", + var_name + ), + )); + }, + } + } + + type_var_names +} + +/// Check a single `OpFnSig` for R2 (undeclared meta-var references) and +/// R3 (concrete type references). +fn check_op_sig(group_name: &str, sig: &pairs::OpFnSig<'_>, declared_type_vars: &[&str], errors: &mut Vec) { + // Walk parameters. + if let Some(params_pair) = sig.OpFnParamsSeparatedByComma() { + let (first, rest) = params_pair.OpFnParam(); + let params: Vec<_> = std::iter::once(first).chain(rest).collect(); + for param in params { + if let Some(ty) = param_type(param) { + check_type(group_name, ty, declared_type_vars, errors); + } + } + } + + // Walk return type. + if let Some(fn_ret) = sig.FnRet() { + let (_, placeholder_or_ty) = fn_ret.get_matched(); + if let Choice2::_1(ty) = placeholder_or_ty { + check_type(group_name, ty, declared_type_vars, errors); + } + } +} + +/// Extract the `Type` node from an `OpFnParam`, if any. +/// +/// `OpFnParam` alternatives: +/// - `SelfParam` — no `Type` node to check (the self type is implicit) +/// - `NormalParam` — has a `Type` +/// - `PlaceHolderWithType` — has a `Type` +/// - `Type` — IS the `Type` +/// - `Dot2` — variadic `..`, no type +fn param_type<'a>(param: &'a pairs::OpFnParam<'a>) -> Option<&'a pairs::Type<'a>> { + // SelfParam — skip (self receiver, no explicit type to validate) + if param.SelfParam().is_some() { + return None; + } + // NormalParam: `$name: Type` + if let Some(normal) = param.NormalParam() { + let (_, _, _, ty) = normal.get_matched(); + return Some(ty); + } + // PlaceHolderWithType: `_: Type` + if let Some(ph_with_ty) = param.PlaceHolderWithType() { + let (_, _, _, ty) = ph_with_ty.get_matched(); + return Some(ty); + } + // Bare `Type` param (e.g. `&mut $T`) + if let Some(ty) = param.Type() { + return Some(ty); + } + // Dot2 — variadic + None +} + +/// Recursively walk a `Type` node to check R2 and R3. +/// +/// - R2: if a `TypeMetaVariable` is found whose name is not in `declared_type_vars`, emit an error. +/// - R3: if a `TypePath` or `PrimitiveType` leaf is found, emit an error. +/// +/// Wrapper types (`TypeReference`, `TypePtr`, `TypeSlice`, `TypeTuple`, +/// `TypeArray`, `TypeGroup`, `TypeParen`) are traversed without error. +/// `TypeNever`, `PlaceHolder` (`_`), and `kw_Self` are silently accepted. +fn check_type(group_name: &str, ty: &pairs::Type<'_>, declared_type_vars: &[&str], errors: &mut Vec) { + match ty.deref() { + // Wrapping types — recurse into the inner type(s). + Choice14::_0(ty_array) => { + let (_, inner, _, _, _) = ty_array.get_matched(); + check_type(group_name, inner, declared_type_vars, errors); + }, + Choice14::_1(ty_group) => { + let (_, inner) = ty_group.get_matched(); + check_type(group_name, inner, declared_type_vars, errors); + }, + Choice14::_2(_ty_never) => { + // `!` — accept (rare, but abstract) + }, + Choice14::_3(ty_paren) => { + let (_, inner, _) = ty_paren.get_matched(); + check_type(group_name, inner, declared_type_vars, errors); + }, + Choice14::_4(ty_ptr) => { + let (_, _, inner) = ty_ptr.get_matched(); + check_type(group_name, inner, declared_type_vars, errors); + }, + Choice14::_5(ty_ref) => { + let (_, _, _, inner) = ty_ref.get_matched(); + check_type(group_name, inner, declared_type_vars, errors); + }, + Choice14::_6(ty_slice) => { + let (_, inner, _) = ty_slice.get_matched(); + check_type(group_name, inner, declared_type_vars, errors); + }, + Choice14::_7(ty_tuple) => { + let (_, tys_opt, _) = ty_tuple.get_matched(); + if let Some(tys) = tys_opt { + let tys_vec = collect_elems_separated_by_comma!(tys).collect::>(); + for inner in tys_vec { + check_type(group_name, inner, declared_type_vars, errors); + } + } + }, + // Meta-variable reference — R2 check. + Choice14::_8(ty_meta_var) => { + // The span text is the raw `$Name` including the `$`. + let var_name = ty_meta_var.span.as_str(); + if !declared_type_vars.contains(&var_name) { + errors.push(OpsWfError::new( + group_name, + format!( + "op-level meta-var '{}' is not declared in op group '{}'", + var_name, group_name + ), + )); + } + }, + // `Self` — silently accepted. + Choice14::_9(_kw_self) => {}, + // PrimitiveType — R3 violation (concrete built-in type). + Choice14::_10(prim) => { + errors.push(OpsWfError::new( + group_name, + format!( + "ops blocks must use op-level meta-vars only — concrete types belong \ + in rpl.toml (found primitive type '{}')", + prim.span.as_str() + ), + )); + }, + // PlaceHolder (`_`) — accepted (wildcard / anonymous). + Choice14::_11(_placeholder) => {}, + // TypePath — R3 violation (concrete Rust path). + Choice14::_12(ty_path) => { + errors.push(OpsWfError::new( + group_name, + format!( + "ops blocks must use op-level meta-vars only — concrete types belong \ + in rpl.toml (found path '{}')", + ty_path.span.as_str() + ), + )); + }, + // LangItemWithArgs — R3 violation (concrete lang-item reference). + Choice14::_13(lang_item) => { + errors.push(OpsWfError::new( + group_name, + format!( + "ops blocks must use op-level meta-vars only — concrete types belong \ + in rpl.toml (found lang item '{}')", + lang_item.span.as_str() + ), + )); + }, + } +} + +// --------------------------------------------------------------------------- +// R6: Op-level meta-vars must not appear in pattern bodies +// --------------------------------------------------------------------------- + +/// Check every `pattBlock` item in `patts` against the op-level meta-var +/// names collected from `ops_blocks`. +/// +/// For each pattern item `p[...] = ...`: +/// 1. Collect the pattern-level declared meta-var names (those in `p[...]`). +/// 2. Collect all op-level meta-var names across all op groups. +/// 3. Walk every `TypeMetaVariable` in the item's RHS. +/// 4. If a type meta-var's name is in the op-level set but NOT in the pattern-level set, emit an R6 +/// error: `"op-level meta-var '$T' cannot appear in a pattern body"`. +/// +/// Returns a flat list of all R6 errors found. +pub fn check_r6_patt_vs_ops(ops_blocks: &[&pairs::opsBlock<'_>], patts: &[&pairs::pattBlock<'_>]) -> Vec { + // Collect all op-level meta-var names (with `$` prefix) across all groups. + let op_level_names: HashSet<&str> = collect_all_op_meta_var_names(ops_blocks); + + let mut errors = Vec::new(); + for patt_block in patts { + for item in patt_block.RPLPatternItem() { + let item_name = item.Identifier().span.as_str(); + // Collect pattern-level declared meta-var names. + let pattern_level_names: HashSet<&str> = collect_pattern_meta_var_names(item.MetaVariableDeclList()); + + // Walk the item body for TypeMetaVariable references. + let rhs = item.RustItemsOrPatternOperation(); + let mut collector = TypeMetaVarCollector::default(); + collect_type_meta_vars_in_rhs(rhs, &mut collector); + + for name in collector.names { + if op_level_names.contains(name) && !pattern_level_names.contains(name) { + errors.push(OpsWfError::new( + item_name, + format!("op-level meta-var '{}' cannot appear in a pattern body", name), + )); + } + } + } + } + errors +} + +/// Collect all type meta-var names (with `$`) declared in ANY op group across +/// all `opsBlock`s. +fn collect_all_op_meta_var_names<'i>(ops_blocks: &[&pairs::opsBlock<'i>]) -> HashSet<&'i str> { + let mut names = HashSet::new(); + for ops_block in ops_blocks { + for item in ops_block.opsItem() { + if let Some(mdl) = item.MetaVariableDeclList() + && let Some(inner) = mdl.get_matched().1 + { + for decl in collect_elems_separated_by_comma!(inner) { + let (ident, _, ty, _) = decl.get_matched(); + // Only type-kind vars are relevant for R6 (R1 already + // rejects non-type vars; we include them anyway for a + // conservative check). + if matches!(ty.deref(), Choice3::_0(_)) { + names.insert(ident.span.as_str()); + } + } + } + } + } + names +} + +/// Collect all meta-var names (with `$`) declared in a +/// `MetaVariableDeclList` (the `[...]` bracket of a pattern item). +fn collect_pattern_meta_var_names<'i>(meta_decl_list: Option<&'i pairs::MetaVariableDeclList<'i>>) -> HashSet<&'i str> { + let mut names = HashSet::new(); + if let Some(mdl) = meta_decl_list + && let Some(inner) = mdl.get_matched().1 + { + for decl in collect_elems_separated_by_comma!(inner) { + let (ident, _, _, _) = decl.get_matched(); + names.insert(ident.span.as_str()); + } + } + names +} + +// --------------------------------------------------------------------------- +// TypeMetaVariable collector for R6 +// --------------------------------------------------------------------------- + +/// Accumulates every `TypeMetaVariable` span text found in a parse sub-tree. +#[derive(Default)] +struct TypeMetaVarCollector<'i> { + names: Vec<&'i str>, +} + +/// Entry point: walk `RustItemsOrPatternOperation` collecting all +/// `TypeMetaVariable` references. +/// +/// We do a best-effort recursive walk over the parts of the grammar that can +/// contain `Type` nodes (function signatures and MIR bodies). We deliberately +/// do NOT walk pattern-operation sub-expressions (they reference util items by +/// name, not types directly). +fn collect_type_meta_vars_in_rhs<'i>( + rhs: &'i pairs::RustItemsOrPatternOperation<'i>, + collector: &mut TypeMetaVarCollector<'i>, +) { + use rpl_parser::generics::Choice3; + match rhs.deref() { + Choice3::_0(single_item) => collect_in_rust_item_with_constraint(single_item, collector), + Choice3::_1(items_block) => { + let (_, items, _) = items_block.get_matched(); + for item in items.iter_matched() { + collect_in_rust_item_with_constraint(item, collector); + } + }, + Choice3::_2(_patt_op) => { + // PatternOperation references util items by name; no Type nodes to + // walk here. + }, + } +} + +fn collect_in_rust_item_with_constraint<'i>( + item: &'i pairs::RustItemWithConstraint<'i>, + collector: &mut TypeMetaVarCollector<'i>, +) { + use rpl_parser::generics::Choice4; + let (_, inner, _where_block) = item.get_matched(); + match inner.deref() { + Choice4::_0(rust_fn) => collect_in_fn(rust_fn, collector), + Choice4::_1(_struct) => { /* struct fields not yet scanned for R6 */ }, + Choice4::_2(_enum) => { /* enum variants not yet scanned for R6 */ }, + Choice4::_3(_impl) => { /* impl fns not yet scanned for R6 */ }, + } +} + +fn collect_in_fn<'i>(rust_fn: &'i pairs::Fn<'i>, collector: &mut TypeMetaVarCollector<'i>) { + let (sig, body) = rust_fn.get_matched(); + collect_in_fn_sig(sig, collector); + if let Some(mir_body) = body.MirBody() { + collect_in_mir_body(mir_body, collector); + } +} + +fn collect_in_fn_sig<'i>(sig: &'i pairs::FnSig<'i>, collector: &mut TypeMetaVarCollector<'i>) { + // Walk parameters. + if let Some(params) = sig.FnParamsSeparatedByComma() { + let (first, rest) = params.FnParam(); + for param in std::iter::once(first).chain(rest) { + collect_in_fn_param(param, collector); + } + } + // Walk return type. + if let Some(fn_ret) = sig.FnRet() { + let (_, placeholder_or_ty) = fn_ret.get_matched(); + if let Choice2::_1(ty) = placeholder_or_ty { + collect_in_type(ty, collector); + } + } +} + +fn collect_in_fn_param<'i>(param: &'i pairs::FnParam<'i>, collector: &mut TypeMetaVarCollector<'i>) { + use rpl_parser::generics::Choice4; + match param.deref() { + Choice4::_0(_self_param) => { /* self — no explicit type to check */ }, + Choice4::_1(normal) => { + let (_, _, _, ty) = normal.get_matched(); + collect_in_type(ty, collector); + }, + Choice4::_2(ph_with_ty) => { + let (_, _, _, ty) = ph_with_ty.get_matched(); + collect_in_type(ty, collector); + }, + Choice4::_3(_ellipsis) => {}, + } +} + +fn collect_in_mir_body<'i>(body: &'i pairs::MirBody<'i>, collector: &mut TypeMetaVarCollector<'i>) { + let (decls, stmts) = body.get_matched(); + for decl in decls.iter_matched() { + collect_in_mir_decl(decl, collector); + } + for stmt in stmts.iter_matched() { + collect_in_mir_stmt(stmt, collector); + } +} + +fn collect_in_mir_decl<'i>(decl: &'i pairs::MirDecl<'i>, collector: &mut TypeMetaVarCollector<'i>) { + // MirDecl has two accessor methods: MirTypeDecl() and MirLocalDecl() + if let Some(local_decl) = decl.MirLocalDecl() { + // `let $x: Type = ...` — the declared type may reference a meta-var + let ty = local_decl.Type(); + collect_in_type(ty, collector); + } + // MirTypeDecl (type aliases) don't carry op-level meta-var leaks we care about. +} + +fn collect_in_mir_stmt<'i>(stmt: &'i pairs::MirStmt<'i>, collector: &mut TypeMetaVarCollector<'i>) { + // Use the accessor methods on MirStmt rather than deref/match. + // Cast rvalues are the only place type meta-vars can appear in statements. + if let Some(assign) = stmt.MirAssign() { + let rvalue_or_call = assign.MirRvalueOrCall(); + use rpl_parser::generics::Choice2; + match rvalue_or_call.deref() { + Choice2::_0(_call) => {}, + Choice2::_1(rvalue) => collect_in_mir_rvalue(rvalue, collector), + } + } +} + +fn collect_in_mir_rvalue<'i>(rvalue: &'i pairs::MirRvalue<'i>, collector: &mut TypeMetaVarCollector<'i>) { + use rpl_parser::generics::Choice12; + match rvalue.deref() { + Choice12::_1(cast) => { + // `operand as Type (cast_kind)` — the target type may reference meta-vars + let (_operand, _, ty, _, _cast_kind, _) = cast.get_matched(); + collect_in_type(ty, collector); + }, + // All other rvalue forms don't carry explicit Type annotations in a + // way that would allow op-level meta-var leaks. + _ => {}, + } +} + +/// Recursively walk a `Type` parse node, pushing any `TypeMetaVariable` +/// span text into `collector.names`. +fn collect_in_type<'i>(ty: &'i pairs::Type<'i>, collector: &mut TypeMetaVarCollector<'i>) { + match ty.deref() { + Choice14::_0(ty_array) => { + let (_, inner, _, _, _) = ty_array.get_matched(); + collect_in_type(inner, collector); + }, + Choice14::_1(ty_group) => { + let (_, inner) = ty_group.get_matched(); + collect_in_type(inner, collector); + }, + Choice14::_2(_ty_never) => {}, + Choice14::_3(ty_paren) => { + let (_, inner, _) = ty_paren.get_matched(); + collect_in_type(inner, collector); + }, + Choice14::_4(ty_ptr) => { + let (_, _, inner) = ty_ptr.get_matched(); + collect_in_type(inner, collector); + }, + Choice14::_5(ty_ref) => { + let (_, _, _, inner) = ty_ref.get_matched(); + collect_in_type(inner, collector); + }, + Choice14::_6(ty_slice) => { + let (_, inner, _) = ty_slice.get_matched(); + collect_in_type(inner, collector); + }, + Choice14::_7(ty_tuple) => { + let (_, tys_opt, _) = ty_tuple.get_matched(); + if let Some(tys) = tys_opt { + let tys_vec = collect_elems_separated_by_comma!(tys).collect::>(); + for inner in tys_vec { + collect_in_type(inner, collector); + } + } + }, + Choice14::_8(ty_meta_var) => { + // This is the key: collect the name with the `$` prefix. + collector.names.push(ty_meta_var.span.as_str()); + }, + Choice14::_9(_kw_self) => {}, + Choice14::_10(_prim) => {}, + Choice14::_11(_placeholder) => {}, + Choice14::_12(_ty_path) => {}, + Choice14::_13(_lang_item) => {}, + } +} + +// Well-formed-input coverage is provided by the integration tests in +// `tests/ops_lowering.rs` and `tests/ops_wf.rs`; no in-file unit tests are +// needed here. diff --git a/crates/rpl_context/tests/common/mod.rs b/crates/rpl_context/tests/common/mod.rs new file mode 100644 index 00000000..da6c723c --- /dev/null +++ b/crates/rpl_context/tests/common/mod.rs @@ -0,0 +1,64 @@ +//! Shared boilerplate for ops integration tests. +//! +//! Every test in this crate needs a `&'static MetaContext<'static>` so that +//! `PatternCtxt::entered_no_tcx` (which takes a re-entrant closure with no +//! bound lifetime) can accept it. The mechanical way to get that is +//! `Box::leak` plus a `'static`-lifetimed arena. +//! +//! Before this module existed, every test (8 occurrences across 4 files) +//! repeated the same 5-line boilerplate. This module collapses it to +//! `make_static_mctx("test.rpl", src)`. +//! +//! The arena is created once per integration-test binary via [`LazyLock`] and +//! shared across all `#[test]` functions in that binary. Each test still +//! parses its own source string and gets its own `MetaContext`; the savings +//! come from not creating (and leaking) a fresh `Arena` per test. + +#![allow(dead_code)] // not every test consumes every helper + +use std::path::PathBuf; +use std::sync::LazyLock; + +use rpl_meta::RPLMetaError; +use rpl_meta::arena::Arena; +use rpl_meta::context::MetaContext; + +/// Returns a shared, lazily-initialised `&'static Arena<'static>` for the +/// current integration-test binary. All tests in a binary share one arena; +/// the underlying allocation grows but is never freed (test process exit +/// reclaims it). +pub fn shared_arena() -> &'static Arena<'static> { + static ARENA: LazyLock<&'static Arena<'static>> = LazyLock::new(|| Box::leak(Box::>::default())); + *ARENA +} + +/// Parse `src` and return a `'static` [`MetaContext`]. +/// +/// Panics on any parse/collect error — use this when the test fixture is +/// intentionally well-formed and a failure indicates a fixture bug. +pub fn make_static_mctx(filename: &str, src: &str) -> &'static MetaContext<'static> { + make_static_mctx_with(filename, src, |err| { + panic!("RPL parse/collect error: {err}"); + }) +} + +/// Like [`make_static_mctx`] but lets the caller supply a custom error +/// handler. +/// +/// Used by tests that intentionally feed malformed input — e.g. R6 +/// fixtures that reference an undeclared pattern-level meta-var and need to +/// suppress the `NonLocalMetaVariableNotDeclared` error from +/// `parse_and_collect` so the R6 check itself can run. +pub fn make_static_mctx_with( + filename: &str, + src: &str, + handler: impl FnMut(&RPLMetaError<'static>), +) -> &'static MetaContext<'static> { + let path_and_content: &'static Vec<(PathBuf, String)> = + Box::leak(Box::new(vec![(PathBuf::from(filename), src.to_string())])); + Box::leak(Box::new(rpl_meta::parse_and_collect( + shared_arena(), + path_and_content, + handler, + ))) +} diff --git a/crates/rpl_context/tests/ops_lowering.rs b/crates/rpl_context/tests/ops_lowering.rs new file mode 100644 index 00000000..59c13b48 --- /dev/null +++ b/crates/rpl_context/tests/ops_lowering.rs @@ -0,0 +1,174 @@ +//! End-to-end lowering test: `ops { ... }` block populates `Pattern.ops_block`. +//! +//! Uses the full parse → collect → lower pipeline so we exercise the same code +//! path as the real driver. `Box::leak` is used to obtain `'static` arenas +//! that satisfy the lifetime requirements of `PatternCtxt::entered_no_tcx`. + +#![allow(internal_features)] +#![feature(rustc_private)] +#![feature(rustc_attrs)] +#![feature(let_chains)] +#![feature(box_patterns)] +#![feature(debug_closure_helpers)] +#![recursion_limit = "256"] + +extern crate rustc_data_structures; +extern crate rustc_span; + +use rpl_context::PatternCtxt; +use rustc_span::Symbol; + +mod common; +use common::make_static_mctx; + +/// Full-pipeline test: parse an RPL source string containing an `ops { ... }` +/// block and verify that the resulting `Pattern.ops_block` is populated with +/// the expected groups and operation names. +#[test] +fn lowering_populates_ops_block() { + let src = r#" +pattern test +ops { + sync[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + fn $unlock(&mut $U) -> _; + } +} +patt { + p[] = fn _ (..) -> _ { let $x: usize = _; } +} +"#; + + let mctx = make_static_mctx("test.rpl", src); + + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + + let mut found_sync = false; + pcx.for_each_rpl_pattern(|_, pattern| { + let groups = &pattern.ops_block.groups; + if groups.is_empty() { + return; + } + + // The `sync` group must be present. + let sync_group = groups + .get(&Symbol::intern("sync")) + .expect("sync op group should be lowered into ops_block.groups"); + + assert_eq!(sync_group.ops.len(), 2, "sync group should have exactly 2 ops"); + + assert!( + sync_group.ops.contains_key(&Symbol::intern("lock")), + "sync group should contain `lock` op (bare, no $ prefix)" + ); + assert!( + sync_group.ops.contains_key(&Symbol::intern("unlock")), + "sync group should contain `unlock` op (bare, no $ prefix)" + ); + + // Verify meta_vars: $T and $U are both type variables. + assert_eq!( + sync_group.meta_vars.ty_vars.len(), + 2, + "sync group should have 2 type meta-variables ($T, $U)" + ); + + found_sync = true; + }); + + assert!(found_sync, "No pattern with a sync ops group was found"); + }); +} + +/// Verify that two op groups within a single `ops { ... }` block are both +/// lowered into `Pattern.ops_block.groups`. +#[test] +fn lowering_multiple_op_groups_in_one_block() { + let src = r#" +pattern test +ops { + sync[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + } + alloc[$T: type] = { + fn $allocate(&mut $T) -> _; + } +} +patt { + p[] = fn _ (..) -> _ { let $x: usize = _; } +} +"#; + + let mctx = make_static_mctx("test_multi_groups.rpl", src); + + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + + let mut found = false; + pcx.for_each_rpl_pattern(|_, pattern| { + let groups = &pattern.ops_block.groups; + if groups.is_empty() { + return; + } + + assert_eq!(groups.len(), 2, "expected exactly 2 op groups"); + + let sync_group = groups + .get(&Symbol::intern("sync")) + .expect("sync op group should be present"); + assert_eq!(sync_group.ops.len(), 1, "sync group should have 1 op"); + assert!( + sync_group.ops.contains_key(&Symbol::intern("lock")), + "sync group should contain `lock` op" + ); + assert_eq!( + sync_group.meta_vars.ty_vars.len(), + 2, + "sync group should have 2 type meta-variables ($T, $U)" + ); + + let alloc_group = groups + .get(&Symbol::intern("alloc")) + .expect("alloc op group should be present"); + assert_eq!(alloc_group.ops.len(), 1, "alloc group should have 1 op"); + assert!( + alloc_group.ops.contains_key(&Symbol::intern("allocate")), + "alloc group should contain `allocate` op" + ); + assert_eq!( + alloc_group.meta_vars.ty_vars.len(), + 1, + "alloc group should have 1 type meta-variable ($T)" + ); + + found = true; + }); + + assert!(found, "No pattern with multiple ops groups was found"); + }); +} + +/// Verify that a pattern file with no `ops` block yields an empty +/// `ops_block.groups` map (not a crash or poison entry). +#[test] +fn no_ops_block_yields_empty_ops_block() { + let src = r#" +pattern test +patt { + p[] = fn _ (..) -> _ { let $x: usize = _; } +} +"#; + + let mctx = make_static_mctx("test_no_ops.rpl", src); + + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + pcx.for_each_rpl_pattern(|_, pattern| { + assert!( + pattern.ops_block.groups.is_empty(), + "pattern without ops block should have empty ops_block.groups" + ); + }); + }); +} diff --git a/crates/rpl_context/tests/ops_resolution.rs b/crates/rpl_context/tests/ops_resolution.rs new file mode 100644 index 00000000..49b3a8ab --- /dev/null +++ b/crates/rpl_context/tests/ops_resolution.rs @@ -0,0 +1,268 @@ +//! Substitution + validation tests for `resolve_ops_config`. +//! +//! Covers the five scenarios from Task 9 of the abstract-ops plan: +//! - Happy path: bindings expand cleanly, instance retained. +//! - C2: missing meta-var binding → warning, instance skipped. +//! - C4: unknown extra key → warning, instance skipped. +//! - C7: cyclic substitution → warning, instance skipped. +//! - Mixed good+bad instances: only the good one is retained. + +#![allow(internal_features)] +#![feature(rustc_private)] +#![feature(rustc_attrs)] +#![feature(let_chains)] +#![feature(box_patterns)] +#![feature(debug_closure_helpers)] +#![recursion_limit = "256"] + +extern crate rustc_data_structures; +extern crate rustc_span; + +use std::collections::BTreeMap; + +use rpl_config::RawOpInstance; +use rpl_context::PatternCtxt; +use rpl_context::pat::ops_resolved::{ResolveDiagnostic, resolve_ops_config}; +use rustc_span::Symbol; + +mod common; +use common::make_static_mctx; + +// --------------------------------------------------------------------------- +// Helper utilities +// --------------------------------------------------------------------------- + +/// Build a `RawOpInstance` from a list of free-placeholder names and key/value pairs. +fn instance(free: &[&str], pairs: &[(&str, &str)]) -> RawOpInstance { + RawOpInstance { + free: free.iter().map(|s| s.to_string()).collect(), + bindings: pairs + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect::>(), + } +} + +/// The RPL source shared by all tests — declares a `sync` group with two type +/// meta-vars ($T, $U) and two ops ($lock, $unlock). +const PATTERN_DECL: &str = r#" +pattern test +ops { + sync[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + fn $unlock(&mut $U) -> _; + } +} +patt { p[] = fn _ () -> _ {} } +"#; + +/// Parse the RPL source, lower it into a `Pattern`, then call the supplied +/// closure `f` with that pattern (inside `PatternCtxt::entered_no_tcx`). +/// +/// The arena and `MetaContext` are obtained via the shared helper in +/// `tests/common/mod.rs`, which leaks them into `'static` once per binary. +fn with_pattern FnMut(&rpl_context::pat::Pattern<'pcx>)>(src: &str, mut f: F) { + let mctx = make_static_mctx("test.rpl", src); + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + pcx.for_each_rpl_pattern(|_, pattern| { + f(pattern); + }); + }); +} + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +/// Happy path: all required bindings present, expansion converges, no residual +/// undeclared placeholders. `$T`/`$U` get expanded into the concrete path +/// strings; `$1` is a free placeholder and is left intact. +#[test] +fn happy_path_eager_expansion() { + with_pattern(PATTERN_DECL, |pattern| { + let raw = vec![( + "sync".to_string(), + vec![instance( + &["$1"], + &[ + ("T", "std::sync::Mutex<$1>"), + ("U", "std::sync::MutexGuard<$1>"), + ("lock", "$T::lock"), + ("unlock", "$U::drop"), + ], + )], + )]; + let (cfg, diags) = resolve_ops_config(pattern, &raw); + assert!( + diags.is_empty(), + "no diagnostics expected for happy path, got: {diags:?}" + ); + + let sync = cfg.instances_of("sync"); + assert_eq!(sync.len(), 1, "expected exactly one resolved instance"); + + let inst = &sync[0]; + + // After expansion, `lock` should contain "Mutex", "$1", and "lock". + let lock_val = inst.paths.get(&Symbol::intern("lock")).unwrap(); + assert!( + lock_val.contains("Mutex"), + "expanded lock path should reference Mutex, got: {lock_val}" + ); + assert!( + lock_val.contains("$1"), + "expanded lock path should retain free placeholder $1, got: {lock_val}" + ); + assert!( + lock_val.contains("lock"), + "expanded lock path should contain 'lock', got: {lock_val}" + ); + + // T should expand to the Mutex string. + let t_val = inst.types.get(&Symbol::intern("T")).unwrap(); + assert!( + t_val.contains("Mutex"), + "T type should expand to Mutex<$1>, got: {t_val}" + ); + assert!( + t_val.contains("$1"), + "T type should retain $1 placeholder, got: {t_val}" + ); + }); +} + +/// C2: when a required meta-var binding is absent from the instance, the +/// resolver emits a `MissingBinding` diagnostic and skips the instance. +#[test] +fn c2_missing_meta_var_binding_warns_and_skips() { + with_pattern(PATTERN_DECL, |pattern| { + let raw = vec![( + "sync".to_string(), + vec![instance( + &["$1"], + &[ + // "T" binding is deliberately absent. + ("U", "std::sync::MutexGuard<$1>"), + ("lock", "$U::lock"), + ("unlock", "$U::drop"), + ], + )], + )]; + let (cfg, diags) = resolve_ops_config(pattern, &raw); + + assert!( + matches!(&diags[..], [ResolveDiagnostic::MissingBinding { .. }]), + "expected exactly one MissingBinding diagnostic, got: {diags:?}" + ); + assert!( + cfg.instances_of("sync").is_empty(), + "instance with missing T must be skipped" + ); + }); +} + +/// C4: when the TOML instance contains a key that is not a declared meta-var +/// or op name, the resolver emits an `UnknownKey` diagnostic and skips it. +#[test] +fn c4_unknown_extra_key_warns_and_skips() { + with_pattern(PATTERN_DECL, |pattern| { + let raw = vec![( + "sync".to_string(), + vec![instance( + &["$1"], + &[ + ("T", "std::sync::Mutex<$1>"), + ("U", "std::sync::MutexGuard<$1>"), + ("lock", "$T::lock"), + ("unlock", "$U::drop"), + ("foo", ""), // not a declared meta-var or op name + ], + )], + )]; + let (cfg, diags) = resolve_ops_config(pattern, &raw); + + assert!( + diags + .iter() + .any(|d| matches!(d, ResolveDiagnostic::UnknownKey { name, .. } if name == "foo")), + "expected an UnknownKey diagnostic for 'foo', got: {diags:?}" + ); + assert!( + cfg.instances_of("sync").is_empty(), + "instance with unknown key must be skipped" + ); + }); +} + +/// C7: when meta-var bindings are mutually recursive (`T = $U`, `U = $T`), +/// the fixed-point expansion does not converge, and a `Cycle` diagnostic is +/// emitted; the instance is skipped. +#[test] +fn c7_cycle_warns_and_skips() { + with_pattern(PATTERN_DECL, |pattern| { + let raw = vec![( + "sync".to_string(), + vec![instance( + &["$1"], + &[ + ("T", "$U"), // T → $U, but U → $T → forms a cycle + ("U", "$T"), + ("lock", "$T::lock"), + ("unlock", "$U::drop"), + ], + )], + )]; + let (cfg, diags) = resolve_ops_config(pattern, &raw); + + assert!( + diags.iter().any(|d| matches!(d, ResolveDiagnostic::Cycle { .. })), + "expected a Cycle diagnostic, got: {diags:?}" + ); + assert!(cfg.instances_of("sync").is_empty(), "cyclic instance must be skipped"); + }); +} + +/// Mixed scenario: a good instance and a bad instance (missing `U`) for the +/// same group. The resolver keeps the good one and skips the bad one. +#[test] +fn good_and_bad_instance_separated() { + with_pattern(PATTERN_DECL, |pattern| { + let raw = vec![( + "sync".to_string(), + vec![ + // Good: all required bindings present. + instance( + &["$1"], + &[ + ("T", "std::sync::Mutex<$1>"), + ("U", "std::sync::MutexGuard<$1>"), + ("lock", "$T::lock"), + ("unlock", "$U::drop"), + ], + ), + // Bad: missing "U" binding → should be skipped. + instance( + &["$1"], + &[ + ("T", "parking_lot::Mutex<$1>"), + ("lock", "$T::lock"), + ("unlock", "$T::drop"), + ], + ), + ], + )]; + let (cfg, diags) = resolve_ops_config(pattern, &raw); + + assert_eq!( + diags.len(), + 1, + "expected exactly 1 diagnostic (for the bad instance), got: {diags:?}" + ); + assert_eq!( + cfg.instances_of("sync").len(), + 1, + "good instance should be retained, bad one skipped" + ); + }); +} diff --git a/crates/rpl_context/tests/ops_wf.rs b/crates/rpl_context/tests/ops_wf.rs new file mode 100644 index 00000000..3c31fc9f --- /dev/null +++ b/crates/rpl_context/tests/ops_wf.rs @@ -0,0 +1,306 @@ +//! Well-formedness checks for `ops { ... }` blocks (R1–R3). +//! +//! These tests exercise `rpl_context::pat::check_ops_block` — the pre-lowering +//! validator that guards the `unreachable!()` contracts inside `OpsMetaLookup`. + +#![allow(internal_features)] +#![feature(rustc_private)] +#![feature(rustc_attrs)] +#![feature(let_chains)] +#![feature(box_patterns)] +#![feature(debug_closure_helpers)] +#![recursion_limit = "256"] + +extern crate rustc_data_structures; +extern crate rustc_span; + +use rpl_context::pat::check_ops_block; + +mod common; +use common::make_static_mctx; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +/// Parse `src` as an RPL pattern file, extract every `opsBlock` in it, run +/// `check_ops_block` on each one, and return all errors as a flat `Vec` +/// (the display form of each `OpsWfError`). +/// +/// Panics if the source fails to parse (that would be a test-fixture bug, not +/// an R1/R2/R3 violation). +fn collect_wf_errors(src: &str) -> Vec { + let mctx = make_static_mctx("test.rpl", src); + let mut errors = Vec::new(); + for syntax_tree in mctx.syntax_trees.iter() { + let (_, _, ops, _) = rpl_meta::meta::collect_blocks(syntax_tree); + for ops_block in ops { + let errs = check_ops_block(ops_block); + errors.extend(errs.into_iter().map(|e| e.to_string())); + } + } + errors +} + +/// Assert that at least one error in `errors` contains `needle`. +#[track_caller] +fn assert_any_contains(errors: &[String], needle: &str) { + assert!( + errors.iter().any(|e| e.contains(needle)), + "expected an error containing {:?} but got: {:?}", + needle, + errors + ); +} + +// --------------------------------------------------------------------------- +// R1: op-level meta-vars must be of kind `type` +// --------------------------------------------------------------------------- + +/// R1: a `const(usize)`-kind meta-var in an op group should be rejected. +#[test] +fn r1_non_type_op_meta_var_const_is_rejected() { + let src = r#" +pattern test +ops { + sync[$N: const(usize)] = { fn $lock() -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!(!errors.is_empty(), "R1: expected at least one error, got none"); + assert_any_contains(&errors, "must be of kind 'type'"); +} + +/// R1: a `place`-kind meta-var in an op group should also be rejected. +#[test] +fn r1_non_type_op_meta_var_place_is_rejected() { + let src = r#" +pattern test +ops { + sync[$P: place(&i32)] = { fn $lock() -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!(!errors.is_empty(), "R1: expected at least one error, got none"); + assert_any_contains(&errors, "must be of kind 'type'"); +} + +/// R1: a `type`-kind meta-var should be accepted (no error). +#[test] +fn r1_type_kind_op_meta_var_is_accepted() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $T) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + let r1_errors: Vec<_> = errors.iter().filter(|e| e.contains("must be of kind")).collect(); + assert!( + r1_errors.is_empty(), + "R1: no error expected for type-kind meta-var, got: {r1_errors:?}" + ); +} + +// --------------------------------------------------------------------------- +// R2: op signatures may only reference meta-vars declared in the same group +// --------------------------------------------------------------------------- + +/// R2: `$Z` is used in the signature but not declared in the op group. +#[test] +fn r2_op_signature_uses_undeclared_meta_var() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $Z) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!(!errors.is_empty(), "R2: expected at least one error, got none"); + assert_any_contains(&errors, "'$Z' is not declared in op group 'sync'"); +} + +/// R2: all meta-vars referenced are declared — no error expected. +#[test] +fn r2_all_referenced_meta_vars_declared_is_accepted() { + let src = r#" +pattern test +ops { + sync[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + fn $unlock(&mut $U) -> _; + } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + let r2_errors: Vec<_> = errors + .iter() + .filter(|e| e.contains("is not declared in op group")) + .collect(); + assert!(r2_errors.is_empty(), "R2: no error expected, got: {r2_errors:?}"); +} + +/// R2: the error message includes both the undeclared var name and the group name. +#[test] +fn r2_error_message_names_group_and_var() { + let src = r#" +pattern test +ops { + alloc[$T: type] = { fn $allocate(&mut $MISSING) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert_any_contains(&errors, "'$MISSING' is not declared in op group 'alloc'"); +} + +// --------------------------------------------------------------------------- +// R3: op signatures must not contain concrete Rust types +// --------------------------------------------------------------------------- + +/// R3: a `TypePath` like `std::sync::Mutex` in a parameter is rejected. +#[test] +fn r3_op_signature_with_concrete_type_path_is_rejected() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut std::sync::Mutex<$T>) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!(!errors.is_empty(), "R3: expected at least one error, got none"); + assert_any_contains(&errors, "concrete types belong in rpl.toml"); +} + +/// R3: a primitive type like `i32` in a parameter is rejected. +#[test] +fn r3_op_signature_with_primitive_type_is_rejected() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(i32) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!(!errors.is_empty(), "R3: expected at least one error, got none"); + assert_any_contains(&errors, "concrete types belong in rpl.toml"); +} + +/// R3: `&mut $T` is NOT a concrete type — only the leaf `$T` matters, which is +/// a meta-var. No error expected. +#[test] +fn r3_ref_to_meta_var_is_accepted() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $T) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + let r3_errors: Vec<_> = errors.iter().filter(|e| e.contains("concrete types belong")).collect(); + assert!( + r3_errors.is_empty(), + "R3: no error expected for &mut $T, got: {r3_errors:?}" + ); +} + +/// R3: concrete type in the return position is also rejected. +#[test] +fn r3_concrete_return_type_is_rejected() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $T) -> i32; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!( + !errors.is_empty(), + "R3: expected at least one error for concrete return type, got none" + ); + assert_any_contains(&errors, "concrete types belong in rpl.toml"); +} + +// --------------------------------------------------------------------------- +// Valid input: all rules satisfied, no errors +// --------------------------------------------------------------------------- + +/// Sanity check: a well-formed ops block with two type meta-vars produces no errors. +#[test] +fn valid_ops_block_produces_no_errors() { + let src = r#" +pattern test +ops { + sync[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + fn $unlock(&mut $U) -> _; + } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!( + errors.is_empty(), + "expected no errors for valid ops block, got: {errors:?}" + ); +} + +/// Sanity check: ops block with no meta-vars and no params produces no errors. +#[test] +fn ops_block_with_no_meta_vars_produces_no_errors() { + let src = r#" +pattern test +ops { + io[] = { fn $read() -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errors = collect_wf_errors(src); + assert!( + errors.is_empty(), + "expected no errors for ops block with no meta-vars, got: {errors:?}" + ); +} + +// --------------------------------------------------------------------------- +// Integration tests: verify add_parsed_patterns does not panic on bad input +// --------------------------------------------------------------------------- + +/// End-to-end guard: feeding a non-type meta-var (`$N: const(usize)`) through +/// the full `add_parsed_patterns` pipeline must not panic. The R1 check +/// inside `add_ops_block` skips the bad group before any lowering code runs. +#[test] +fn integration_r1_does_not_panic_on_bad_input() { + use rpl_context::PatternCtxt; + + let src = r#" +pattern test +ops { + sync[$N: const(usize)] = { fn $lock() -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let mctx = make_static_mctx("test_r1.rpl", src); + + // This must NOT panic — the R1 guard skips the bad group. + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + // The bad group should be absent from ops_block.groups. + pcx.for_each_rpl_pattern(|_, pattern| { + assert!( + pattern.ops_block.groups.is_empty(), + "expected no groups (bad group was rejected by R1), got: {:?}", + pattern.ops_block.groups.keys().collect::>() + ); + }); + }); +} diff --git a/crates/rpl_context/tests/referenced_op_groups.rs b/crates/rpl_context/tests/referenced_op_groups.rs new file mode 100644 index 00000000..2c3efd7a --- /dev/null +++ b/crates/rpl_context/tests/referenced_op_groups.rs @@ -0,0 +1,165 @@ +//! Tests for `RustItems::referenced_op_groups` population. +//! +//! After `add_parsed_patterns` the per-pattern `referenced_op_groups` set +//! must contain exactly the group names that appear as `$group::$op` operands +//! in the pattern's function bodies. + +#![allow(internal_features)] +#![feature(rustc_private)] +#![feature(rustc_attrs)] +#![feature(let_chains)] +#![feature(box_patterns)] +#![feature(debug_closure_helpers)] +#![recursion_limit = "256"] + +extern crate rustc_data_structures; +extern crate rustc_span; + +use rpl_context::PatternCtxt; +use rustc_span::Symbol; + +mod common; +use common::make_static_mctx; + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +/// Two op groups (`sync` and `logger`) are referenced by OpRefs in the body. +/// The `referenced_op_groups` set must contain exactly those two names. +#[test] +fn referenced_op_groups_collects_distinct_names() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $T) -> _; fn $unlock(&mut $T) -> _; } + logger[$L: type] = { fn $log(&$L) -> _; } +} +patt { + p[$T: type, $L: type] = fn _ (..) -> _ { + let $x: $T = $sync::$lock(_); + let $y: () = $sync::$unlock(_); + let $z: () = $logger::$log(_); + } +} +"#; + + let mctx = make_static_mctx("test_refgroups.rpl", src); + + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + + let mut found = false; + pcx.for_each_rpl_pattern(|_, pattern| { + let p = pattern + .patt_block + .get(&Symbol::intern("p")) + .expect("pattern item 'p' should exist"); + let groups = p.expect_rust_items().referenced_op_groups(); + assert_eq!( + groups.len(), + 2, + "expected 2 referenced op groups, got {}: {:?}", + groups.len(), + groups.iter().map(|s| s.as_str()).collect::>() + ); + assert!( + groups.contains(&Symbol::intern("sync")), + "expected 'sync' in referenced_op_groups" + ); + assert!( + groups.contains(&Symbol::intern("logger")), + "expected 'logger' in referenced_op_groups" + ); + found = true; + }); + + assert!(found, "no pattern with referenced op groups was found"); + }); +} + +/// A pattern that references the same group twice should still produce a set +/// of size 1 (deduplication). +#[test] +fn referenced_op_groups_deduplicates() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $T) -> _; fn $unlock(&mut $T) -> _; } +} +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = $sync::$lock(_); + let $y: () = $sync::$unlock(_); + } +} +"#; + + let mctx = make_static_mctx("test_refgroups.rpl", src); + + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + + let mut found = false; + pcx.for_each_rpl_pattern(|_, pattern| { + let p = pattern + .patt_block + .get(&Symbol::intern("p")) + .expect("pattern item 'p' should exist"); + let groups = p.expect_rust_items().referenced_op_groups(); + assert_eq!( + groups.len(), + 1, + "expected 1 referenced op group (dedup), got {}: {:?}", + groups.len(), + groups.iter().map(|s| s.as_str()).collect::>() + ); + assert!( + groups.contains(&Symbol::intern("sync")), + "expected 'sync' in referenced_op_groups" + ); + found = true; + }); + + assert!(found, "no pattern was found"); + }); +} + +/// A pattern with no OpRef calls should have an empty `referenced_op_groups`. +#[test] +fn referenced_op_groups_empty_when_no_op_refs() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $T) -> _; } +} +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = _; + } +} +"#; + + let mctx = make_static_mctx("test_refgroups.rpl", src); + + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + + let mut found = false; + pcx.for_each_rpl_pattern(|_, pattern| { + let p = pattern + .patt_block + .get(&Symbol::intern("p")) + .expect("pattern item 'p' should exist"); + let groups = p.expect_rust_items().referenced_op_groups(); + assert!( + groups.is_empty(), + "expected empty referenced_op_groups, got: {:?}", + groups.iter().map(|s| s.as_str()).collect::>() + ); + found = true; + }); + + assert!(found, "no pattern was found"); + }); +} diff --git a/crates/rpl_driver/Cargo.toml b/crates/rpl_driver/Cargo.toml index 8eb70805..a745514e 100644 --- a/crates/rpl_driver/Cargo.toml +++ b/crates/rpl_driver/Cargo.toml @@ -8,6 +8,7 @@ keywords.workspace = true edition.workspace = true [dependencies] +rpl_config.workspace = true rpl_context.workspace = true rpl_match.workspace = true rpl_meta.workspace = true diff --git a/crates/rpl_driver/src/lib.rs b/crates/rpl_driver/src/lib.rs index 7052f388..93c45fe2 100644 --- a/crates/rpl_driver/src/lib.rs +++ b/crates/rpl_driver/src/lib.rs @@ -21,9 +21,11 @@ use std::cell::RefCell; use std::convert::identity; use either::Either; +use rpl_config::RawOpInstance; use rpl_constraints::predicates::BodyInfoCache; use rpl_context::PatCtxt; use rpl_context::pat::DynamicError; +use rpl_context::pat::ops_resolved::{OpsConfig, resolve_ops_config}; use rpl_match::graph::{MirControlFlowGraph, MirDataDepGraph}; use rpl_match::matches::Matched; use rpl_match::matches::artifact::NormalizedMatched; @@ -45,6 +47,110 @@ use rustc_session::declare_tool_lint; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; +// --------------------------------------------------------------------------- +// Cartesian-product helper +// --------------------------------------------------------------------------- + +/// Generate the cartesian product of a sequence of factors. +/// +/// - Empty input (no factors): yields a single empty combination. +/// - Any factor that is empty: yields zero combinations (fold-on-empty semantics). +/// - Otherwise: yields every combination of one element from each factor, with the rightmost index +/// varying fastest (odometer order). +/// +/// The "fold on empty instances" property falls out of the helper: an empty +/// factor folds the product to zero combinations, which contributes the empty +/// match-set to set-op composition (Task 11 spec). +pub fn cartesian(factors: II) -> CartesianIter +where + I: Iterator, + II: IntoIterator, +{ + let factors: Vec> = factors.into_iter().map(|i| i.collect()).collect(); + + if factors.is_empty() { + // No factors → yield one empty combination. + return CartesianIter { + factors: Vec::new(), + indices: Vec::new(), + done: false, + empty_fold: false, + }; + } + if factors.iter().any(|f| f.is_empty()) { + // Any empty factor → fold to zero combos. + return CartesianIter { + factors: Vec::new(), + indices: Vec::new(), + done: true, + empty_fold: true, + }; + } + + let n = factors.len(); + CartesianIter { + factors, + indices: vec![0usize; n], + done: false, + empty_fold: false, + } +} + +/// Iterator returned by [`cartesian`]. +pub struct CartesianIter { + factors: Vec>, + indices: Vec, + done: bool, + /// `true` when an empty factor forced the product to zero — done before any yield. + empty_fold: bool, +} + +impl Iterator for CartesianIter { + type Item = Vec; + + fn next(&mut self) -> Option> { + if self.done || self.empty_fold { + return None; + } + if self.factors.is_empty() { + // No-factors case: one empty combo, then done. + self.done = true; + return Some(Vec::new()); + } + + let combo: Vec = self + .factors + .iter() + .zip(&self.indices) + .map(|(f, &i)| f[i].clone()) + .collect(); + + // Increment odometer (rightmost index varies fastest). + let mut k = self.factors.len(); + loop { + if k == 0 { + self.done = true; + break; + } + k -= 1; + self.indices[k] += 1; + if self.indices[k] < self.factors[k].len() { + break; + } + self.indices[k] = 0; + } + Some(combo) + } +} + +// --------------------------------------------------------------------------- +// ResolvedOpBindings — one (group → instance) assignment for a cartesian combo +// --------------------------------------------------------------------------- + +use rpl_context::pat::ops_resolved::{ResolvedOpBindings, ResolvedOpInstance}; + +// --------------------------------------------------------------------------- + #[cfg(feature = "timing")] mod errors; @@ -119,6 +225,18 @@ pub fn check_crate<'tcx, 'pcx, 'mcx: 'pcx>(tcx: TyCtxt<'tcx>, pcx: PatCtxt<'pcx> #[cfg(feature = "timing")] let start = std::time::Instant::now(); + // Resolve raw ops from rpl.toml into typed bindings against the loaded patterns. + // `load_raw_ops` returns an empty map when there is no rpl.toml or no [ops] table. + let raw_ops: Vec<(String, Vec)> = match rpl_config::load_raw_ops(None) { + Ok(map) => map.into_iter().collect(), + Err(err) => { + // Config loading failure is non-fatal: surface as a warning and continue + // without any op instances. + tcx.dcx().warn(format!("rpl: failed to load rpl.toml ops: {err}")); + Vec::new() + }, + }; + // _ = tcx.hir_crate_items(()).par_items(|item_id| { // check_item(tcx, pcx, item_id); // Ok(()) @@ -128,6 +246,7 @@ pub fn check_crate<'tcx, 'pcx, 'mcx: 'pcx>(tcx: TyCtxt<'tcx>, pcx: PatCtxt<'pcx> tcx, pcx, body_caches: RefCell::default(), + raw_ops, }; tcx.hir().walk_toplevel_module(&mut check_ctxt); rpl_utils::visit_crate(tcx); @@ -166,6 +285,10 @@ struct CheckFnCtxt<'pcx, 'tcx> { tcx: TyCtxt<'tcx>, pcx: PatCtxt<'pcx>, body_caches: RefCell>, + /// Raw op-group instances loaded from `rpl.toml` (empty when no file exists). + /// Stored as a pre-collected `Vec` so `resolve_ops_config` can be called + /// inside each `for_each_rpl_pattern` closure without lifetime trouble. + raw_ops: Vec<(String, Vec)>, } impl<'tcx> Visitor<'tcx> for CheckFnCtxt<'_, 'tcx> { @@ -262,9 +385,11 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { body: &'a mir::Body<'tcx>, mir_cfg: &'a MirControlFlowGraph, mir_ddg: &'a MirDataDepGraph, + op_bindings: ResolvedOpBindings, ) -> impl Iterator> { let iter = rpl_rust_items.impls.values().flat_map(move |impl_pat| { // FIXME: check impl_pat.ty and impl_pat.trait_id + let op_bindings = op_bindings.clone(); impl_pat .fns .values() @@ -276,7 +401,7 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { // continue; // } - CheckMirCtxt::new( + CheckMirCtxt::new_with_bindings( self.tcx, self.pcx, body, @@ -287,6 +412,7 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { fn_pat, mir_cfg, mir_ddg, + op_bindings.clone(), ) .check() .into_iter() @@ -301,12 +427,57 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { rpl_rust_items.post_process(iter) } - #[instrument(level = "trace", skip(self, pat_op, header, body, mir_cfg, mir_ddg), fields(pat_name = ?name))] + #[instrument(level = "trace", skip(self, ops, pat_op, header, body, mir_cfg, mir_ddg), fields(pat_name = ?name))] #[expect(clippy::too_many_arguments)] fn impl_matched_pat_op<'a>( &self, name: Symbol, + ops: &OpsConfig, + pat_op: &pat::PatternOperation<'pcx>, + def_id: LocalDefId, + header: Option, + has_self: bool, + self_ty: Option>, + body: &'a mir::Body<'tcx>, + mir_cfg: &'a MirControlFlowGraph, + mir_ddg: &'a MirDataDepGraph, + ) -> impl Iterator> { + // Determine which op groups any operand of this PatternOperation references. + let groups_used: Vec = pat_op.referenced_op_groups().into_iter().collect(); + + // Build the cartesian product of (group → instance choices). + // If groups_used is empty, cartesian yields one empty combo and the + // behavior is identical to the original (no-op-groups) path. + // If any group has zero instances, cartesian yields zero combos and the + // match-set is empty (fold-on-no-instances). + let factors: Vec> = groups_used + .iter() + .map(|g| ops.instances_of(g.as_str()).iter().collect()) + .collect(); + + let mut all: Vec> = Vec::new(); + for combo in cartesian(factors.into_iter().map(|v| v.into_iter())) { + let bindings = ResolvedOpBindings::from_combo(&groups_used, combo); + all.extend(self.impl_matched_pat_op_with_bindings( + name, ops, pat_op, &bindings, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + )); + } + all.into_iter() + } + + /// Inner body of `impl_matched_pat_op`, lifted out so the cartesian loop + /// can call it once per (group → instance) combination. + /// + /// `bindings` carries the current combo assignment; for patterns that + /// reference no op groups `bindings` is empty and behavior is identical + /// to the original implementation. + #[expect(clippy::too_many_arguments)] + fn impl_matched_pat_op_with_bindings<'a>( + &self, + _name: Symbol, + ops: &OpsConfig, pat_op: &pat::PatternOperation<'pcx>, + bindings: &ResolvedOpBindings, def_id: LocalDefId, header: Option, has_self: bool, @@ -320,7 +491,7 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { .iter() .flat_map(|positive| { self.impl_matched_pat_item( - positive.0, positive.1, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + positive.0, ops, positive.1, bindings, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, ) .map(|matched| matched.map(&positive.2)) }) @@ -330,12 +501,12 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { .iter() .flat_map(|negative| { self.impl_matched_pat_item( - negative.0, negative.1, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + negative.0, ops, negative.1, bindings, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, ) .map(|matched| matched.map(&negative.2)) }) .collect(); - debug!(?positive, ?negative, "impl_matched_pat_op"); + debug!(?positive, ?negative, "impl_matched_pat_op_with_bindings"); let iter = positive .into_iter() @@ -353,7 +524,9 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { fn impl_matched_pat_item<'a>( &self, name: Symbol, + ops: &OpsConfig, pat_item: &'pcx PatternItem<'pcx>, + bindings: &ResolvedOpBindings, def_id: LocalDefId, header: Option, has_self: bool, @@ -363,12 +536,68 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { mir_ddg: &'a MirDataDepGraph, ) -> impl Iterator> { match pat_item { - PatternItem::RustItems(rust_items) => Either::Left(self.impl_matched( - name, rust_items, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + PatternItem::RustItems(rust_items) => { + // Two cases: + // + // (a) `bindings` is non-empty. The outer `impl_matched_pat_op` has + // already chosen one element of the cartesian product over its + // `referenced_op_groups()` (the union over all sub-items) and is + // threading those bindings down through every sub-item in turn. + // We must use the outer combo unchanged — re-running a local + // cartesian here would silently overwrite the outer choices for + // any group this sub-item happens to reference, breaking + // `set_op_with_ops`-style composition where two sub-items each + // reference a different (or overlapping) subset of groups. + // + // (b) `bindings` is empty. This is the top-level direct entry into + // a `RustItems` pattern from `for_each_rpl_pattern`. Iterate + // the cartesian product over this `RustItems`' own + // `referenced_op_groups()`. + let mut all: Vec> = Vec::new(); + if !bindings.by_group.is_empty() { + all.extend(self.impl_matched( + name, + rust_items, + def_id, + header, + has_self, + self_ty, + body, + mir_cfg, + mir_ddg, + bindings.clone(), + )); + } else { + let groups_used: Vec = rust_items.referenced_op_groups().iter().copied().collect(); + let factors: Vec> = groups_used + .iter() + .map(|g| ops.instances_of(g.as_str()).iter().collect()) + .collect(); + for combo in cartesian(factors.into_iter().map(|v| v.into_iter())) { + let combo_bindings = if groups_used.is_empty() { + bindings.clone() + } else { + ResolvedOpBindings::from_combo(&groups_used, combo) + }; + all.extend(self.impl_matched( + name, + rust_items, + def_id, + header, + has_self, + self_ty, + body, + mir_cfg, + mir_ddg, + combo_bindings, + )); + } + } + Either::Left(all.into_iter()) + }, + PatternItem::RPLPatternOperation(pat_op) => Either::Right(self.impl_matched_pat_op( + name, ops, pat_op, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, )), - PatternItem::RPLPatternOperation(pat_op) => Either::Right( - self.impl_matched_pat_op(name, pat_op, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg), - ), } } @@ -385,6 +614,7 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { body: &'a mir::Body<'tcx>, mir_cfg: &'a MirControlFlowGraph, mir_ddg: &'a MirDataDepGraph, + op_bindings: ResolvedOpBindings, ) -> impl Iterator> { let iter = rpl_rust_items .fns @@ -392,7 +622,7 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { .filter(move |fn_pat| fn_pat.filter(self.tcx, def_id, header, body)) .filter_map(move |fn_pat| Some((fn_pat, fn_pat.extra_span(self.tcx, def_id)?))) .flat_map(move |(fn_pat, attr_map)| { - CheckMirCtxt::new( + CheckMirCtxt::new_with_bindings( self.tcx, self.pcx, body, @@ -403,6 +633,7 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { fn_pat, mir_cfg, mir_ddg, + op_bindings.clone(), ) .check() .into_iter() @@ -417,12 +648,49 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { rpl_rust_items.post_process(iter) } - #[instrument(level = "trace", skip(self, pat_op, header, body, mir_cfg, mir_ddg), fields(pat_name = ?name))] + #[instrument(level = "trace", skip(self, ops, pat_op, header, body, mir_cfg, mir_ddg), fields(pat_name = ?name))] #[expect(clippy::too_many_arguments)] fn fn_matched_pat_op<'a>( &self, name: Symbol, + ops: &OpsConfig, + pat_op: &pat::PatternOperation<'pcx>, + def_id: LocalDefId, + header: Option, + has_self: bool, + self_ty: Option>, + body: &'a mir::Body<'tcx>, + mir_cfg: &'a MirControlFlowGraph, + mir_ddg: &'a MirDataDepGraph, + ) -> impl Iterator> { + // Determine which op groups any operand of this PatternOperation references. + let groups_used: Vec = pat_op.referenced_op_groups().into_iter().collect(); + + // Cartesian product over op-group instance vectors (see impl_matched_pat_op). + let factors: Vec> = groups_used + .iter() + .map(|g| ops.instances_of(g.as_str()).iter().collect()) + .collect(); + + let mut all: Vec> = Vec::new(); + for combo in cartesian(factors.into_iter().map(|v| v.into_iter())) { + let bindings = ResolvedOpBindings::from_combo(&groups_used, combo); + all.extend(self.fn_matched_pat_op_with_bindings( + name, ops, pat_op, &bindings, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + )); + } + all.into_iter() + } + + /// Inner body of `fn_matched_pat_op`, lifted out so the cartesian loop + /// can call it once per (group → instance) combination. + #[expect(clippy::too_many_arguments)] + fn fn_matched_pat_op_with_bindings<'a>( + &self, + _name: Symbol, + ops: &OpsConfig, pat_op: &pat::PatternOperation<'pcx>, + bindings: &ResolvedOpBindings, def_id: LocalDefId, header: Option, has_self: bool, @@ -436,7 +704,7 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { .iter() .flat_map(|positive| { self.fn_matched_pat_item( - positive.0, positive.1, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + positive.0, ops, positive.1, bindings, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, ) .map(|matched| matched.map(&positive.2)) }) @@ -446,12 +714,12 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { .iter() .flat_map(|negative| { self.fn_matched_pat_item( - negative.0, negative.1, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + negative.0, ops, negative.1, bindings, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, ) .map(|matched| matched.map(&negative.2)) }) .collect(); - debug!(?positive, ?negative, "impl_matched_pat_op"); + debug!(?positive, ?negative, "fn_matched_pat_op_with_bindings"); let iter = positive .into_iter() @@ -469,7 +737,9 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { fn fn_matched_pat_item<'a>( &self, name: Symbol, + ops: &OpsConfig, pat_item: &'pcx PatternItem<'pcx>, + bindings: &ResolvedOpBindings, def_id: LocalDefId, header: Option, has_self: bool, @@ -479,12 +749,60 @@ impl<'tcx, 'pcx> CheckFnCtxt<'pcx, 'tcx> { mir_ddg: &'a MirDataDepGraph, ) -> impl Iterator> { match pat_item { - PatternItem::RustItems(rust_items) => Either::Left(self.fn_matched( - name, rust_items, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, + PatternItem::RustItems(rust_items) => { + // See the rationale on `impl_matched_pat_item` above — same shape + // applies here on the free-fn side. When `bindings` is non-empty + // the outer `fn_matched_pat_op` has already chosen a combo for + // the union of groups referenced by the operation; we must + // descend with the same combo rather than rebuild a local one + // over this `RustItems`' own subset of groups. + let mut all: Vec> = Vec::new(); + if !bindings.by_group.is_empty() { + all.extend(self.fn_matched( + name, + rust_items, + def_id, + header, + has_self, + self_ty, + body, + mir_cfg, + mir_ddg, + bindings.clone(), + )); + } else { + let groups_used: Vec = rust_items.referenced_op_groups().iter().copied().collect(); + let factors: Vec> = groups_used + .iter() + .map(|g| ops.instances_of(g.as_str()).iter().collect()) + .collect(); + for combo in cartesian(factors.into_iter().map(|v| v.into_iter())) { + let combo_bindings = if groups_used.is_empty() { + // No op groups referenced — use the caller-supplied bindings + // (preserves the existing behaviour for patterns without ops). + bindings.clone() + } else { + ResolvedOpBindings::from_combo(&groups_used, combo) + }; + all.extend(self.fn_matched( + name, + rust_items, + def_id, + header, + has_self, + self_ty, + body, + mir_cfg, + mir_ddg, + combo_bindings, + )); + } + } + Either::Left(all.into_iter()) + }, + PatternItem::RPLPatternOperation(pat_op) => Either::Right(self.fn_matched_pat_op( + name, ops, pat_op, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg, )), - PatternItem::RPLPatternOperation(pat_op) => Either::Right( - self.fn_matched_pat_op(name, pat_op, def_id, header, has_self, self_ty, body, mir_cfg, mir_ddg), - ), } } @@ -564,10 +882,25 @@ impl<'tcx> CheckFnCtxt<'_, 'tcx> { let mir_ddg = rpl_match::graph::mir_data_dep_graph(body, &mir_cfg); let header = Some(sig.header); let source_map = self.tcx.sess.source_map(); + // Clone so the borrow of `self.raw_ops` does not conflict with + // the `&self` receiver used inside the closure body. + let raw_ops: Vec<(String, Vec)> = self.raw_ops.clone(); self.pcx.for_each_rpl_pattern(|_id, pattern| { + let (ops, _ops_diags) = resolve_ops_config(pattern, &raw_ops); + // _ops_diags: resolution diagnostics will be surfaced in Task 14. for (&name, pat_item) in &pattern.patt_block { for matched in self.impl_matched_pat_item( - name, pat_item, def_id, header, has_self, self_ty, body, &mir_cfg, &mir_ddg, + name, + &ops, + pat_item, + &ResolvedOpBindings::empty(), + def_id, + header, + has_self, + self_ty, + body, + &mir_cfg, + &mir_ddg, ) { let error = pattern .get_diag(name, source_map, None, body, decl, &matched) @@ -600,10 +933,25 @@ impl<'tcx> CheckFnCtxt<'_, 'tcx> { let mir_ddg = rpl_match::graph::mir_data_dep_graph(body, &mir_cfg); let fn_name = fn_name.map(|ident| ident.name); let source_map = self.tcx.sess.source_map(); + // Clone so the borrow of `self.raw_ops` does not conflict with + // the `&self` receiver used inside the closure body. + let raw_ops: Vec<(String, Vec)> = self.raw_ops.clone(); self.pcx.for_each_rpl_pattern(|_id, pattern| { + let (ops, _ops_diags) = resolve_ops_config(pattern, &raw_ops); + // _ops_diags: resolution diagnostics will be surfaced in Task 14. for (&name, pat_item) in &pattern.patt_block { for matched in self.fn_matched_pat_item( - name, pat_item, def_id, header, has_self, self_ty, body, &mir_cfg, &mir_ddg, + name, + &ops, + pat_item, + &ResolvedOpBindings::empty(), + def_id, + header, + has_self, + self_ty, + body, + &mir_cfg, + &mir_ddg, ) { let error = pattern .get_diag(name, source_map, fn_name, body, decl, &matched) diff --git a/crates/rpl_driver/tests/cartesian.rs b/crates/rpl_driver/tests/cartesian.rs new file mode 100644 index 00000000..76ab9580 --- /dev/null +++ b/crates/rpl_driver/tests/cartesian.rs @@ -0,0 +1,40 @@ +//! Unit tests for the cartesian-product helper. +//! +//! These tests verify the four corner-cases specified in Task 11: +//! - empty input yields one empty combo +//! - single factor yields one combo per element +//! - two factors yield the full cross-product +//! - one empty factor folds the product to zero combos (the fold-on-no-instances mechanism) +#![feature(rustc_private)] + +use rpl_driver::cartesian; + +#[test] +fn empty_input_yields_one_empty_combo() { + let combos: Vec> = cartesian(std::iter::empty::>()).collect(); + assert_eq!(combos, vec![Vec::::new()]); +} + +#[test] +fn single_factor_yields_one_combo_per_element() { + let factors = vec![vec![1usize, 2, 3]]; + let iters: Vec<_> = factors.into_iter().map(|v| v.into_iter()).collect(); + let combos: Vec> = cartesian(iters).collect(); + assert_eq!(combos.len(), 3); +} + +#[test] +fn two_factors_two_three_yields_six() { + let factors = vec![vec![1usize, 2], vec![10, 20, 30]]; + let iters: Vec<_> = factors.into_iter().map(|v| v.into_iter()).collect(); + let combos: Vec> = cartesian(iters).collect(); + assert_eq!(combos.len(), 6); +} + +#[test] +fn one_empty_factor_yields_zero_combos() { + let factors: Vec> = vec![vec![1, 2], vec![]]; + let iters: Vec<_> = factors.into_iter().map(|v| v.into_iter()).collect(); + let combos: Vec> = cartesian(iters).collect(); + assert!(combos.is_empty(), "an empty factor folds the product to empty"); +} diff --git a/crates/rpl_driver/tests/ops_threading.rs b/crates/rpl_driver/tests/ops_threading.rs new file mode 100644 index 00000000..e61497d6 --- /dev/null +++ b/crates/rpl_driver/tests/ops_threading.rs @@ -0,0 +1,12 @@ +//! Smoke test: OpsConfig is constructed and passed through the matcher pipeline. +//! This test verifies the threading compiles and runs; matching semantics are +//! tested in Tasks 11/12 and the end-to-end UI tests in Phase 6. +#![feature(rustc_private)] + +#[test] +fn ops_config_threading_compiles_and_can_be_empty() { + // Construct an empty OpsConfig directly — no rustc_span globals needed. + let cfg = rpl_context::pat::ops_resolved::OpsConfig::default(); + // An empty OpsConfig has no instances at all. + assert!(cfg.instances.is_empty()); +} diff --git a/crates/rpl_match/src/matches/color.rs b/crates/rpl_match/src/matches/color.rs index 7ef58c3e..2ba38e96 100644 --- a/crates/rpl_match/src/matches/color.rs +++ b/crates/rpl_match/src/matches/color.rs @@ -2,6 +2,7 @@ //! A.K.A. if we're using building blocks with the right color. use rpl_constraints::Const; +use rpl_context::pat::ops_resolved::ResolvedOpBindings; use rustc_middle::{mir, ty}; use crate::matches::MatchCtxt; @@ -50,6 +51,10 @@ impl<'pcx, 'tcx> MatchStatement<'pcx, 'tcx> for MatchCtxt<'_, 'pcx, 'tcx> { self.cx.ty.typing_env } + fn op_bindings(&self) -> &ResolvedOpBindings { + &self.cx.op_bindings + } + type MatchTy = Self; fn ty(&self) -> &Self::MatchTy { self diff --git a/crates/rpl_match/src/mir.rs b/crates/rpl_match/src/mir.rs index c482a70e..b87b0202 100644 --- a/crates/rpl_match/src/mir.rs +++ b/crates/rpl_match/src/mir.rs @@ -3,6 +3,7 @@ use std::cell::RefCell; use rpl_context::PatCtxt; pub use rpl_context::pat; pub use rpl_context::pat::MatchedMap; +pub use rpl_context::pat::ops_resolved::ResolvedOpBindings; use rustc_data_structures::fx::FxIndexSet; use rustc_index::IndexVec; use rustc_index::bit_set::MixedBitSet; @@ -34,6 +35,9 @@ pub struct CheckMirCtxt<'a, 'pcx, 'tcx> { // mir_pdg: MirProgramDepGraph, pub(crate) locals: IndexVec>>, pub(crate) places: IndexVec>>>, + /// Op-group bindings for this cartesian-product combination (Task 12). + /// Empty when the pattern references no op groups. + pub(crate) op_bindings: ResolvedOpBindings, } impl<'a, 'pcx, 'tcx> CheckMirCtxt<'a, 'pcx, 'tcx> { @@ -55,6 +59,43 @@ impl<'a, 'pcx, 'tcx> CheckMirCtxt<'a, 'pcx, 'tcx> { fn_pat: &'a pat::FnPattern<'pcx>, mir_cfg: &'a MirControlFlowGraph, mir_ddg: &'a MirDataDepGraph, + ) -> Self { + Self::new_with_bindings( + tcx, + pcx, + body, + has_self, + self_ty, + pat, + pat_name, + fn_pat, + mir_cfg, + mir_ddg, + ResolvedOpBindings::empty(), + ) + } + + /// Like [`Self::new`] but also accepts op-group bindings for `OpRef` resolution + /// during matching (Task 12). + #[expect(clippy::too_many_arguments)] + #[instrument(level = "debug", skip_all, fields( + def_id = ?body.source.def_id(), + pat_name = ?pat_name, + ?has_self, + ?self_ty, + ))] + pub fn new_with_bindings( + tcx: TyCtxt<'tcx>, + pcx: PatCtxt<'pcx>, + body: &'a mir::Body<'tcx>, + has_self: bool, + self_ty: Option>, + pat: &'pcx pat::RustItems<'pcx>, + pat_name: Symbol, + fn_pat: &'a pat::FnPattern<'pcx>, + mir_cfg: &'a MirControlFlowGraph, + mir_ddg: &'a MirDataDepGraph, + op_bindings: ResolvedOpBindings, ) -> Self { let typing_env = ty::TypingEnv::post_analysis(tcx, body.source.def_id()); let ty = MatchTyCtxt::new(tcx, pcx, typing_env, self_ty, pat, &fn_pat.meta); @@ -85,6 +126,7 @@ impl<'a, 'pcx, 'tcx> CheckMirCtxt<'a, 'pcx, 'tcx> { mir_pat.locals.len(), ), places: IndexVec::from_elem_n(RefCell::new(FxIndexSet::default()), fn_pat.meta.place_vars.len()), + op_bindings, } } #[instrument(level = "info", skip_all, fields( @@ -276,6 +318,10 @@ impl<'pcx, 'tcx> MatchStatement<'pcx, 'tcx> for CheckMirCtxt<'_, 'pcx, 'tcx> { self.ty.typing_env } + fn op_bindings(&self) -> &ResolvedOpBindings { + &self.op_bindings + } + type MatchTy = MatchTyCtxt<'pcx, 'tcx>; fn ty(&self) -> &Self::MatchTy { &self.ty diff --git a/crates/rpl_match/src/statement.rs b/crates/rpl_match/src/statement.rs index 6035a8e9..e026aa3f 100644 --- a/crates/rpl_match/src/statement.rs +++ b/crates/rpl_match/src/statement.rs @@ -2,6 +2,7 @@ use std::iter::zip; use rpl_context::PatCtxt; pub use rpl_context::pat; +use rpl_context::pat::ops_resolved::ResolvedOpBindings; use rpl_mir_graph::TerminatorEdges; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_hash::FxHashMap; @@ -17,6 +18,34 @@ use crate::MatchFnCtxt; use crate::graph::{MirControlFlowGraph, MirDataDepGraph, PatControlFlowGraph, PatDataDepGraph}; use crate::ty::MatchTy; +/// Strip generic-argument brackets from a path string and split on `::`. +/// +/// Returns owned `String` segments so that callers can intern them to `Symbol`. +/// +/// For example: +/// - `"std::sync::Mutex<$1>::lock"` → `["std", "sync", "Mutex", "lock"]` +/// - `"std::sync::Arc>::clone"` → `["std", "sync", "Arc", "clone"]` +/// +/// Nested brackets are handled by a depth counter. +fn strip_generics_and_split(path: &str) -> Vec { + let mut result = String::with_capacity(path.len()); + let mut depth: u32 = 0; + for ch in path.chars() { + match ch { + '<' => depth += 1, + '>' => depth = depth.saturating_sub(1), + _ if depth == 0 => result.push(ch), + _ => {}, + } + } + result + .split("::") + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(str::to_owned) + .collect() +} + fn iter_place_proj_and_ty<'pcx, 'tcx>( body: &mir::Body<'tcx>, tcx: TyCtxt<'tcx>, @@ -61,6 +90,10 @@ pub(crate) trait MatchStatement<'pcx, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx>; fn typing_env(&self) -> TypingEnv<'tcx>; + /// Op-group bindings for the current cartesian-product combination. + /// Used by `match_operand` when it encounters `Operand::OpRef { group, op }`. + fn op_bindings(&self) -> &ResolvedOpBindings; + type MatchTy: MatchTy<'pcx, 'tcx>; fn ty(&self) -> &Self::MatchTy; @@ -439,6 +472,15 @@ pub(crate) trait MatchStatement<'pcx, 'tcx> { }), ) if let &ty::FnDef(fn_did, _args) = ty.kind() => self.match_fn_pat(fn_pat, fn_did), (pat::Operand::Any, mir::Operand::Copy(_) | mir::Operand::Move(_) | mir::Operand::Constant(_)) => true, + ( + &pat::Operand::OpRef { group, op }, + mir::Operand::Constant(box mir::ConstOperand { + const_: mir::Const::Val(mir::ConstValue::ZeroSized, ty), + .. + }), + ) if let &ty::FnDef(fn_did, _args) = ty.kind() => self.match_op_ref(group, op, fn_did), + // OpRef against a non-FnDef operand: no match. + (pat::Operand::OpRef { .. }, _) => false, ( pat::Operand::Copy(_) | pat::Operand::Move(_) | pat::Operand::Constant(_) | pat::Operand::FnPat(_), mir::Operand::Copy(_) | mir::Operand::Move(_) | mir::Operand::Constant(_), @@ -505,6 +547,41 @@ pub(crate) trait MatchStatement<'pcx, 'tcx> { MatchFnCtxt::new(self.tcx(), self.pcx(), self.pat(), fn_pat).match_fn(fn_did) } + /// Resolve an `Operand::OpRef { group, op }` against a concrete MIR `fn_did`. + /// + /// Steps: + /// 1. Look up the `ResolvedOpInstance` for `group` in the active bindings. + /// 2. Fetch the expanded path string for `op` (e.g. `"std::sync::Mutex::lock"`). + /// 3. Strip generic-argument brackets and split on `::` to build an `ItemPath`. + /// 4. Delegate to `match_item_path_by_def_path`. + #[instrument(level = "debug", skip(self), ret)] + fn match_op_ref(&self, group: Symbol, op: Symbol, fn_did: DefId) -> bool { + let bindings = self.op_bindings(); + let Some(instance) = bindings.get(&group) else { + // No binding for this group in the current cartesian combo — no match. + debug!(?group, "OpRef: no binding for group"); + return false; + }; + let Some(path_str) = instance.paths.get(&op) else { + // The resolver should have caught missing op entries; be defensive. + debug!(?group, ?op, "OpRef: op key not in instance.paths"); + return false; + }; + // Parse the path string into a flat sequence of symbol segments. + // Strategy: strip everything inside `<...>` (generic args), then split on `::`. + let path_str = path_str.as_str(); + let segments = strip_generics_and_split(path_str); + if segments.is_empty() { + debug!(?path_str, "OpRef: empty path after stripping generics"); + return false; + } + let symbols: Vec = segments.iter().map(|s| Symbol::intern(s)).collect(); + let item_path = pat::ItemPath(self.pcx().mk_slice(&symbols)); + let matched = self.ty().match_item_path_by_def_path(item_path, fn_did); + debug!(?path_str, ?fn_did, matched, "match_op_ref"); + matched + } + #[instrument(level = "trace", skip(self), ret)] fn match_agg_adt_variant( &self, diff --git a/crates/rpl_meta/src/check.rs b/crates/rpl_meta/src/check.rs index f44fabb1..d25e8745 100644 --- a/crates/rpl_meta/src/check.rs +++ b/crates/rpl_meta/src/check.rs @@ -498,11 +498,12 @@ impl<'i> CheckFnCtxt<'i, '_> { fn check_mir_fn_operand(&mut self, mctx: &MetaContext<'i>, fn_operand: &'i pairs::MirFnOperand<'i>) { match fn_operand.deref() { - Choice5::_0(copy_) => self.check_mir_place(mctx, copy_.get_matched().1.MirPlace()), - Choice5::_1(move_) => self.check_mir_place(mctx, move_.get_matched().1.MirPlace()), - Choice5::_2(ty_path) => self.check_type_path(mctx, ty_path), - Choice5::_3(lang_item) => self.check_lang_item_with_args(mctx, lang_item), - Choice5::_4(_ident) => self.check_mir_fn_pat(mctx), + Choice6::_0(copy_) => self.check_mir_place(mctx, copy_.get_matched().1.MirPlace()), + Choice6::_1(move_) => self.check_mir_place(mctx, move_.get_matched().1.MirPlace()), + Choice6::_2(ty_path) => self.check_type_path(mctx, ty_path), + Choice6::_3(lang_item) => self.check_lang_item_with_args(mctx, lang_item), + Choice6::_4(_op_ref) => { /* validated by resolver in Task 7 */ }, + Choice6::_5(_ident) => self.check_mir_fn_pat(mctx), } } diff --git a/crates/rpl_meta/src/meta.rs b/crates/rpl_meta/src/meta.rs index 2b1c2a20..5948dcad 100644 --- a/crates/rpl_meta/src/meta.rs +++ b/crates/rpl_meta/src/meta.rs @@ -38,7 +38,7 @@ impl<'mcx> SymbolTables<'mcx> { // Collect the pattern name of the rpl file. let name = Self::collect_rpl_pattern_name(main); // Collect the blocks. - let (utils, patts, diags) = collect_blocks(main); + let (utils, patts, _ops, diags) = collect_blocks(main); // Collect the symbol table of the util blocks. let util_imports = utils.iter().flat_map(|util| util.get_matched().2.iter_matched()); let util_items = utils.iter().flat_map(|util| util.get_matched().3.iter_matched()); @@ -104,10 +104,12 @@ pub fn collect_blocks<'mcx, 'i>( ) -> ( Vec<&'mcx pairs::utilBlock<'i>>, Vec<&'mcx pairs::pattBlock<'i>>, + Vec<&'mcx pairs::opsBlock<'i>>, Vec<&'mcx pairs::diagBlock<'i>>, ) { let mut utils = Vec::new(); let mut patts = Vec::new(); + let mut ops = Vec::new(); let mut diags = Vec::new(); let blocks = main.get_matched().1.get_matched().1; @@ -118,10 +120,12 @@ pub fn collect_blocks<'mcx, 'i>( utils.push(util); } else if let Some(patt) = block.pattBlock() { patts.push(patt); + } else if let Some(op) = block.opsBlock() { + ops.push(op); } else if let Some(diag) = block.diagBlock() { diags.push(diag); } } - (utils, patts, diags) + (utils, patts, ops, diags) } diff --git a/crates/rpl_parser/src/grammar/RPL.pest b/crates/rpl_parser/src/grammar/RPL.pest index 2dd37432..6c4437e3 100644 --- a/crates/rpl_parser/src/grammar/RPL.pest +++ b/crates/rpl_parser/src/grammar/RPL.pest @@ -3,6 +3,7 @@ kw_pattern = @{ "pattern" ~ !WordFollowing } kw_patt = @{ "patt" ~ !WordFollowing } kw_util = @{ "util" ~ !WordFollowing } +kw_ops = @{ "ops" ~ !WordFollowing } // Reserved words kw_cstr = @{ "cstr" ~ !WordFollowing } @@ -381,6 +382,9 @@ TypePath = { QSelf? ~ Path } +// Reference to a named operation in a declared op group, used as a call target. +OpRef = { MetaVariable ~ Colon2 ~ MetaVariable } + Konst = { Literal | TypePath @@ -714,6 +718,7 @@ MirFnOperand = { | LeftParen ~ MirOperandMove ~ RightParen | TypePath | LangItemWithArgs + | OpRef | MetaVariable } @@ -971,6 +976,33 @@ diagBlockItem = { Identifier ~ Assign ~ LeftBrace ~ diagItems ~ MetaVariableWithDiagMessageSeparatedByComma? ~ RightBrace } +// ops block helpers +// A function parameter in an op group signature: supports type-only params +// (e.g. `&mut $T`) in addition to the named/self forms from FnParam. +OpFnParam = { + SelfParam + | NormalParam + | PlaceHolderWithType + | Type + | Dot2 +} + +OpFnParamsSeparatedByComma = { + OpFnParam ~ (Comma ~ OpFnParam)* ~ Comma? +} + +// Like FnSig but uses OpFnParam so type-only params like `&mut $T` are allowed. +OpFnSig = { + Visibility? ~ Safety? ~ kw_fn ~ FnName ~ LeftParen ~ OpFnParamsSeparatedByComma? ~ RightParen ~ FnRet? +} + +// One signature-only Rust function declaration inside an op group. +OpFnDecl = { OpFnSig ~ SemiColon } + +// One named op group, e.g. `sync[$T:type, $U:type] = { fn $lock(...); ... }`. +opsItem = { Attr* ~ Identifier ~ MetaVariableDeclList? ~ Assign + ~ LeftBrace ~ (OpFnDecl)+ ~ RightBrace } + // RPL Blocks pattBlock = { kw_patt ~ LeftBrace ~ (UsePath)* ~ (RPLPatternItem)* ~ RightBrace @@ -978,10 +1010,13 @@ pattBlock = { utilBlock = { kw_util ~ LeftBrace ~ (UsePath)* ~ (RPLPatternItem)* ~ RightBrace } +opsBlock = { + kw_ops ~ LeftBrace ~ (opsItem)* ~ RightBrace +} diagBlock = { kw_diag ~ LeftBrace ~ (diagBlockItem)* ~ RightBrace } -Block = _{ pattBlock | utilBlock | diagBlock } +Block = _{ pattBlock | utilBlock | opsBlock | diagBlock } // RPL Header RPLHeader = { kw_pattern ~ Identifier } diff --git a/crates/rpl_parser/src/parser.rs b/crates/rpl_parser/src/parser.rs index bde876e2..26a6d269 100644 --- a/crates/rpl_parser/src/parser.rs +++ b/crates/rpl_parser/src/parser.rs @@ -9,6 +9,7 @@ pub enum Rule { r#kw_pattern, r#kw_patt, r#kw_util, + r#kw_ops, r#kw_cstr, r#kw_diag, r#kw_meta, @@ -172,6 +173,7 @@ pub enum Rule { r#PathLeading, r#PathSegment, r#TypePath, + r#OpRef, r#Konst, r#GenericConst, r#GenericArgument, @@ -296,8 +298,14 @@ pub enum Rule { r#diagItem, r#diagItems, r#diagBlockItem, + r#OpFnParam, + r#OpFnParamsSeparatedByComma, + r#OpFnSig, + r#OpFnDecl, + r#opsItem, r#pattBlock, r#utilBlock, + r#opsBlock, r#diagBlock, r#Block, r#RPLHeader, @@ -328,614 +336,614 @@ mod constant_wrappers { impl ::pest_typed::StringWrapper for r#w_2 { const CONTENT: &'static ::core::primitive::str = "util"; } - #[doc = "A wrapper for `\"cstr\"`."] + #[doc = "A wrapper for `\"ops\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_3; impl ::pest_typed::StringWrapper for r#w_3 { - const CONTENT: &'static ::core::primitive::str = "cstr"; + const CONTENT: &'static ::core::primitive::str = "ops"; } - #[doc = "A wrapper for `\"diag\"`."] + #[doc = "A wrapper for `\"cstr\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_4; impl ::pest_typed::StringWrapper for r#w_4 { - const CONTENT: &'static ::core::primitive::str = "diag"; + const CONTENT: &'static ::core::primitive::str = "cstr"; } - #[doc = "A wrapper for `\"meta\"`."] + #[doc = "A wrapper for `\"diag\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_5; impl ::pest_typed::StringWrapper for r#w_5 { - const CONTENT: &'static ::core::primitive::str = "meta"; + const CONTENT: &'static ::core::primitive::str = "diag"; } - #[doc = "A wrapper for `\"import\"`."] + #[doc = "A wrapper for `\"meta\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_6; impl ::pest_typed::StringWrapper for r#w_6 { - const CONTENT: &'static ::core::primitive::str = "import"; + const CONTENT: &'static ::core::primitive::str = "meta"; } - #[doc = "A wrapper for `\"self\"`."] + #[doc = "A wrapper for `\"import\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_7; impl ::pest_typed::StringWrapper for r#w_7 { - const CONTENT: &'static ::core::primitive::str = "self"; + const CONTENT: &'static ::core::primitive::str = "import"; } - #[doc = "A wrapper for `\"Self\"`."] + #[doc = "A wrapper for `\"self\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_8; impl ::pest_typed::StringWrapper for r#w_8 { - const CONTENT: &'static ::core::primitive::str = "Self"; + const CONTENT: &'static ::core::primitive::str = "self"; } - #[doc = "A wrapper for `\"fn\"`."] + #[doc = "A wrapper for `\"Self\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_9; impl ::pest_typed::StringWrapper for r#w_9 { - const CONTENT: &'static ::core::primitive::str = "fn"; + const CONTENT: &'static ::core::primitive::str = "Self"; } - #[doc = "A wrapper for `\"mut\"`."] + #[doc = "A wrapper for `\"fn\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_10; impl ::pest_typed::StringWrapper for r#w_10 { - const CONTENT: &'static ::core::primitive::str = "mut"; + const CONTENT: &'static ::core::primitive::str = "fn"; } - #[doc = "A wrapper for `\"const\"`."] + #[doc = "A wrapper for `\"mut\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_11; impl ::pest_typed::StringWrapper for r#w_11 { - const CONTENT: &'static ::core::primitive::str = "const"; + const CONTENT: &'static ::core::primitive::str = "mut"; } - #[doc = "A wrapper for `\"static\"`."] + #[doc = "A wrapper for `\"const\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_12; impl ::pest_typed::StringWrapper for r#w_12 { - const CONTENT: &'static ::core::primitive::str = "static"; + const CONTENT: &'static ::core::primitive::str = "const"; } - #[doc = "A wrapper for `\"lang\"`."] + #[doc = "A wrapper for `\"static\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_13; impl ::pest_typed::StringWrapper for r#w_13 { - const CONTENT: &'static ::core::primitive::str = "lang"; + const CONTENT: &'static ::core::primitive::str = "static"; } - #[doc = "A wrapper for `\"as\"`."] + #[doc = "A wrapper for `\"lang\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_14; impl ::pest_typed::StringWrapper for r#w_14 { - const CONTENT: &'static ::core::primitive::str = "as"; + const CONTENT: &'static ::core::primitive::str = "lang"; } - #[doc = "A wrapper for `\"crate\"`."] + #[doc = "A wrapper for `\"as\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_15; impl ::pest_typed::StringWrapper for r#w_15 { - const CONTENT: &'static ::core::primitive::str = "crate"; + const CONTENT: &'static ::core::primitive::str = "as"; } - #[doc = "A wrapper for `\"use\"`."] + #[doc = "A wrapper for `\"crate\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_16; impl ::pest_typed::StringWrapper for r#w_16 { - const CONTENT: &'static ::core::primitive::str = "use"; + const CONTENT: &'static ::core::primitive::str = "crate"; } - #[doc = "A wrapper for `\"type\"`."] + #[doc = "A wrapper for `\"use\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_17; impl ::pest_typed::StringWrapper for r#w_17 { - const CONTENT: &'static ::core::primitive::str = "type"; + const CONTENT: &'static ::core::primitive::str = "use"; } - #[doc = "A wrapper for `\"let\"`."] + #[doc = "A wrapper for `\"type\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_18; impl ::pest_typed::StringWrapper for r#w_18 { - const CONTENT: &'static ::core::primitive::str = "let"; + const CONTENT: &'static ::core::primitive::str = "type"; } - #[doc = "A wrapper for `\"move\"`."] + #[doc = "A wrapper for `\"let\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_19; impl ::pest_typed::StringWrapper for r#w_19 { - const CONTENT: &'static ::core::primitive::str = "move"; + const CONTENT: &'static ::core::primitive::str = "let"; } - #[doc = "A wrapper for `\"Len\"`."] + #[doc = "A wrapper for `\"move\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_20; impl ::pest_typed::StringWrapper for r#w_20 { - const CONTENT: &'static ::core::primitive::str = "Len"; + const CONTENT: &'static ::core::primitive::str = "move"; } - #[doc = "A wrapper for `\"PtrToPtr\"`."] + #[doc = "A wrapper for `\"Len\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_21; impl ::pest_typed::StringWrapper for r#w_21 { - const CONTENT: &'static ::core::primitive::str = "PtrToPtr"; + const CONTENT: &'static ::core::primitive::str = "Len"; } - #[doc = "A wrapper for `\"IntToInt\"`."] + #[doc = "A wrapper for `\"PtrToPtr\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_22; impl ::pest_typed::StringWrapper for r#w_22 { - const CONTENT: &'static ::core::primitive::str = "IntToInt"; + const CONTENT: &'static ::core::primitive::str = "PtrToPtr"; } - #[doc = "A wrapper for `\"Transmute\"`."] + #[doc = "A wrapper for `\"IntToInt\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_23; impl ::pest_typed::StringWrapper for r#w_23 { - const CONTENT: &'static ::core::primitive::str = "Transmute"; + const CONTENT: &'static ::core::primitive::str = "IntToInt"; } - #[doc = "A wrapper for `\"PointerCoercion\"`."] + #[doc = "A wrapper for `\"Transmute\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_24; impl ::pest_typed::StringWrapper for r#w_24 { - const CONTENT: &'static ::core::primitive::str = "PointerCoercion"; + const CONTENT: &'static ::core::primitive::str = "Transmute"; } - #[doc = "A wrapper for `\"copy\"`."] + #[doc = "A wrapper for `\"PointerCoercion\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_25; impl ::pest_typed::StringWrapper for r#w_25 { - const CONTENT: &'static ::core::primitive::str = "copy"; + const CONTENT: &'static ::core::primitive::str = "PointerCoercion"; } - #[doc = "A wrapper for `\"Unsize\"`."] + #[doc = "A wrapper for `\"copy\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_26; impl ::pest_typed::StringWrapper for r#w_26 { - const CONTENT: &'static ::core::primitive::str = "Unsize"; + const CONTENT: &'static ::core::primitive::str = "copy"; } - #[doc = "A wrapper for `\"Implicit\"`."] + #[doc = "A wrapper for `\"Unsize\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_27; impl ::pest_typed::StringWrapper for r#w_27 { - const CONTENT: &'static ::core::primitive::str = "Implicit"; + const CONTENT: &'static ::core::primitive::str = "Unsize"; } - #[doc = "A wrapper for `\"PointerExposeProvenance\"`."] + #[doc = "A wrapper for `\"Implicit\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_28; impl ::pest_typed::StringWrapper for r#w_28 { - const CONTENT: &'static ::core::primitive::str = "PointerExposeProvenance"; + const CONTENT: &'static ::core::primitive::str = "Implicit"; } - #[doc = "A wrapper for `\"PointerWithExposedProvenance\"`."] + #[doc = "A wrapper for `\"PointerExposeProvenance\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_29; impl ::pest_typed::StringWrapper for r#w_29 { - const CONTENT: &'static ::core::primitive::str = "PointerWithExposedProvenance"; + const CONTENT: &'static ::core::primitive::str = "PointerExposeProvenance"; } - #[doc = "A wrapper for `\"restricted\"`."] + #[doc = "A wrapper for `\"PointerWithExposedProvenance\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_30; impl ::pest_typed::StringWrapper for r#w_30 { - const CONTENT: &'static ::core::primitive::str = "restricted"; + const CONTENT: &'static ::core::primitive::str = "PointerWithExposedProvenance"; } - #[doc = "A wrapper for `\"Add\"`."] + #[doc = "A wrapper for `\"restricted\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_31; impl ::pest_typed::StringWrapper for r#w_31 { - const CONTENT: &'static ::core::primitive::str = "Add"; + const CONTENT: &'static ::core::primitive::str = "restricted"; } - #[doc = "A wrapper for `\"Sub\"`."] + #[doc = "A wrapper for `\"Add\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_32; impl ::pest_typed::StringWrapper for r#w_32 { - const CONTENT: &'static ::core::primitive::str = "Sub"; + const CONTENT: &'static ::core::primitive::str = "Add"; } - #[doc = "A wrapper for `\"Mul\"`."] + #[doc = "A wrapper for `\"Sub\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_33; impl ::pest_typed::StringWrapper for r#w_33 { - const CONTENT: &'static ::core::primitive::str = "Mul"; + const CONTENT: &'static ::core::primitive::str = "Sub"; } - #[doc = "A wrapper for `\"Div\"`."] + #[doc = "A wrapper for `\"Mul\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_34; impl ::pest_typed::StringWrapper for r#w_34 { - const CONTENT: &'static ::core::primitive::str = "Div"; + const CONTENT: &'static ::core::primitive::str = "Mul"; } - #[doc = "A wrapper for `\"Rem\"`."] + #[doc = "A wrapper for `\"Div\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_35; impl ::pest_typed::StringWrapper for r#w_35 { - const CONTENT: &'static ::core::primitive::str = "Rem"; + const CONTENT: &'static ::core::primitive::str = "Div"; } - #[doc = "A wrapper for `\"Lt\"`."] + #[doc = "A wrapper for `\"Rem\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_36; impl ::pest_typed::StringWrapper for r#w_36 { - const CONTENT: &'static ::core::primitive::str = "Lt"; + const CONTENT: &'static ::core::primitive::str = "Rem"; } - #[doc = "A wrapper for `\"Le\"`."] + #[doc = "A wrapper for `\"Lt\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_37; impl ::pest_typed::StringWrapper for r#w_37 { - const CONTENT: &'static ::core::primitive::str = "Le"; + const CONTENT: &'static ::core::primitive::str = "Lt"; } - #[doc = "A wrapper for `\"Gt\"`."] + #[doc = "A wrapper for `\"Le\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_38; impl ::pest_typed::StringWrapper for r#w_38 { - const CONTENT: &'static ::core::primitive::str = "Gt"; + const CONTENT: &'static ::core::primitive::str = "Le"; } - #[doc = "A wrapper for `\"Ge\"`."] + #[doc = "A wrapper for `\"Gt\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_39; impl ::pest_typed::StringWrapper for r#w_39 { - const CONTENT: &'static ::core::primitive::str = "Ge"; + const CONTENT: &'static ::core::primitive::str = "Gt"; } - #[doc = "A wrapper for `\"Eq\"`."] + #[doc = "A wrapper for `\"Ge\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_40; impl ::pest_typed::StringWrapper for r#w_40 { - const CONTENT: &'static ::core::primitive::str = "Eq"; + const CONTENT: &'static ::core::primitive::str = "Ge"; } - #[doc = "A wrapper for `\"Ne\"`."] + #[doc = "A wrapper for `\"Eq\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_41; impl ::pest_typed::StringWrapper for r#w_41 { - const CONTENT: &'static ::core::primitive::str = "Ne"; + const CONTENT: &'static ::core::primitive::str = "Eq"; } - #[doc = "A wrapper for `\"BitAnd\"`."] + #[doc = "A wrapper for `\"Ne\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_42; impl ::pest_typed::StringWrapper for r#w_42 { - const CONTENT: &'static ::core::primitive::str = "BitAnd"; + const CONTENT: &'static ::core::primitive::str = "Ne"; } - #[doc = "A wrapper for `\"BitOr\"`."] + #[doc = "A wrapper for `\"BitAnd\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_43; impl ::pest_typed::StringWrapper for r#w_43 { - const CONTENT: &'static ::core::primitive::str = "BitOr"; + const CONTENT: &'static ::core::primitive::str = "BitAnd"; } - #[doc = "A wrapper for `\"BitXor\"`."] + #[doc = "A wrapper for `\"BitOr\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_44; impl ::pest_typed::StringWrapper for r#w_44 { - const CONTENT: &'static ::core::primitive::str = "BitXor"; + const CONTENT: &'static ::core::primitive::str = "BitOr"; } - #[doc = "A wrapper for `\"Offset\"`."] + #[doc = "A wrapper for `\"BitXor\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_45; impl ::pest_typed::StringWrapper for r#w_45 { - const CONTENT: &'static ::core::primitive::str = "Offset"; + const CONTENT: &'static ::core::primitive::str = "BitXor"; } - #[doc = "A wrapper for `\"SizeOf\"`."] + #[doc = "A wrapper for `\"Offset\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_46; impl ::pest_typed::StringWrapper for r#w_46 { - const CONTENT: &'static ::core::primitive::str = "SizeOf"; + const CONTENT: &'static ::core::primitive::str = "Offset"; } - #[doc = "A wrapper for `\"AlignOf\"`."] + #[doc = "A wrapper for `\"SizeOf\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_47; impl ::pest_typed::StringWrapper for r#w_47 { - const CONTENT: &'static ::core::primitive::str = "AlignOf"; + const CONTENT: &'static ::core::primitive::str = "SizeOf"; } - #[doc = "A wrapper for `\"Neg\"`."] + #[doc = "A wrapper for `\"AlignOf\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_48; impl ::pest_typed::StringWrapper for r#w_48 { - const CONTENT: &'static ::core::primitive::str = "Neg"; + const CONTENT: &'static ::core::primitive::str = "AlignOf"; } - #[doc = "A wrapper for `\"Not\"`."] + #[doc = "A wrapper for `\"Neg\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_49; impl ::pest_typed::StringWrapper for r#w_49 { - const CONTENT: &'static ::core::primitive::str = "Not"; + const CONTENT: &'static ::core::primitive::str = "Neg"; } - #[doc = "A wrapper for `\"PtrMetadata\"`."] + #[doc = "A wrapper for `\"Not\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_50; impl ::pest_typed::StringWrapper for r#w_50 { - const CONTENT: &'static ::core::primitive::str = "PtrMetadata"; + const CONTENT: &'static ::core::primitive::str = "Not"; } - #[doc = "A wrapper for `\"discriminant\"`."] + #[doc = "A wrapper for `\"PtrMetadata\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_51; impl ::pest_typed::StringWrapper for r#w_51 { - const CONTENT: &'static ::core::primitive::str = "discriminant"; + const CONTENT: &'static ::core::primitive::str = "PtrMetadata"; } - #[doc = "A wrapper for `\"Ctor\"`."] + #[doc = "A wrapper for `\"discriminant\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_52; impl ::pest_typed::StringWrapper for r#w_52 { - const CONTENT: &'static ::core::primitive::str = "Ctor"; + const CONTENT: &'static ::core::primitive::str = "discriminant"; } - #[doc = "A wrapper for `\"from\"`."] + #[doc = "A wrapper for `\"Ctor\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_53; impl ::pest_typed::StringWrapper for r#w_53 { - const CONTENT: &'static ::core::primitive::str = "from"; + const CONTENT: &'static ::core::primitive::str = "Ctor"; } - #[doc = "A wrapper for `\"of\"`."] + #[doc = "A wrapper for `\"from\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_54; impl ::pest_typed::StringWrapper for r#w_54 { - const CONTENT: &'static ::core::primitive::str = "of"; + const CONTENT: &'static ::core::primitive::str = "from"; } - #[doc = "A wrapper for `\"raw\"`."] + #[doc = "A wrapper for `\"of\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_55; impl ::pest_typed::StringWrapper for r#w_55 { - const CONTENT: &'static ::core::primitive::str = "raw"; + const CONTENT: &'static ::core::primitive::str = "of"; } - #[doc = "A wrapper for `\"unreachable\"`."] + #[doc = "A wrapper for `\"raw\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_56; impl ::pest_typed::StringWrapper for r#w_56 { - const CONTENT: &'static ::core::primitive::str = "unreachable"; + const CONTENT: &'static ::core::primitive::str = "raw"; } - #[doc = "A wrapper for `\"drop\"`."] + #[doc = "A wrapper for `\"unreachable\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_57; impl ::pest_typed::StringWrapper for r#w_57 { - const CONTENT: &'static ::core::primitive::str = "drop"; + const CONTENT: &'static ::core::primitive::str = "unreachable"; } - #[doc = "A wrapper for `\"break\"`."] + #[doc = "A wrapper for `\"drop\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_58; impl ::pest_typed::StringWrapper for r#w_58 { - const CONTENT: &'static ::core::primitive::str = "break"; + const CONTENT: &'static ::core::primitive::str = "drop"; } - #[doc = "A wrapper for `\"continue\"`."] + #[doc = "A wrapper for `\"break\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_59; impl ::pest_typed::StringWrapper for r#w_59 { - const CONTENT: &'static ::core::primitive::str = "continue"; + const CONTENT: &'static ::core::primitive::str = "break"; } - #[doc = "A wrapper for `\"loop\"`."] + #[doc = "A wrapper for `\"continue\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_60; impl ::pest_typed::StringWrapper for r#w_60 { - const CONTENT: &'static ::core::primitive::str = "loop"; + const CONTENT: &'static ::core::primitive::str = "continue"; } - #[doc = "A wrapper for `\"return\"`."] + #[doc = "A wrapper for `\"loop\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_61; impl ::pest_typed::StringWrapper for r#w_61 { - const CONTENT: &'static ::core::primitive::str = "return"; + const CONTENT: &'static ::core::primitive::str = "loop"; } - #[doc = "A wrapper for `\"switchInt\"`."] + #[doc = "A wrapper for `\"return\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_62; impl ::pest_typed::StringWrapper for r#w_62 { - const CONTENT: &'static ::core::primitive::str = "switchInt"; + const CONTENT: &'static ::core::primitive::str = "return"; } - #[doc = "A wrapper for `\"true\"`."] + #[doc = "A wrapper for `\"switchInt\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_63; impl ::pest_typed::StringWrapper for r#w_63 { - const CONTENT: &'static ::core::primitive::str = "true"; + const CONTENT: &'static ::core::primitive::str = "switchInt"; } - #[doc = "A wrapper for `\"false\"`."] + #[doc = "A wrapper for `\"true\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_64; impl ::pest_typed::StringWrapper for r#w_64 { - const CONTENT: &'static ::core::primitive::str = "false"; + const CONTENT: &'static ::core::primitive::str = "true"; } - #[doc = "A wrapper for `\"unsafe\"`."] + #[doc = "A wrapper for `\"false\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_65; impl ::pest_typed::StringWrapper for r#w_65 { - const CONTENT: &'static ::core::primitive::str = "unsafe"; + const CONTENT: &'static ::core::primitive::str = "false"; } - #[doc = "A wrapper for `\"pub\"`."] + #[doc = "A wrapper for `\"unsafe\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_66; impl ::pest_typed::StringWrapper for r#w_66 { - const CONTENT: &'static ::core::primitive::str = "pub"; + const CONTENT: &'static ::core::primitive::str = "unsafe"; } - #[doc = "A wrapper for `\"struct\"`."] + #[doc = "A wrapper for `\"pub\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_67; impl ::pest_typed::StringWrapper for r#w_67 { - const CONTENT: &'static ::core::primitive::str = "struct"; + const CONTENT: &'static ::core::primitive::str = "pub"; } - #[doc = "A wrapper for `\"enum\"`."] + #[doc = "A wrapper for `\"struct\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_68; impl ::pest_typed::StringWrapper for r#w_68 { - const CONTENT: &'static ::core::primitive::str = "enum"; + const CONTENT: &'static ::core::primitive::str = "struct"; } - #[doc = "A wrapper for `\"impl\"`."] + #[doc = "A wrapper for `\"enum\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_69; impl ::pest_typed::StringWrapper for r#w_69 { - const CONTENT: &'static ::core::primitive::str = "impl"; + const CONTENT: &'static ::core::primitive::str = "enum"; } - #[doc = "A wrapper for `\"for\"`."] + #[doc = "A wrapper for `\"impl\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_70; impl ::pest_typed::StringWrapper for r#w_70 { - const CONTENT: &'static ::core::primitive::str = "for"; + const CONTENT: &'static ::core::primitive::str = "impl"; } - #[doc = "A wrapper for `\"place\"`."] + #[doc = "A wrapper for `\"for\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_71; impl ::pest_typed::StringWrapper for r#w_71 { - const CONTENT: &'static ::core::primitive::str = "place"; + const CONTENT: &'static ::core::primitive::str = "for"; } - #[doc = "A wrapper for `\"where\"`."] + #[doc = "A wrapper for `\"place\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_72; impl ::pest_typed::StringWrapper for r#w_72 { - const CONTENT: &'static ::core::primitive::str = "where"; + const CONTENT: &'static ::core::primitive::str = "place"; } - #[doc = "A wrapper for `\"RET\"`."] + #[doc = "A wrapper for `\"where\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_73; impl ::pest_typed::StringWrapper for r#w_73 { - const CONTENT: &'static ::core::primitive::str = "RET"; + const CONTENT: &'static ::core::primitive::str = "where"; } - #[doc = "A wrapper for `\"copy_nonoverlapping\"`."] + #[doc = "A wrapper for `\"RET\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_74; impl ::pest_typed::StringWrapper for r#w_74 { - const CONTENT: &'static ::core::primitive::str = "copy_nonoverlapping"; + const CONTENT: &'static ::core::primitive::str = "RET"; } - #[doc = "A wrapper for `\"u8\"`."] + #[doc = "A wrapper for `\"copy_nonoverlapping\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_75; impl ::pest_typed::StringWrapper for r#w_75 { - const CONTENT: &'static ::core::primitive::str = "u8"; + const CONTENT: &'static ::core::primitive::str = "copy_nonoverlapping"; } - #[doc = "A wrapper for `\"u16\"`."] + #[doc = "A wrapper for `\"u8\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_76; impl ::pest_typed::StringWrapper for r#w_76 { - const CONTENT: &'static ::core::primitive::str = "u16"; + const CONTENT: &'static ::core::primitive::str = "u8"; } - #[doc = "A wrapper for `\"u32\"`."] + #[doc = "A wrapper for `\"u16\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_77; impl ::pest_typed::StringWrapper for r#w_77 { - const CONTENT: &'static ::core::primitive::str = "u32"; + const CONTENT: &'static ::core::primitive::str = "u16"; } - #[doc = "A wrapper for `\"u64\"`."] + #[doc = "A wrapper for `\"u32\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_78; impl ::pest_typed::StringWrapper for r#w_78 { - const CONTENT: &'static ::core::primitive::str = "u64"; + const CONTENT: &'static ::core::primitive::str = "u32"; } - #[doc = "A wrapper for `\"usize\"`."] + #[doc = "A wrapper for `\"u64\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_79; impl ::pest_typed::StringWrapper for r#w_79 { - const CONTENT: &'static ::core::primitive::str = "usize"; + const CONTENT: &'static ::core::primitive::str = "u64"; } - #[doc = "A wrapper for `\"i8\"`."] + #[doc = "A wrapper for `\"usize\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_80; impl ::pest_typed::StringWrapper for r#w_80 { - const CONTENT: &'static ::core::primitive::str = "i8"; + const CONTENT: &'static ::core::primitive::str = "usize"; } - #[doc = "A wrapper for `\"i16\"`."] + #[doc = "A wrapper for `\"i8\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_81; impl ::pest_typed::StringWrapper for r#w_81 { - const CONTENT: &'static ::core::primitive::str = "i16"; + const CONTENT: &'static ::core::primitive::str = "i8"; } - #[doc = "A wrapper for `\"i32\"`."] + #[doc = "A wrapper for `\"i16\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_82; impl ::pest_typed::StringWrapper for r#w_82 { - const CONTENT: &'static ::core::primitive::str = "i32"; + const CONTENT: &'static ::core::primitive::str = "i16"; } - #[doc = "A wrapper for `\"i64\"`."] + #[doc = "A wrapper for `\"i32\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_83; impl ::pest_typed::StringWrapper for r#w_83 { - const CONTENT: &'static ::core::primitive::str = "i64"; + const CONTENT: &'static ::core::primitive::str = "i32"; } - #[doc = "A wrapper for `\"isize\"`."] + #[doc = "A wrapper for `\"i64\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_84; impl ::pest_typed::StringWrapper for r#w_84 { - const CONTENT: &'static ::core::primitive::str = "isize"; + const CONTENT: &'static ::core::primitive::str = "i64"; } - #[doc = "A wrapper for `\"bool\"`."] + #[doc = "A wrapper for `\"isize\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_85; impl ::pest_typed::StringWrapper for r#w_85 { - const CONTENT: &'static ::core::primitive::str = "bool"; + const CONTENT: &'static ::core::primitive::str = "isize"; } - #[doc = "A wrapper for `\"str\"`."] + #[doc = "A wrapper for `\"bool\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_86; impl ::pest_typed::StringWrapper for r#w_86 { - const CONTENT: &'static ::core::primitive::str = "str"; + const CONTENT: &'static ::core::primitive::str = "bool"; } - #[doc = "A wrapper for `\"//\"`."] + #[doc = "A wrapper for `\"str\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_87; impl ::pest_typed::StringWrapper for r#w_87 { - const CONTENT: &'static ::core::primitive::str = "//"; + const CONTENT: &'static ::core::primitive::str = "str"; } - #[doc = "A wrapper for `\"/*\"`."] + #[doc = "A wrapper for `\"//\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_88; impl ::pest_typed::StringWrapper for r#w_88 { - const CONTENT: &'static ::core::primitive::str = "/*"; + const CONTENT: &'static ::core::primitive::str = "//"; } - #[doc = "A wrapper for `\"*/\"`."] + #[doc = "A wrapper for `\"/*\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_89; impl ::pest_typed::StringWrapper for r#w_89 { - const CONTENT: &'static ::core::primitive::str = "*/"; + const CONTENT: &'static ::core::primitive::str = "/*"; } #[doc = "A wrapper for `\"*/\"`."] #[allow(non_camel_case_types)] @@ -944,236 +952,236 @@ mod constant_wrappers { impl ::pest_typed::StringWrapper for r#w_90 { const CONTENT: &'static ::core::primitive::str = "*/"; } - #[doc = "A wrapper for `\" \"`."] + #[doc = "A wrapper for `\"*/\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_91; impl ::pest_typed::StringWrapper for r#w_91 { - const CONTENT: &'static ::core::primitive::str = " "; + const CONTENT: &'static ::core::primitive::str = "*/"; } - #[doc = "A wrapper for `\"\\t\"`."] + #[doc = "A wrapper for `\" \"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_92; impl ::pest_typed::StringWrapper for r#w_92 { - const CONTENT: &'static ::core::primitive::str = "\t"; + const CONTENT: &'static ::core::primitive::str = " "; } - #[doc = "A wrapper for `\"\\r\"`."] + #[doc = "A wrapper for `\"\\t\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_93; impl ::pest_typed::StringWrapper for r#w_93 { - const CONTENT: &'static ::core::primitive::str = "\r"; + const CONTENT: &'static ::core::primitive::str = "\t"; } - #[doc = "A wrapper for `\"\\n\"`."] + #[doc = "A wrapper for `\"\\r\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_94; impl ::pest_typed::StringWrapper for r#w_94 { - const CONTENT: &'static ::core::primitive::str = "\n"; + const CONTENT: &'static ::core::primitive::str = "\r"; } - #[doc = "A wrapper for `\"{\"`."] + #[doc = "A wrapper for `\"\\n\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_95; impl ::pest_typed::StringWrapper for r#w_95 { - const CONTENT: &'static ::core::primitive::str = "{"; + const CONTENT: &'static ::core::primitive::str = "\n"; } - #[doc = "A wrapper for `\"}\"`."] + #[doc = "A wrapper for `\"{\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_96; impl ::pest_typed::StringWrapper for r#w_96 { - const CONTENT: &'static ::core::primitive::str = "}"; + const CONTENT: &'static ::core::primitive::str = "{"; } - #[doc = "A wrapper for `\"[\"`."] + #[doc = "A wrapper for `\"}\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_97; impl ::pest_typed::StringWrapper for r#w_97 { - const CONTENT: &'static ::core::primitive::str = "["; + const CONTENT: &'static ::core::primitive::str = "}"; } - #[doc = "A wrapper for `\"]\"`."] + #[doc = "A wrapper for `\"[\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_98; impl ::pest_typed::StringWrapper for r#w_98 { - const CONTENT: &'static ::core::primitive::str = "]"; + const CONTENT: &'static ::core::primitive::str = "["; } - #[doc = "A wrapper for `\"(\"`."] + #[doc = "A wrapper for `\"]\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_99; impl ::pest_typed::StringWrapper for r#w_99 { - const CONTENT: &'static ::core::primitive::str = "("; + const CONTENT: &'static ::core::primitive::str = "]"; } - #[doc = "A wrapper for `\")\"`."] + #[doc = "A wrapper for `\"(\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_100; impl ::pest_typed::StringWrapper for r#w_100 { - const CONTENT: &'static ::core::primitive::str = ")"; + const CONTENT: &'static ::core::primitive::str = "("; } - #[doc = "A wrapper for `\"<\"`."] + #[doc = "A wrapper for `\")\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_101; impl ::pest_typed::StringWrapper for r#w_101 { - const CONTENT: &'static ::core::primitive::str = "<"; + const CONTENT: &'static ::core::primitive::str = ")"; } - #[doc = "A wrapper for `\">\"`."] + #[doc = "A wrapper for `\"<\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_102; impl ::pest_typed::StringWrapper for r#w_102 { - const CONTENT: &'static ::core::primitive::str = ">"; + const CONTENT: &'static ::core::primitive::str = "<"; } - #[doc = "A wrapper for `\"$\"`."] + #[doc = "A wrapper for `\">\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_103; impl ::pest_typed::StringWrapper for r#w_103 { - const CONTENT: &'static ::core::primitive::str = "$"; + const CONTENT: &'static ::core::primitive::str = ">"; } - #[doc = "A wrapper for `\"=\"`."] + #[doc = "A wrapper for `\"$\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_104; impl ::pest_typed::StringWrapper for r#w_104 { - const CONTENT: &'static ::core::primitive::str = "="; + const CONTENT: &'static ::core::primitive::str = "$"; } - #[doc = "A wrapper for `\",\"`."] + #[doc = "A wrapper for `\"=\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_105; impl ::pest_typed::StringWrapper for r#w_105 { - const CONTENT: &'static ::core::primitive::str = ","; + const CONTENT: &'static ::core::primitive::str = "="; } - #[doc = "A wrapper for `\".\"`."] + #[doc = "A wrapper for `\",\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_106; impl ::pest_typed::StringWrapper for r#w_106 { - const CONTENT: &'static ::core::primitive::str = "."; + const CONTENT: &'static ::core::primitive::str = ","; } - #[doc = "A wrapper for `\"..\"`."] + #[doc = "A wrapper for `\".\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_107; impl ::pest_typed::StringWrapper for r#w_107 { - const CONTENT: &'static ::core::primitive::str = ".."; + const CONTENT: &'static ::core::primitive::str = "."; } - #[doc = "A wrapper for `\":\"`."] + #[doc = "A wrapper for `\"..\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_108; impl ::pest_typed::StringWrapper for r#w_108 { - const CONTENT: &'static ::core::primitive::str = ":"; + const CONTENT: &'static ::core::primitive::str = ".."; } - #[doc = "A wrapper for `\"::\"`."] + #[doc = "A wrapper for `\":\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_109; impl ::pest_typed::StringWrapper for r#w_109 { - const CONTENT: &'static ::core::primitive::str = "::"; + const CONTENT: &'static ::core::primitive::str = ":"; } - #[doc = "A wrapper for `\";\"`."] + #[doc = "A wrapper for `\"::\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_110; impl ::pest_typed::StringWrapper for r#w_110 { - const CONTENT: &'static ::core::primitive::str = ";"; + const CONTENT: &'static ::core::primitive::str = "::"; } - #[doc = "A wrapper for `\"#\"`."] + #[doc = "A wrapper for `\";\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_111; impl ::pest_typed::StringWrapper for r#w_111 { - const CONTENT: &'static ::core::primitive::str = "#"; + const CONTENT: &'static ::core::primitive::str = ";"; } - #[doc = "A wrapper for `\"&\"`."] + #[doc = "A wrapper for `\"#\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_112; impl ::pest_typed::StringWrapper for r#w_112 { - const CONTENT: &'static ::core::primitive::str = "&"; + const CONTENT: &'static ::core::primitive::str = "#"; } - #[doc = "A wrapper for `\"&&\"`."] + #[doc = "A wrapper for `\"&\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_113; impl ::pest_typed::StringWrapper for r#w_113 { - const CONTENT: &'static ::core::primitive::str = "&&"; + const CONTENT: &'static ::core::primitive::str = "&"; } - #[doc = "A wrapper for `\"||\"`."] + #[doc = "A wrapper for `\"&&\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_114; impl ::pest_typed::StringWrapper for r#w_114 { - const CONTENT: &'static ::core::primitive::str = "||"; + const CONTENT: &'static ::core::primitive::str = "&&"; } - #[doc = "A wrapper for `\"!\"`."] + #[doc = "A wrapper for `\"||\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_115; impl ::pest_typed::StringWrapper for r#w_115 { - const CONTENT: &'static ::core::primitive::str = "!"; + const CONTENT: &'static ::core::primitive::str = "||"; } - #[doc = "A wrapper for `\"?\"`."] + #[doc = "A wrapper for `\"!\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_116; impl ::pest_typed::StringWrapper for r#w_116 { - const CONTENT: &'static ::core::primitive::str = "?"; + const CONTENT: &'static ::core::primitive::str = "!"; } - #[doc = "A wrapper for `\"*\"`."] + #[doc = "A wrapper for `\"?\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_117; impl ::pest_typed::StringWrapper for r#w_117 { - const CONTENT: &'static ::core::primitive::str = "*"; + const CONTENT: &'static ::core::primitive::str = "?"; } - #[doc = "A wrapper for `\"->\"`."] + #[doc = "A wrapper for `\"*\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_118; impl ::pest_typed::StringWrapper for r#w_118 { - const CONTENT: &'static ::core::primitive::str = "->"; + const CONTENT: &'static ::core::primitive::str = "*"; } - #[doc = "A wrapper for `\"=>\"`."] + #[doc = "A wrapper for `\"->\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_119; impl ::pest_typed::StringWrapper for r#w_119 { - const CONTENT: &'static ::core::primitive::str = "=>"; + const CONTENT: &'static ::core::primitive::str = "->"; } - #[doc = "A wrapper for `\"'\"`."] + #[doc = "A wrapper for `\"=>\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_120; impl ::pest_typed::StringWrapper for r#w_120 { - const CONTENT: &'static ::core::primitive::str = "'"; + const CONTENT: &'static ::core::primitive::str = "=>"; } - #[doc = "A wrapper for `\"+\"`."] + #[doc = "A wrapper for `\"'\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_121; impl ::pest_typed::StringWrapper for r#w_121 { - const CONTENT: &'static ::core::primitive::str = "+"; + const CONTENT: &'static ::core::primitive::str = "'"; } - #[doc = "A wrapper for `\"-\"`."] + #[doc = "A wrapper for `\"+\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_122; impl ::pest_typed::StringWrapper for r#w_122 { - const CONTENT: &'static ::core::primitive::str = "-"; + const CONTENT: &'static ::core::primitive::str = "+"; } - #[doc = "A wrapper for `\"_\"`."] + #[doc = "A wrapper for `\"-\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_123; impl ::pest_typed::StringWrapper for r#w_123 { - const CONTENT: &'static ::core::primitive::str = "_"; + const CONTENT: &'static ::core::primitive::str = "-"; } #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] @@ -1182,19 +1190,19 @@ mod constant_wrappers { impl ::pest_typed::StringWrapper for r#w_124 { const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"0b\"`."] + #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_125; impl ::pest_typed::StringWrapper for r#w_125 { - const CONTENT: &'static ::core::primitive::str = "0b"; + const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"_\"`."] + #[doc = "A wrapper for `\"0b\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_126; impl ::pest_typed::StringWrapper for r#w_126 { - const CONTENT: &'static ::core::primitive::str = "_"; + const CONTENT: &'static ::core::primitive::str = "0b"; } #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] @@ -1203,19 +1211,19 @@ mod constant_wrappers { impl ::pest_typed::StringWrapper for r#w_127 { const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"0o\"`."] + #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_128; impl ::pest_typed::StringWrapper for r#w_128 { - const CONTENT: &'static ::core::primitive::str = "0o"; + const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"_\"`."] + #[doc = "A wrapper for `\"0o\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_129; impl ::pest_typed::StringWrapper for r#w_129 { - const CONTENT: &'static ::core::primitive::str = "_"; + const CONTENT: &'static ::core::primitive::str = "0o"; } #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] @@ -1224,19 +1232,19 @@ mod constant_wrappers { impl ::pest_typed::StringWrapper for r#w_130 { const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"0x\"`."] + #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_131; impl ::pest_typed::StringWrapper for r#w_131 { - const CONTENT: &'static ::core::primitive::str = "0x"; + const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"_\"`."] + #[doc = "A wrapper for `\"0x\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_132; impl ::pest_typed::StringWrapper for r#w_132 { - const CONTENT: &'static ::core::primitive::str = "_"; + const CONTENT: &'static ::core::primitive::str = "0x"; } #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] @@ -1245,54 +1253,54 @@ mod constant_wrappers { impl ::pest_typed::StringWrapper for r#w_133 { const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"\\\"\"`."] + #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_134; impl ::pest_typed::StringWrapper for r#w_134 { + const CONTENT: &'static ::core::primitive::str = "_"; + } + #[doc = "A wrapper for `\"\\\"\"`."] + #[allow(non_camel_case_types)] + #[derive(Clone, Hash, PartialEq, Eq)] + pub struct r#w_135; + impl ::pest_typed::StringWrapper for r#w_135 { const CONTENT: &'static ::core::primitive::str = "\""; } #[doc = "A wrapper for `[\"\\\"\"]`."] #[allow(non_camel_case_types)] #[derive(Clone, PartialEq)] - pub struct r#w_135; - impl ::pest_typed::StringArrayWrapper for r#w_135 { + pub struct r#w_136; + impl ::pest_typed::StringArrayWrapper for r#w_136 { const CONTENT: &'static [&'static ::core::primitive::str] = &["\""]; } #[doc = "A wrapper for `\"\\\"\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] - pub struct r#w_136; - impl ::pest_typed::StringWrapper for r#w_136 { - const CONTENT: &'static ::core::primitive::str = "\""; - } - #[doc = "A wrapper for `\"_\"`."] - #[allow(non_camel_case_types)] - #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_137; impl ::pest_typed::StringWrapper for r#w_137 { - const CONTENT: &'static ::core::primitive::str = "_"; + const CONTENT: &'static ::core::primitive::str = "\""; } - #[doc = "A wrapper for `\"-\"`."] + #[doc = "A wrapper for `\"_\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_138; impl ::pest_typed::StringWrapper for r#w_138 { - const CONTENT: &'static ::core::primitive::str = "-"; + const CONTENT: &'static ::core::primitive::str = "_"; } - #[doc = "A wrapper for `\"Group\"`."] + #[doc = "A wrapper for `\"-\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_139; impl ::pest_typed::StringWrapper for r#w_139 { - const CONTENT: &'static ::core::primitive::str = "Group"; + const CONTENT: &'static ::core::primitive::str = "-"; } - #[doc = "A wrapper for `\"\\\"\"`."] + #[doc = "A wrapper for `\"Group\"`."] #[allow(non_camel_case_types)] #[derive(Clone, Hash, PartialEq, Eq)] pub struct r#w_140; impl ::pest_typed::StringWrapper for r#w_140 { - const CONTENT: &'static ::core::primitive::str = "\""; + const CONTENT: &'static ::core::primitive::str = "Group"; } #[doc = "A wrapper for `\"\\\"\"`."] #[allow(non_camel_case_types)] @@ -1308,6 +1316,13 @@ mod constant_wrappers { impl ::pest_typed::StringWrapper for r#w_142 { const CONTENT: &'static ::core::primitive::str = "\""; } + #[doc = "A wrapper for `\"\\\"\"`."] + #[allow(non_camel_case_types)] + #[derive(Clone, Hash, PartialEq, Eq)] + pub struct r#w_143; + impl ::pest_typed::StringWrapper for r#w_143 { + const CONTENT: &'static ::core::primitive::str = "\""; + } } #[doc = "Generated structs for tags."] pub mod tags {} @@ -1321,177 +1336,179 @@ pub mod rules_impl { impl<'i, const INHERITED: ::core::primitive::usize> r#kw_patt<'i, INHERITED> {} :: pest_typed :: rule ! (r#kw_util , "Corresponds to expression: `(\"util\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_util , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_2 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_util<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_cstr , "Corresponds to expression: `(\"cstr\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_cstr , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_3 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_ops , "Corresponds to expression: `(\"ops\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_ops , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_3 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#kw_ops<'i, INHERITED> {} + :: pest_typed :: rule ! (r#kw_cstr , "Corresponds to expression: `(\"cstr\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_cstr , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_4 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_cstr<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_diag , "Corresponds to expression: `(\"diag\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_diag , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_4 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_diag , "Corresponds to expression: `(\"diag\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_diag , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_5 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_diag<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_meta , "Corresponds to expression: `(\"meta\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_meta , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_5 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_meta , "Corresponds to expression: `(\"meta\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_meta , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_6 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_meta<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_import , "Corresponds to expression: `(\"import\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_import , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_6 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_import , "Corresponds to expression: `(\"import\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_import , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_7 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_import<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_self , "Corresponds to expression: `(\"self\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_self , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_7 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_self , "Corresponds to expression: `(\"self\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_self , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_8 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_self<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Self , "Corresponds to expression: `(\"Self\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Self , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_8 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Self , "Corresponds to expression: `(\"Self\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Self , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_9 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Self<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_fn , "Corresponds to expression: `(\"fn\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_fn , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_9 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_fn , "Corresponds to expression: `(\"fn\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_fn , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_10 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_fn<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_mut , "Corresponds to expression: `(\"mut\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_mut , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_10 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_mut , "Corresponds to expression: `(\"mut\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_mut , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_11 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_mut<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_const , "Corresponds to expression: `(\"const\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_const , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_11 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_const , "Corresponds to expression: `(\"const\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_const , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_12 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_const<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_static , "Corresponds to expression: `(\"static\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_static , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_12 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_static , "Corresponds to expression: `(\"static\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_static , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_13 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_static<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_lang , "Corresponds to expression: `(\"lang\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_lang , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_13 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_lang , "Corresponds to expression: `(\"lang\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_lang , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_14 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_lang<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_as , "Corresponds to expression: `(\"as\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_as , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_14 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_as , "Corresponds to expression: `(\"as\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_as , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_15 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_as<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_crate , "Corresponds to expression: `(\"crate\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_crate , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_15 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_crate , "Corresponds to expression: `(\"crate\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_crate , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_16 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_crate<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_use , "Corresponds to expression: `(\"use\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_use , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_16 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_use , "Corresponds to expression: `(\"use\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_use , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_17 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_use<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_type , "Corresponds to expression: `(\"type\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_type , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_17 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_type , "Corresponds to expression: `(\"type\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_type , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_18 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_type<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_let , "Corresponds to expression: `(\"let\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_let , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_18 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_let , "Corresponds to expression: `(\"let\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_let , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_19 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_let<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_move , "Corresponds to expression: `(\"move\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_move , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_19 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_move , "Corresponds to expression: `(\"move\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_move , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_20 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_move<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Len , "Corresponds to expression: `(\"Len\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Len , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_20 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Len , "Corresponds to expression: `(\"Len\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Len , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_21 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Len<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_PtrToPtr , "Corresponds to expression: `(\"PtrToPtr\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PtrToPtr , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_21 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_PtrToPtr , "Corresponds to expression: `(\"PtrToPtr\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PtrToPtr , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_22 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_PtrToPtr<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_IntToInt , "Corresponds to expression: `(\"IntToInt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_IntToInt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_22 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_IntToInt , "Corresponds to expression: `(\"IntToInt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_IntToInt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_23 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_IntToInt<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Transmute , "Corresponds to expression: `(\"Transmute\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Transmute , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_23 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Transmute , "Corresponds to expression: `(\"Transmute\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Transmute , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_24 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Transmute<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_PointerCoercion , "Corresponds to expression: `(\"PointerCoercion\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PointerCoercion , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_24 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_PointerCoercion , "Corresponds to expression: `(\"PointerCoercion\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PointerCoercion , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_25 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_PointerCoercion<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_copy , "Corresponds to expression: `(\"copy\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_copy , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_25 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_copy , "Corresponds to expression: `(\"copy\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_copy , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_26 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_copy<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Unsize , "Corresponds to expression: `(\"Unsize\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Unsize , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_26 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Unsize , "Corresponds to expression: `(\"Unsize\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Unsize , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_27 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Unsize<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Implicit , "Corresponds to expression: `(\"Implicit\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Implicit , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_27 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Implicit , "Corresponds to expression: `(\"Implicit\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Implicit , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_28 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Implicit<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_PointerExposeProvenance , "Corresponds to expression: `(\"PointerExposeProvenance\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PointerExposeProvenance , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_28 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_PointerExposeProvenance , "Corresponds to expression: `(\"PointerExposeProvenance\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PointerExposeProvenance , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_29 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_PointerExposeProvenance<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_PointerWithExposedProvenance , "Corresponds to expression: `(\"PointerWithExposedProvenance\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PointerWithExposedProvenance , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_29 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_PointerWithExposedProvenance , "Corresponds to expression: `(\"PointerWithExposedProvenance\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PointerWithExposedProvenance , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_30 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_PointerWithExposedProvenance<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Restricted , "Corresponds to expression: `(\"restricted\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Restricted , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_30 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Restricted , "Corresponds to expression: `(\"restricted\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Restricted , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_31 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Restricted<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Add , "Corresponds to expression: `(\"Add\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Add , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_31 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Add , "Corresponds to expression: `(\"Add\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Add , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_32 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Add<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Sub , "Corresponds to expression: `(\"Sub\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Sub , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_32 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Sub , "Corresponds to expression: `(\"Sub\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Sub , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_33 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Sub<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Mul , "Corresponds to expression: `(\"Mul\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Mul , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_33 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Mul , "Corresponds to expression: `(\"Mul\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Mul , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_34 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Mul<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Div , "Corresponds to expression: `(\"Div\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Div , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_34 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Div , "Corresponds to expression: `(\"Div\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Div , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_35 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Div<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Rem , "Corresponds to expression: `(\"Rem\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Rem , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_35 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Rem , "Corresponds to expression: `(\"Rem\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Rem , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_36 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Rem<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Lt , "Corresponds to expression: `(\"Lt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Lt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_36 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Lt , "Corresponds to expression: `(\"Lt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Lt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_37 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Lt<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Le , "Corresponds to expression: `(\"Le\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Le , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_37 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Le , "Corresponds to expression: `(\"Le\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Le , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_38 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Le<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Gt , "Corresponds to expression: `(\"Gt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Gt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_38 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Gt , "Corresponds to expression: `(\"Gt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Gt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_39 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Gt<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Ge , "Corresponds to expression: `(\"Ge\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Ge , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_39 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Ge , "Corresponds to expression: `(\"Ge\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Ge , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_40 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Ge<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Eq , "Corresponds to expression: `(\"Eq\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Eq , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_40 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Eq , "Corresponds to expression: `(\"Eq\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Eq , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_41 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Eq<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Ne , "Corresponds to expression: `(\"Ne\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Ne , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_41 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Ne , "Corresponds to expression: `(\"Ne\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Ne , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_42 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Ne<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_BitAnd , "Corresponds to expression: `(\"BitAnd\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_BitAnd , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_42 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_BitAnd , "Corresponds to expression: `(\"BitAnd\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_BitAnd , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_43 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_BitAnd<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_BitOr , "Corresponds to expression: `(\"BitOr\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_BitOr , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_43 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_BitOr , "Corresponds to expression: `(\"BitOr\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_BitOr , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_44 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_BitOr<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_BitXor , "Corresponds to expression: `(\"BitXor\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_BitXor , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_44 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_BitXor , "Corresponds to expression: `(\"BitXor\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_BitXor , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_45 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_BitXor<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Offset , "Corresponds to expression: `(\"Offset\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Offset , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_45 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Offset , "Corresponds to expression: `(\"Offset\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Offset , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_46 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Offset<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_SizeOf , "Corresponds to expression: `(\"SizeOf\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_SizeOf , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_46 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_SizeOf , "Corresponds to expression: `(\"SizeOf\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_SizeOf , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_47 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_SizeOf<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_AlignOf , "Corresponds to expression: `(\"AlignOf\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_AlignOf , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_47 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_AlignOf , "Corresponds to expression: `(\"AlignOf\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_AlignOf , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_48 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_AlignOf<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Neg , "Corresponds to expression: `(\"Neg\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Neg , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_48 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Neg , "Corresponds to expression: `(\"Neg\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Neg , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_49 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Neg<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Not , "Corresponds to expression: `(\"Not\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Not , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_49 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Not , "Corresponds to expression: `(\"Not\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Not , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_50 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Not<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_PtrMetadata , "Corresponds to expression: `(\"PtrMetadata\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PtrMetadata , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_50 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_PtrMetadata , "Corresponds to expression: `(\"PtrMetadata\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_PtrMetadata , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_51 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_PtrMetadata<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_discriminant , "Corresponds to expression: `(\"discriminant\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_discriminant , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_51 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_discriminant , "Corresponds to expression: `(\"discriminant\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_discriminant , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_52 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_discriminant<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_Ctor , "Corresponds to expression: `(\"Ctor\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Ctor , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_52 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_Ctor , "Corresponds to expression: `(\"Ctor\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_Ctor , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_53 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_Ctor<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_from , "Corresponds to expression: `(\"from\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_from , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_53 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_from , "Corresponds to expression: `(\"from\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_from , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_54 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_from<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_of , "Corresponds to expression: `(\"of\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_of , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_54 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_of , "Corresponds to expression: `(\"of\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_of , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_55 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_of<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_raw , "Corresponds to expression: `(\"raw\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_raw , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_55 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_raw , "Corresponds to expression: `(\"raw\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_raw , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_56 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_raw<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_unreachable , "Corresponds to expression: `(\"unreachable\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_unreachable , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_56 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_unreachable , "Corresponds to expression: `(\"unreachable\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_unreachable , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_57 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_unreachable<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_drop , "Corresponds to expression: `(\"drop\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_drop , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_57 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_drop , "Corresponds to expression: `(\"drop\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_drop , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_58 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_drop<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_break , "Corresponds to expression: `(\"break\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_break , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_58 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_break , "Corresponds to expression: `(\"break\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_break , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_59 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_break<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_continue , "Corresponds to expression: `(\"continue\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_continue , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_59 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_continue , "Corresponds to expression: `(\"continue\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_continue , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_60 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_continue<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_loop , "Corresponds to expression: `(\"loop\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_loop , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_60 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_loop , "Corresponds to expression: `(\"loop\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_loop , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_61 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_loop<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_return , "Corresponds to expression: `(\"return\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_return , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_61 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_return , "Corresponds to expression: `(\"return\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_return , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_62 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_return<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_switchInt , "Corresponds to expression: `(\"switchInt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_switchInt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_62 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_switchInt , "Corresponds to expression: `(\"switchInt\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_switchInt , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_63 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_switchInt<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_true , "Corresponds to expression: `(\"true\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_true , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_63 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_true , "Corresponds to expression: `(\"true\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_true , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_64 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_true<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_false , "Corresponds to expression: `(\"false\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_false , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_64 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_false , "Corresponds to expression: `(\"false\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_false , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_65 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_false<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_unsafe , "Corresponds to expression: `(\"unsafe\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_unsafe , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_65 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_unsafe , "Corresponds to expression: `(\"unsafe\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_unsafe , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_66 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_unsafe<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_pub , "Corresponds to expression: `(\"pub\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_pub , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_66 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_pub , "Corresponds to expression: `(\"pub\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_pub , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_67 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_pub<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_struct , "Corresponds to expression: `(\"struct\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_struct , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_67 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_struct , "Corresponds to expression: `(\"struct\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_struct , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_68 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_struct<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_enum , "Corresponds to expression: `(\"enum\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_enum , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_68 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_enum , "Corresponds to expression: `(\"enum\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_enum , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_69 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_enum<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_impl , "Corresponds to expression: `(\"impl\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_impl , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_69 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_impl , "Corresponds to expression: `(\"impl\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_impl , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_70 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_impl<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_for , "Corresponds to expression: `(\"for\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_for , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_70 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_for , "Corresponds to expression: `(\"for\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_for , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_71 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_for<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_place , "Corresponds to expression: `(\"place\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_place , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_71 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_place , "Corresponds to expression: `(\"place\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_place , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_72 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_place<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_where , "Corresponds to expression: `(\"where\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_where , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_72 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_where , "Corresponds to expression: `(\"where\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_where , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_73 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_where<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_RET , "Corresponds to expression: `(\"RET\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_RET , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_73 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_RET , "Corresponds to expression: `(\"RET\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_RET , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_74 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_RET<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_copy_nonoverlapping , "Corresponds to expression: `(\"copy_nonoverlapping\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_copy_nonoverlapping , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_74 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_copy_nonoverlapping , "Corresponds to expression: `(\"copy_nonoverlapping\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_copy_nonoverlapping , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_75 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_copy_nonoverlapping<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_u8 , "Corresponds to expression: `(\"u8\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u8 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_75 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_u8 , "Corresponds to expression: `(\"u8\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u8 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_76 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_u8<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_u16 , "Corresponds to expression: `(\"u16\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u16 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_76 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_u16 , "Corresponds to expression: `(\"u16\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u16 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_77 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_u16<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_u32 , "Corresponds to expression: `(\"u32\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u32 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_77 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_u32 , "Corresponds to expression: `(\"u32\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u32 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_78 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_u32<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_u64 , "Corresponds to expression: `(\"u64\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u64 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_78 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_u64 , "Corresponds to expression: `(\"u64\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_u64 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_79 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_u64<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_usize , "Corresponds to expression: `(\"usize\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_usize , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_79 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_usize , "Corresponds to expression: `(\"usize\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_usize , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_80 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_usize<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_i8 , "Corresponds to expression: `(\"i8\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i8 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_80 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_i8 , "Corresponds to expression: `(\"i8\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i8 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_81 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_i8<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_i16 , "Corresponds to expression: `(\"i16\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i16 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_81 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_i16 , "Corresponds to expression: `(\"i16\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i16 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_82 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_i16<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_i32 , "Corresponds to expression: `(\"i32\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i32 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_82 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_i32 , "Corresponds to expression: `(\"i32\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i32 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_83 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_i32<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_i64 , "Corresponds to expression: `(\"i64\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i64 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_83 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_i64 , "Corresponds to expression: `(\"i64\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_i64 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_84 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_i64<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_isize , "Corresponds to expression: `(\"isize\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_isize , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_84 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_isize , "Corresponds to expression: `(\"isize\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_isize , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_85 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_isize<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_bool , "Corresponds to expression: `(\"bool\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_bool , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_85 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_bool , "Corresponds to expression: `(\"bool\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_bool , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_86 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_bool<'i, INHERITED> {} - :: pest_typed :: rule ! (r#kw_str , "Corresponds to expression: `(\"str\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_str , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_86 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#kw_str , "Corresponds to expression: `(\"str\" ~ !WordFollowing)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#kw_str , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_87 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#kw_str<'i, INHERITED> {} :: pest_typed :: rule ! (r#Keywords , "Corresponds to expression: `(kw_pattern | kw_patt | kw_util | kw_cstr | kw_diag | kw_meta | kw_import | kw_self | kw_Self | kw_fn | kw_mut | kw_const | kw_static | kw_lang | kw_as | kw_crate | kw_use | kw_type | kw_let | kw_move | kw_Len | kw_PtrToPtr | kw_IntToInt | kw_Transmute | kw_PointerCoercion | kw_PointerExposeProvenance | kw_PointerWithExposedProvenance | kw_Add | kw_Sub | kw_Mul | kw_Div | kw_Rem | kw_Lt | kw_Le | kw_Gt | kw_Ge | kw_Eq | kw_Ne | kw_BitAnd | kw_BitOr | kw_BitXor | kw_Offset | kw_SizeOf | kw_AlignOf | kw_Neg | kw_Not | kw_PtrMetadata | kw_discriminant | kw_copy_nonoverlapping | kw_Ctor | kw_from | kw_of | kw_raw | kw_break | kw_continue | kw_loop | kw_return | kw_switchInt | kw_true | kw_false | kw_unsafe | kw_pub | kw_struct | kw_enum | kw_impl | kw_for | kw_where)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Keywords , super :: super :: generics :: Choice67 :: < super :: super :: rules :: r#kw_pattern :: < 'i , 0 > , super :: super :: rules :: r#kw_patt :: < 'i , 0 > , super :: super :: rules :: r#kw_util :: < 'i , 0 > , super :: super :: rules :: r#kw_cstr :: < 'i , 0 > , super :: super :: rules :: r#kw_diag :: < 'i , 0 > , super :: super :: rules :: r#kw_meta :: < 'i , 0 > , super :: super :: rules :: r#kw_import :: < 'i , 0 > , super :: super :: rules :: r#kw_self :: < 'i , 0 > , super :: super :: rules :: r#kw_Self :: < 'i , 0 > , super :: super :: rules :: r#kw_fn :: < 'i , 0 > , super :: super :: rules :: r#kw_mut :: < 'i , 0 > , super :: super :: rules :: r#kw_const :: < 'i , 0 > , super :: super :: rules :: r#kw_static :: < 'i , 0 > , super :: super :: rules :: r#kw_lang :: < 'i , 0 > , super :: super :: rules :: r#kw_as :: < 'i , 0 > , super :: super :: rules :: r#kw_crate :: < 'i , 0 > , super :: super :: rules :: r#kw_use :: < 'i , 0 > , super :: super :: rules :: r#kw_type :: < 'i , 0 > , super :: super :: rules :: r#kw_let :: < 'i , 0 > , super :: super :: rules :: r#kw_move :: < 'i , 0 > , super :: super :: rules :: r#kw_Len :: < 'i , 0 > , super :: super :: rules :: r#kw_PtrToPtr :: < 'i , 0 > , super :: super :: rules :: r#kw_IntToInt :: < 'i , 0 > , super :: super :: rules :: r#kw_Transmute :: < 'i , 0 > , super :: super :: rules :: r#kw_PointerCoercion :: < 'i , 0 > , super :: super :: rules :: r#kw_PointerExposeProvenance :: < 'i , 0 > , super :: super :: rules :: r#kw_PointerWithExposedProvenance :: < 'i , 0 > , super :: super :: rules :: r#kw_Add :: < 'i , 0 > , super :: super :: rules :: r#kw_Sub :: < 'i , 0 > , super :: super :: rules :: r#kw_Mul :: < 'i , 0 > , super :: super :: rules :: r#kw_Div :: < 'i , 0 > , super :: super :: rules :: r#kw_Rem :: < 'i , 0 > , super :: super :: rules :: r#kw_Lt :: < 'i , 0 > , super :: super :: rules :: r#kw_Le :: < 'i , 0 > , super :: super :: rules :: r#kw_Gt :: < 'i , 0 > , super :: super :: rules :: r#kw_Ge :: < 'i , 0 > , super :: super :: rules :: r#kw_Eq :: < 'i , 0 > , super :: super :: rules :: r#kw_Ne :: < 'i , 0 > , super :: super :: rules :: r#kw_BitAnd :: < 'i , 0 > , super :: super :: rules :: r#kw_BitOr :: < 'i , 0 > , super :: super :: rules :: r#kw_BitXor :: < 'i , 0 > , super :: super :: rules :: r#kw_Offset :: < 'i , 0 > , super :: super :: rules :: r#kw_SizeOf :: < 'i , 0 > , super :: super :: rules :: r#kw_AlignOf :: < 'i , 0 > , super :: super :: rules :: r#kw_Neg :: < 'i , 0 > , super :: super :: rules :: r#kw_Not :: < 'i , 0 > , super :: super :: rules :: r#kw_PtrMetadata :: < 'i , 0 > , super :: super :: rules :: r#kw_discriminant :: < 'i , 0 > , super :: super :: rules :: r#kw_copy_nonoverlapping :: < 'i , 0 > , super :: super :: rules :: r#kw_Ctor :: < 'i , 0 > , super :: super :: rules :: r#kw_from :: < 'i , 0 > , super :: super :: rules :: r#kw_of :: < 'i , 0 > , super :: super :: rules :: r#kw_raw :: < 'i , 0 > , super :: super :: rules :: r#kw_break :: < 'i , 0 > , super :: super :: rules :: r#kw_continue :: < 'i , 0 > , super :: super :: rules :: r#kw_loop :: < 'i , 0 > , super :: super :: rules :: r#kw_return :: < 'i , 0 > , super :: super :: rules :: r#kw_switchInt :: < 'i , 0 > , super :: super :: rules :: r#kw_true :: < 'i , 0 > , super :: super :: rules :: r#kw_false :: < 'i , 0 > , super :: super :: rules :: r#kw_unsafe :: < 'i , 0 > , super :: super :: rules :: r#kw_pub :: < 'i , 0 > , super :: super :: rules :: r#kw_struct :: < 'i , 0 > , super :: super :: rules :: r#kw_enum :: < 'i , 0 > , super :: super :: rules :: r#kw_impl :: < 'i , 0 > , super :: super :: rules :: r#kw_for :: < 'i , 0 > , super :: super :: rules :: r#kw_where :: < 'i , 0 > , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Keywords<'i, INHERITED> {} - :: pest_typed :: rule ! (r#COMMENT , "Corresponds to expression: `((\"//\" ~ (!NEWLINE ~ ANY)*) | (\"/*\" ~ (!\"*/\" ~ ANY)* ~ \"*/\"))`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#COMMENT , super :: super :: generics :: Choice2 :: < super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_87 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#NEWLINE > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#ANY , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_88 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_89 > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#ANY , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_90 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Expression , true); + :: pest_typed :: rule ! (r#COMMENT , "Corresponds to expression: `((\"//\" ~ (!NEWLINE ~ ANY)*) | (\"/*\" ~ (!\"*/\" ~ ANY)* ~ \"*/\"))`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#COMMENT , super :: super :: generics :: Choice2 :: < super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_88 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: rules :: r#NEWLINE > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#ANY , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_89 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_90 > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#ANY , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_91 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Expression , true); impl<'i, const INHERITED: ::core::primitive::usize> r#COMMENT<'i, INHERITED> { #[doc = "A helper function to access [`ANY`]."] #[allow(non_snake_case)] @@ -1549,65 +1566,65 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#WHITESPACE , "Corresponds to expression: `(\" \" | \"\\t\" | \"\\r\" | \"\\n\")`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#WHITESPACE , super :: super :: generics :: Choice4 :: < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_91 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_92 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_93 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_94 > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Expression , true); + :: pest_typed :: rule ! (r#WHITESPACE , "Corresponds to expression: `(\" \" | \"\\t\" | \"\\r\" | \"\\n\")`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#WHITESPACE , super :: super :: generics :: Choice4 :: < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_92 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_93 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_94 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_95 > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Expression , true); impl<'i, const INHERITED: ::core::primitive::usize> r#WHITESPACE<'i, INHERITED> {} - :: pest_typed :: rule ! (r#LeftBrace , "Corresponds to expression: `\"{\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LeftBrace , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_95 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#LeftBrace , "Corresponds to expression: `\"{\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LeftBrace , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_96 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#LeftBrace<'i, INHERITED> {} - :: pest_typed :: rule ! (r#RightBrace , "Corresponds to expression: `\"}\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightBrace , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_96 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#RightBrace , "Corresponds to expression: `\"}\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightBrace , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_97 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#RightBrace<'i, INHERITED> {} - :: pest_typed :: rule ! (r#LeftBracket , "Corresponds to expression: `\"[\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LeftBracket , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_97 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#LeftBracket , "Corresponds to expression: `\"[\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LeftBracket , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_98 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#LeftBracket<'i, INHERITED> {} - :: pest_typed :: rule ! (r#RightBracket , "Corresponds to expression: `\"]\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightBracket , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_98 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#RightBracket , "Corresponds to expression: `\"]\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightBracket , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_99 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#RightBracket<'i, INHERITED> {} - :: pest_typed :: rule ! (r#LeftParen , "Corresponds to expression: `\"(\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LeftParen , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_99 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#LeftParen , "Corresponds to expression: `\"(\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LeftParen , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_100 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#LeftParen<'i, INHERITED> {} - :: pest_typed :: rule ! (r#RightParen , "Corresponds to expression: `\")\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightParen , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_100 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#RightParen , "Corresponds to expression: `\")\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightParen , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_101 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#RightParen<'i, INHERITED> {} - :: pest_typed :: rule ! (r#LessThan , "Corresponds to expression: `\"<\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LessThan , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_101 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#LessThan , "Corresponds to expression: `\"<\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#LessThan , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_102 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#LessThan<'i, INHERITED> {} - :: pest_typed :: rule ! (r#GreaterThan , "Corresponds to expression: `\">\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#GreaterThan , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_102 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#GreaterThan , "Corresponds to expression: `\">\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#GreaterThan , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_103 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#GreaterThan<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Dollar , "Corresponds to expression: `\"$\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Dollar , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_103 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Dollar , "Corresponds to expression: `\"$\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Dollar , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_104 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Dollar<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Assign , "Corresponds to expression: `\"=\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Assign , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_104 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Assign , "Corresponds to expression: `\"=\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Assign , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_105 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Assign<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Comma , "Corresponds to expression: `\",\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Comma , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_105 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Comma , "Corresponds to expression: `\",\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Comma , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_106 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Comma<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Dot , "Corresponds to expression: `\".\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Dot , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_106 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Dot , "Corresponds to expression: `\".\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Dot , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_107 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Dot<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Dot2 , "Corresponds to expression: `\"..\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Dot2 , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_107 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Dot2 , "Corresponds to expression: `\"..\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Dot2 , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_108 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Dot2<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Colon , "Corresponds to expression: `\":\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Colon , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_108 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Colon , "Corresponds to expression: `\":\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Colon , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_109 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Colon<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Colon2 , "Corresponds to expression: `\"::\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Colon2 , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_109 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Colon2 , "Corresponds to expression: `\"::\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Colon2 , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_110 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Colon2<'i, INHERITED> {} - :: pest_typed :: rule ! (r#SemiColon , "Corresponds to expression: `\";\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#SemiColon , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_110 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#SemiColon , "Corresponds to expression: `\";\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#SemiColon , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_111 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#SemiColon<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Hash , "Corresponds to expression: `\"#\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Hash , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_111 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Hash , "Corresponds to expression: `\"#\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Hash , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_112 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Hash<'i, INHERITED> {} - :: pest_typed :: rule ! (r#And , "Corresponds to expression: `\"&\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#And , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_112 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#And , "Corresponds to expression: `\"&\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#And , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_113 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#And<'i, INHERITED> {} - :: pest_typed :: rule ! (r#AndAnd , "Corresponds to expression: `\"&&\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#AndAnd , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_113 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#AndAnd , "Corresponds to expression: `\"&&\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#AndAnd , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_114 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#AndAnd<'i, INHERITED> {} - :: pest_typed :: rule ! (r#OrOr , "Corresponds to expression: `\"||\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OrOr , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_114 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#OrOr , "Corresponds to expression: `\"||\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OrOr , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_115 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#OrOr<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Bang , "Corresponds to expression: `\"!\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Bang , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_115 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Bang , "Corresponds to expression: `\"!\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Bang , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_116 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Bang<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Question , "Corresponds to expression: `\"?\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Question , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_116 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Question , "Corresponds to expression: `\"?\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Question , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_117 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Question<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Star , "Corresponds to expression: `\"*\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Star , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_117 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Star , "Corresponds to expression: `\"*\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Star , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_118 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Star<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Arrow , "Corresponds to expression: `\"->\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Arrow , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_118 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Arrow , "Corresponds to expression: `\"->\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Arrow , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_119 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Arrow<'i, INHERITED> {} - :: pest_typed :: rule ! (r#RightArrow , "Corresponds to expression: `\"=>\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightArrow , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_119 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#RightArrow , "Corresponds to expression: `\"=>\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#RightArrow , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_120 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#RightArrow<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Quote , "Corresponds to expression: `\"'\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Quote , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_120 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Quote , "Corresponds to expression: `\"'\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Quote , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_121 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Quote<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Plus , "Corresponds to expression: `\"+\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Plus , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_121 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Plus , "Corresponds to expression: `\"+\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Plus , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_122 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Plus<'i, INHERITED> {} - :: pest_typed :: rule ! (r#Minus , "Corresponds to expression: `\"-\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Minus , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_122 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#Minus , "Corresponds to expression: `\"-\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Minus , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_123 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Minus<'i, INHERITED> {} - :: pest_typed :: rule ! (r#PlaceHolder , "Corresponds to expression: `\"_\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#PlaceHolder , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_123 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#PlaceHolder , "Corresponds to expression: `\"_\"`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#PlaceHolder , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_124 > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#PlaceHolder<'i, INHERITED> {} :: pest_typed :: rule ! (r#Literal , "Corresponds to expression: `(Integer | String | Bool)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Literal , super :: super :: generics :: Choice3 :: < super :: super :: rules :: r#Integer :: < 'i , INHERITED > , super :: super :: rules :: r#String :: < 'i , INHERITED > , super :: super :: rules :: r#Bool :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Literal<'i, INHERITED> { @@ -1653,13 +1670,13 @@ pub mod rules_impl { impl<'i, const INHERITED: ::core::primitive::usize> r#DEC_DIGIT<'i, INHERITED> {} :: pest_typed :: rule ! (r#HEX_DIGIT , "Corresponds to expression: `(('0'..'9') | ('a'..'f') | ('A'..'F'))`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#HEX_DIGIT , super :: super :: generics :: Choice3 :: < super :: super :: generics :: CharRange :: < '0' , '9' > , super :: super :: generics :: CharRange :: < 'a' , 'f' > , super :: super :: generics :: CharRange :: < 'A' , 'F' > , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#HEX_DIGIT<'i, INHERITED> {} - :: pest_typed :: rule ! (r#DEC_LITERAL , "Corresponds to expression: `(DEC_DIGIT ~ (DEC_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#DEC_LITERAL , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#DEC_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#DEC_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_124 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#DEC_LITERAL , "Corresponds to expression: `(DEC_DIGIT ~ (DEC_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#DEC_LITERAL , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#DEC_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#DEC_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_125 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#DEC_LITERAL<'i, INHERITED> {} - :: pest_typed :: rule ! (r#BIN_LITERAL , "Corresponds to expression: `(\"0b\" ~ (BIN_DIGIT | \"_\")* ~ BIN_DIGIT ~ (BIN_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#BIN_LITERAL , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_125 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#BIN_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_126 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#BIN_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#BIN_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_127 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#BIN_LITERAL , "Corresponds to expression: `(\"0b\" ~ (BIN_DIGIT | \"_\")* ~ BIN_DIGIT ~ (BIN_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#BIN_LITERAL , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_126 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#BIN_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_127 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#BIN_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#BIN_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_128 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#BIN_LITERAL<'i, INHERITED> {} - :: pest_typed :: rule ! (r#OCT_LITERAL , "Corresponds to expression: `(\"0o\" ~ (OCT_DIGIT | \"_\")* ~ OCT_DIGIT ~ (OCT_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OCT_LITERAL , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_128 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#OCT_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_129 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#OCT_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#OCT_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_130 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#OCT_LITERAL , "Corresponds to expression: `(\"0o\" ~ (OCT_DIGIT | \"_\")* ~ OCT_DIGIT ~ (OCT_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OCT_LITERAL , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_129 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#OCT_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_130 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#OCT_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#OCT_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_131 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#OCT_LITERAL<'i, INHERITED> {} - :: pest_typed :: rule ! (r#HEX_LITERAL , "Corresponds to expression: `(\"0x\" ~ (HEX_DIGIT | \"_\")* ~ HEX_DIGIT ~ (HEX_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#HEX_LITERAL , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_131 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#HEX_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_132 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#HEX_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#HEX_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_133 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#HEX_LITERAL , "Corresponds to expression: `(\"0x\" ~ (HEX_DIGIT | \"_\")* ~ HEX_DIGIT ~ (HEX_DIGIT | \"_\")*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#HEX_LITERAL , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_132 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#HEX_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_133 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#HEX_DIGIT :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#HEX_DIGIT :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_134 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#HEX_LITERAL<'i, INHERITED> {} :: pest_typed :: rule ! (r#IntegerSuffix , "Corresponds to expression: `(kw_u8 | kw_u16 | kw_u32 | kw_u64 | kw_usize | kw_i8 | kw_i16 | kw_i32 | kw_i64 | kw_isize)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#IntegerSuffix , super :: super :: generics :: Choice10 :: < super :: super :: rules :: r#kw_u8 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_u16 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_u32 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_u64 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_usize :: < 'i , INHERITED > , super :: super :: rules :: r#kw_i8 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_i16 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_i32 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_i64 :: < 'i , INHERITED > , super :: super :: rules :: r#kw_isize :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#IntegerSuffix<'i, INHERITED> { @@ -1983,7 +2000,7 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#String , "Corresponds to expression: `(\"\\\"\" ~ (!(\"\\\"\") ~ ANY)* ~ \"\\\"\")`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#String , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_134 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Skip :: < super :: super :: constant_wrappers :: r#w_135 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_136 > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#String , "Corresponds to expression: `(\"\\\"\" ~ (!(\"\\\"\") ~ ANY)* ~ \"\\\"\")`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#String , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_135 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Skip :: < super :: super :: constant_wrappers :: r#w_136 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_137 > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#String<'i, INHERITED> {} :: pest_typed :: rule ! (r#Bool , "Corresponds to expression: `(kw_true | kw_false)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Bool , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#kw_true :: < 'i , INHERITED > , super :: super :: rules :: r#kw_false :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Bool<'i, INHERITED> { @@ -2012,7 +2029,7 @@ pub mod rules_impl { } :: pest_typed :: rule ! (r#WordLeading , "Corresponds to expression: `(('a'..'z') | ('A'..'Z') | ('一'..'龥') | ('_'..'_'))`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#WordLeading , super :: super :: generics :: Choice4 :: < super :: super :: generics :: CharRange :: < 'a' , 'z' > , super :: super :: generics :: CharRange :: < 'A' , 'Z' > , super :: super :: generics :: CharRange :: < '一' , '龥' > , super :: super :: generics :: CharRange :: < '_' , '_' > , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#WordLeading<'i, INHERITED> {} - :: pest_typed :: rule ! (r#WordFollowing , "Corresponds to expression: `(WordLeading | \"_\" | \"-\" | ('0'..'9'))`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#WordFollowing , super :: super :: generics :: Choice4 :: < super :: super :: rules :: r#WordLeading :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_137 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_138 > , super :: super :: generics :: CharRange :: < '0' , '9' > , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#WordFollowing , "Corresponds to expression: `(WordLeading | \"_\" | \"-\" | ('0'..'9'))`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#WordFollowing , super :: super :: generics :: Choice4 :: < super :: super :: rules :: r#WordLeading :: < 'i , 0 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_138 > , super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_139 > , super :: super :: generics :: CharRange :: < '0' , '9' > , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#WordFollowing<'i, INHERITED> {} :: pest_typed :: rule ! (r#Word , "Corresponds to expression: `(WordLeading ~ WordFollowing*)`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Word , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#WordLeading :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: rules :: r#WordFollowing :: < 'i , 0 > > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Word<'i, INHERITED> {} @@ -3478,6 +3495,41 @@ pub mod rules_impl { } } } + :: pest_typed :: rule ! (r#OpRef , "Corresponds to expression: `(MetaVariable ~ Colon2 ~ MetaVariable)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OpRef , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#MetaVariable :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Colon2 :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#MetaVariable :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#OpRef<'i, INHERITED> { + #[doc = "A helper function to access [`Colon2`]."] + #[allow(non_snake_case)] + pub fn r#Colon2<'s>(&'s self) -> &'s super::super::rules::r#Colon2<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.1.matched; + res + } + } + #[doc = "A helper function to access [`MetaVariable`]."] + #[allow(non_snake_case)] + pub fn r#MetaVariable<'s>( + &'s self, + ) -> ( + &'s super::super::rules::r#MetaVariable<'i, INHERITED>, + &'s super::super::rules::r#MetaVariable<'i, INHERITED>, + ) { + let res = &*self.content; + { + let res = ( + { + let res = &res.content.0.matched; + res + }, + { + let res = &res.content.2.matched; + res + }, + ); + res + } + } + } :: pest_typed :: rule ! (r#Konst , "Corresponds to expression: `(Literal | TypePath)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Konst , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#Literal :: < 'i , INHERITED > , super :: super :: rules :: r#TypePath :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Konst<'i, INHERITED> { #[doc = "A helper function to access [`Literal`]."] @@ -3938,7 +3990,7 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#TypeGroup , "Corresponds to expression: `(\"Group\" ~ Type)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#TypeGroup , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_139 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Type :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + :: pest_typed :: rule ! (r#TypeGroup , "Corresponds to expression: `(\"Group\" ~ Type)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#TypeGroup , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_140 > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Type :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#TypeGroup<'i, INHERITED> { #[doc = "A helper function to access [`Type`]."] #[allow(non_snake_case)] @@ -6716,7 +6768,7 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#MirFnOperand , "Corresponds to expression: `((LeftParen ~ MirOperandCopy ~ RightParen) | (LeftParen ~ MirOperandMove ~ RightParen) | TypePath | LangItemWithArgs | MetaVariable)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#MirFnOperand , super :: super :: generics :: Choice5 :: < super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#MirOperandCopy :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#MirOperandMove :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: rules :: r#TypePath :: < 'i , INHERITED > , super :: super :: rules :: r#LangItemWithArgs :: < 'i , INHERITED > , super :: super :: rules :: r#MetaVariable :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + :: pest_typed :: rule ! (r#MirFnOperand , "Corresponds to expression: `((LeftParen ~ MirOperandCopy ~ RightParen) | (LeftParen ~ MirOperandMove ~ RightParen) | TypePath | LangItemWithArgs | OpRef | MetaVariable)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#MirFnOperand , super :: super :: generics :: Choice6 :: < super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#MirOperandCopy :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#MirOperandMove :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: rules :: r#TypePath :: < 'i , INHERITED > , super :: super :: rules :: r#LangItemWithArgs :: < 'i , INHERITED > , super :: super :: rules :: r#OpRef :: < 'i , INHERITED > , super :: super :: rules :: r#MetaVariable :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#MirFnOperand<'i, INHERITED> { #[doc = "A helper function to access [`LangItemWithArgs`]."] #[allow(non_snake_case)] @@ -6766,7 +6818,7 @@ pub mod rules_impl { ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#MetaVariable<'i, INHERITED>> { let res = &*self.content; { - let res = res._4().map(|res| res); + let res = res._5().map(|res| res); res } } @@ -6800,6 +6852,17 @@ pub mod rules_impl { res } } + #[doc = "A helper function to access [`OpRef`]."] + #[allow(non_snake_case)] + pub fn r#OpRef<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#OpRef<'i, INHERITED>> { + let res = &*self.content; + { + let res = res._4().map(|res| res); + res + } + } #[doc = "A helper function to access [`RightParen`]."] #[allow(non_snake_case)] pub fn r#RightParen<'s>( @@ -9646,7 +9709,7 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#diagMessageText , "Corresponds to expression: `(!(\"\\\"\" | LeftBrace) ~ ANY)+`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagMessageText , super :: super :: generics :: RepOnce :: < 'i , 0 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: generics :: Choice2 :: < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_140 > , super :: super :: rules :: r#LeftBrace :: < 'i , 0 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#ANY , super :: super :: generics :: Skipped < 'i > , 0 >) , > > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); + :: pest_typed :: rule ! (r#diagMessageText , "Corresponds to expression: `(!(\"\\\"\" | LeftBrace) ~ ANY)+`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagMessageText , super :: super :: generics :: RepOnce :: < 'i , 0 , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Negative :: < super :: super :: generics :: Choice2 :: < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_141 > , super :: super :: rules :: r#LeftBrace :: < 'i , 0 > , > > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#ANY , super :: super :: generics :: Skipped < 'i > , 0 >) , > > , super :: super :: generics :: Skipped :: < 'i > , true , Span , true); impl<'i, const INHERITED: ::core::primitive::usize> r#diagMessageText<'i, INHERITED> {} :: pest_typed :: rule ! (r#diagMessageInner , "Corresponds to expression: `(diagMessageArg | diagMessageText)*`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagMessageInner , super :: super :: generics :: Rep :: < 'i , 0 , super :: super :: generics :: Choice2 :: < super :: super :: rules :: r#diagMessageArg :: < 'i , 0 > , super :: super :: rules :: r#diagMessageText :: < 'i , 0 > , > > , super :: super :: generics :: Skipped :: < 'i > , true , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#diagMessageInner<'i, INHERITED> { @@ -9697,7 +9760,7 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#diagMessage , "Corresponds to expression: `(\"\\\"\" ~ diagMessageInner ~ \"\\\"\")`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagMessage , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_141 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagMessageInner :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_142 > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Both , true); + :: pest_typed :: rule ! (r#diagMessage , "Corresponds to expression: `(\"\\\"\" ~ diagMessageInner ~ \"\\\"\")`. Atomic rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagMessage , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_142 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagMessageInner :: < 'i , 0 > , super :: super :: generics :: Skipped < 'i > , 0 >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Str :: < super :: super :: constant_wrappers :: r#w_143 > , super :: super :: generics :: Skipped < 'i > , 0 >) , > , super :: super :: generics :: Skipped :: < 'i > , true , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#diagMessage<'i, INHERITED> { #[doc = "A helper function to access [`diagMessageInner`]."] #[allow(non_snake_case)] @@ -9974,35 +10037,236 @@ pub mod rules_impl { } } } - #[doc = "A helper function to access [`diagAttrs`]."] + #[doc = "A helper function to access [`diagAttrs`]."] + #[allow(non_snake_case)] + pub fn r#diagAttrs<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#diagAttrs<'i, INHERITED>> { + let res = &*self.content; + { + let res = &res.content.1.matched; + { + let res = res.as_ref().map(|res| { + let res = &res.content.1.matched; + res + }); + res + } + } + } + #[doc = "A helper function to access [`diagMessage`]."] + #[allow(non_snake_case)] + pub fn r#diagMessage<'s>(&'s self) -> &'s super::super::rules::r#diagMessage<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.3.matched; + res + } + } + } + :: pest_typed :: rule ! (r#diagItems , "Corresponds to expression: `(diagItem ~ (Comma ~ diagItem)* ~ Comma?)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagItems , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagItem :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Comma :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagItem :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#Comma :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#diagItems<'i, INHERITED> { + #[doc = "A helper function to access [`Comma`]."] + #[allow(non_snake_case)] + pub fn r#Comma<'s>( + &'s self, + ) -> ( + ::pest_typed::re_exported::Vec<&'s super::super::rules::r#Comma<'i, INHERITED>>, + ::pest_typed::re_exported::Option<&'s super::super::rules::r#Comma<'i, INHERITED>>, + ) { + let res = &*self.content; + { + let res = ( + { + let res = &res.content.1.matched; + { + let res = res + .content + .iter() + .map(|res| { + let res = &res.matched; + { + let res = &res.content.0.matched; + res + } + }) + .collect::<::pest_typed::re_exported::Vec<_>>(); + res + } + }, + { + let res = &res.content.2.matched; + { + let res = res.as_ref().map(|res| res); + res + } + }, + ); + res + } + } + #[doc = "A helper function to access [`diagItem`]."] + #[allow(non_snake_case)] + pub fn r#diagItem<'s>( + &'s self, + ) -> ( + &'s super::super::rules::r#diagItem<'i, INHERITED>, + ::pest_typed::re_exported::Vec<&'s super::super::rules::r#diagItem<'i, INHERITED>>, + ) { + let res = &*self.content; + { + let res = ( + { + let res = &res.content.0.matched; + res + }, + { + let res = &res.content.1.matched; + { + let res = res + .content + .iter() + .map(|res| { + let res = &res.matched; + { + let res = &res.content.1.matched; + res + } + }) + .collect::<::pest_typed::re_exported::Vec<_>>(); + res + } + }, + ); + res + } + } + } + :: pest_typed :: rule ! (r#diagBlockItem , "Corresponds to expression: `(Identifier ~ Assign ~ LeftBrace ~ diagItems ~ MetaVariableWithDiagMessageSeparatedByComma? ~ RightBrace)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagBlockItem , super :: super :: generics :: Seq6 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Identifier :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Assign :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagItems :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#MetaVariableWithDiagMessageSeparatedByComma :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#diagBlockItem<'i, INHERITED> { + #[doc = "A helper function to access [`Assign`]."] + #[allow(non_snake_case)] + pub fn r#Assign<'s>(&'s self) -> &'s super::super::rules::r#Assign<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.1.matched; + res + } + } + #[doc = "A helper function to access [`Identifier`]."] + #[allow(non_snake_case)] + pub fn r#Identifier<'s>(&'s self) -> &'s super::super::rules::r#Identifier<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.0.matched; + res + } + } + #[doc = "A helper function to access [`LeftBrace`]."] + #[allow(non_snake_case)] + pub fn r#LeftBrace<'s>(&'s self) -> &'s super::super::rules::r#LeftBrace<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.2.matched; + res + } + } + #[doc = "A helper function to access [`MetaVariableWithDiagMessageSeparatedByComma`]."] + #[allow(non_snake_case)] + pub fn r#MetaVariableWithDiagMessageSeparatedByComma<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option< + &'s super::super::rules::r#MetaVariableWithDiagMessageSeparatedByComma<'i, INHERITED>, + > { + let res = &*self.content; + { + let res = &res.content.4.matched; + { + let res = res.as_ref().map(|res| res); + res + } + } + } + #[doc = "A helper function to access [`RightBrace`]."] + #[allow(non_snake_case)] + pub fn r#RightBrace<'s>(&'s self) -> &'s super::super::rules::r#RightBrace<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.5.matched; + res + } + } + #[doc = "A helper function to access [`diagItems`]."] + #[allow(non_snake_case)] + pub fn r#diagItems<'s>(&'s self) -> &'s super::super::rules::r#diagItems<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.3.matched; + res + } + } + } + :: pest_typed :: rule ! (r#OpFnParam , "Corresponds to expression: `(SelfParam | NormalParam | PlaceHolderWithType | Type | Dot2)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OpFnParam , super :: super :: generics :: Choice5 :: < super :: super :: rules :: r#SelfParam :: < 'i , INHERITED > , super :: super :: rules :: r#NormalParam :: < 'i , INHERITED > , super :: super :: rules :: r#PlaceHolderWithType :: < 'i , INHERITED > , super :: super :: rules :: r#Type :: < 'i , INHERITED > , super :: super :: rules :: r#Dot2 :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#OpFnParam<'i, INHERITED> { + #[doc = "A helper function to access [`Dot2`]."] + #[allow(non_snake_case)] + pub fn r#Dot2<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#Dot2<'i, INHERITED>> { + let res = &*self.content; + { + let res = res._4().map(|res| res); + res + } + } + #[doc = "A helper function to access [`NormalParam`]."] + #[allow(non_snake_case)] + pub fn r#NormalParam<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#NormalParam<'i, INHERITED>> { + let res = &*self.content; + { + let res = res._1().map(|res| res); + res + } + } + #[doc = "A helper function to access [`PlaceHolderWithType`]."] + #[allow(non_snake_case)] + pub fn r#PlaceHolderWithType<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#PlaceHolderWithType<'i, INHERITED>> + { + let res = &*self.content; + { + let res = res._2().map(|res| res); + res + } + } + #[doc = "A helper function to access [`SelfParam`]."] #[allow(non_snake_case)] - pub fn r#diagAttrs<'s>( + pub fn r#SelfParam<'s>( &'s self, - ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#diagAttrs<'i, INHERITED>> { + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#SelfParam<'i, INHERITED>> { let res = &*self.content; { - let res = &res.content.1.matched; - { - let res = res.as_ref().map(|res| { - let res = &res.content.1.matched; - res - }); - res - } + let res = res._0().map(|res| res); + res } } - #[doc = "A helper function to access [`diagMessage`]."] + #[doc = "A helper function to access [`Type`]."] #[allow(non_snake_case)] - pub fn r#diagMessage<'s>(&'s self) -> &'s super::super::rules::r#diagMessage<'i, INHERITED> { + pub fn r#Type<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#Type<'i, INHERITED>> { let res = &*self.content; { - let res = &res.content.3.matched; + let res = res._3().map(|res| res); res } } } - :: pest_typed :: rule ! (r#diagItems , "Corresponds to expression: `(diagItem ~ (Comma ~ diagItem)* ~ Comma?)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagItems , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagItem :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Comma :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagItem :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#Comma :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); - impl<'i, const INHERITED: ::core::primitive::usize> r#diagItems<'i, INHERITED> { + :: pest_typed :: rule ! (r#OpFnParamsSeparatedByComma , "Corresponds to expression: `(OpFnParam ~ (Comma ~ OpFnParam)* ~ Comma?)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OpFnParamsSeparatedByComma , super :: super :: generics :: Seq3 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#OpFnParam :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Comma :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#OpFnParam :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#Comma :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#OpFnParamsSeparatedByComma<'i, INHERITED> { #[doc = "A helper function to access [`Comma`]."] #[allow(non_snake_case)] pub fn r#Comma<'s>( @@ -10042,13 +10306,13 @@ pub mod rules_impl { res } } - #[doc = "A helper function to access [`diagItem`]."] + #[doc = "A helper function to access [`OpFnParam`]."] #[allow(non_snake_case)] - pub fn r#diagItem<'s>( + pub fn r#OpFnParam<'s>( &'s self, ) -> ( - &'s super::super::rules::r#diagItem<'i, INHERITED>, - ::pest_typed::re_exported::Vec<&'s super::super::rules::r#diagItem<'i, INHERITED>>, + &'s super::super::rules::r#OpFnParam<'i, INHERITED>, + ::pest_typed::re_exported::Vec<&'s super::super::rules::r#OpFnParam<'i, INHERITED>>, ) { let res = &*self.content; { @@ -10079,23 +10343,161 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#diagBlockItem , "Corresponds to expression: `(Identifier ~ Assign ~ LeftBrace ~ diagItems ~ MetaVariableWithDiagMessageSeparatedByComma? ~ RightBrace)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagBlockItem , super :: super :: generics :: Seq6 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Identifier :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Assign :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#diagItems :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#MetaVariableWithDiagMessageSeparatedByComma :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); - impl<'i, const INHERITED: ::core::primitive::usize> r#diagBlockItem<'i, INHERITED> { + :: pest_typed :: rule ! (r#OpFnSig , "Corresponds to expression: `(Visibility? ~ Safety? ~ kw_fn ~ FnName ~ LeftParen ~ OpFnParamsSeparatedByComma? ~ RightParen ~ FnRet?)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OpFnSig , super :: super :: generics :: Seq8 :: < (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#Visibility :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#Safety :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#kw_fn :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#FnName :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#OpFnParamsSeparatedByComma :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightParen :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#FnRet :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#OpFnSig<'i, INHERITED> { + #[doc = "A helper function to access [`FnName`]."] + #[allow(non_snake_case)] + pub fn r#FnName<'s>(&'s self) -> &'s super::super::rules::r#FnName<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.3.matched; + res + } + } + #[doc = "A helper function to access [`FnRet`]."] + #[allow(non_snake_case)] + pub fn r#FnRet<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#FnRet<'i, INHERITED>> { + let res = &*self.content; + { + let res = &res.content.7.matched; + { + let res = res.as_ref().map(|res| res); + res + } + } + } + #[doc = "A helper function to access [`LeftParen`]."] + #[allow(non_snake_case)] + pub fn r#LeftParen<'s>(&'s self) -> &'s super::super::rules::r#LeftParen<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.4.matched; + res + } + } + #[doc = "A helper function to access [`OpFnParamsSeparatedByComma`]."] + #[allow(non_snake_case)] + pub fn r#OpFnParamsSeparatedByComma<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#OpFnParamsSeparatedByComma<'i, INHERITED>> + { + let res = &*self.content; + { + let res = &res.content.5.matched; + { + let res = res.as_ref().map(|res| res); + res + } + } + } + #[doc = "A helper function to access [`RightParen`]."] + #[allow(non_snake_case)] + pub fn r#RightParen<'s>(&'s self) -> &'s super::super::rules::r#RightParen<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.6.matched; + res + } + } + #[doc = "A helper function to access [`Safety`]."] + #[allow(non_snake_case)] + pub fn r#Safety<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#Safety<'i, INHERITED>> { + let res = &*self.content; + { + let res = &res.content.1.matched; + { + let res = res.as_ref().map(|res| res); + res + } + } + } + #[doc = "A helper function to access [`Visibility`]."] + #[allow(non_snake_case)] + pub fn r#Visibility<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#Visibility<'i, INHERITED>> { + let res = &*self.content; + { + let res = &res.content.0.matched; + { + let res = res.as_ref().map(|res| res); + res + } + } + } + #[doc = "A helper function to access [`kw_fn`]."] + #[allow(non_snake_case)] + pub fn r#kw_fn<'s>(&'s self) -> &'s super::super::rules::r#kw_fn<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.2.matched; + res + } + } + } + :: pest_typed :: rule ! (r#OpFnDecl , "Corresponds to expression: `(OpFnSig ~ SemiColon)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#OpFnDecl , super :: super :: generics :: Seq2 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#OpFnSig :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#SemiColon :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#OpFnDecl<'i, INHERITED> { + #[doc = "A helper function to access [`OpFnSig`]."] + #[allow(non_snake_case)] + pub fn r#OpFnSig<'s>(&'s self) -> &'s super::super::rules::r#OpFnSig<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.0.matched; + res + } + } + #[doc = "A helper function to access [`SemiColon`]."] + #[allow(non_snake_case)] + pub fn r#SemiColon<'s>(&'s self) -> &'s super::super::rules::r#SemiColon<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.1.matched; + res + } + } + } + :: pest_typed :: rule ! (r#opsItem , "Corresponds to expression: `(Attr* ~ Identifier ~ MetaVariableDeclList? ~ Assign ~ LeftBrace ~ OpFnDecl+ ~ RightBrace)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#opsItem , super :: super :: generics :: Seq7 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: rules :: r#Attr :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Identifier :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < :: pest_typed :: re_exported :: Option :: < super :: super :: rules :: r#MetaVariableDeclList :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#Assign :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: RepOnce :: < 'i , INHERITED , super :: super :: rules :: r#OpFnDecl :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#opsItem<'i, INHERITED> { #[doc = "A helper function to access [`Assign`]."] #[allow(non_snake_case)] pub fn r#Assign<'s>(&'s self) -> &'s super::super::rules::r#Assign<'i, INHERITED> { let res = &*self.content; { - let res = &res.content.1.matched; + let res = &res.content.3.matched; res } } + #[doc = "A helper function to access [`Attr`]."] + #[allow(non_snake_case)] + pub fn r#Attr<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Vec<&'s super::super::rules::r#Attr<'i, INHERITED>> { + let res = &*self.content; + { + let res = &res.content.0.matched; + { + let res = res + .content + .iter() + .map(|res| { + let res = &res.matched; + res + }) + .collect::<::pest_typed::re_exported::Vec<_>>(); + res + } + } + } #[doc = "A helper function to access [`Identifier`]."] #[allow(non_snake_case)] pub fn r#Identifier<'s>(&'s self) -> &'s super::super::rules::r#Identifier<'i, INHERITED> { let res = &*self.content; { - let res = &res.content.0.matched; + let res = &res.content.1.matched; res } } @@ -10104,41 +10506,52 @@ pub mod rules_impl { pub fn r#LeftBrace<'s>(&'s self) -> &'s super::super::rules::r#LeftBrace<'i, INHERITED> { let res = &*self.content; { - let res = &res.content.2.matched; + let res = &res.content.4.matched; res } } - #[doc = "A helper function to access [`MetaVariableWithDiagMessageSeparatedByComma`]."] + #[doc = "A helper function to access [`MetaVariableDeclList`]."] #[allow(non_snake_case)] - pub fn r#MetaVariableWithDiagMessageSeparatedByComma<'s>( + pub fn r#MetaVariableDeclList<'s>( &'s self, - ) -> ::pest_typed::re_exported::Option< - &'s super::super::rules::r#MetaVariableWithDiagMessageSeparatedByComma<'i, INHERITED>, - > { + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#MetaVariableDeclList<'i, INHERITED>> + { let res = &*self.content; { - let res = &res.content.4.matched; + let res = &res.content.2.matched; { let res = res.as_ref().map(|res| res); res } } } - #[doc = "A helper function to access [`RightBrace`]."] + #[doc = "A helper function to access [`OpFnDecl`]."] #[allow(non_snake_case)] - pub fn r#RightBrace<'s>(&'s self) -> &'s super::super::rules::r#RightBrace<'i, INHERITED> { + pub fn r#OpFnDecl<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Vec<&'s super::super::rules::r#OpFnDecl<'i, INHERITED>> { let res = &*self.content; { let res = &res.content.5.matched; - res + { + let res = res + .content + .iter() + .map(|res| { + let res = &res.matched; + res + }) + .collect::<::pest_typed::re_exported::Vec<_>>(); + res + } } } - #[doc = "A helper function to access [`diagItems`]."] + #[doc = "A helper function to access [`RightBrace`]."] #[allow(non_snake_case)] - pub fn r#diagItems<'s>(&'s self) -> &'s super::super::rules::r#diagItems<'i, INHERITED> { + pub fn r#RightBrace<'s>(&'s self) -> &'s super::super::rules::r#RightBrace<'i, INHERITED> { let res = &*self.content; { - let res = &res.content.3.matched; + let res = &res.content.6.matched; res } } @@ -10287,6 +10700,57 @@ pub mod rules_impl { } } } + :: pest_typed :: rule ! (r#opsBlock , "Corresponds to expression: `(kw_ops ~ LeftBrace ~ opsItem* ~ RightBrace)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#opsBlock , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#kw_ops :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: rules :: r#opsItem :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); + impl<'i, const INHERITED: ::core::primitive::usize> r#opsBlock<'i, INHERITED> { + #[doc = "A helper function to access [`LeftBrace`]."] + #[allow(non_snake_case)] + pub fn r#LeftBrace<'s>(&'s self) -> &'s super::super::rules::r#LeftBrace<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.1.matched; + res + } + } + #[doc = "A helper function to access [`RightBrace`]."] + #[allow(non_snake_case)] + pub fn r#RightBrace<'s>(&'s self) -> &'s super::super::rules::r#RightBrace<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.3.matched; + res + } + } + #[doc = "A helper function to access [`kw_ops`]."] + #[allow(non_snake_case)] + pub fn r#kw_ops<'s>(&'s self) -> &'s super::super::rules::r#kw_ops<'i, INHERITED> { + let res = &*self.content; + { + let res = &res.content.0.matched; + res + } + } + #[doc = "A helper function to access [`opsItem`]."] + #[allow(non_snake_case)] + pub fn r#opsItem<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Vec<&'s super::super::rules::r#opsItem<'i, INHERITED>> { + let res = &*self.content; + { + let res = &res.content.2.matched; + { + let res = res + .content + .iter() + .map(|res| { + let res = &res.matched; + res + }) + .collect::<::pest_typed::re_exported::Vec<_>>(); + res + } + } + } + } :: pest_typed :: rule ! (r#diagBlock , "Corresponds to expression: `(kw_diag ~ LeftBrace ~ diagBlockItem* ~ RightBrace)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#diagBlock , super :: super :: generics :: Seq4 :: < (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#kw_diag :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#LeftBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: generics :: Rep :: < 'i , INHERITED , super :: super :: rules :: r#diagBlockItem :: < 'i , INHERITED > > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , (:: pest_typed :: predefined_node :: Skipped < super :: super :: rules :: r#RightBrace :: < 'i , INHERITED > , super :: super :: generics :: Skipped < 'i > , INHERITED >) , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Both , true); impl<'i, const INHERITED: ::core::primitive::usize> r#diagBlock<'i, INHERITED> { #[doc = "A helper function to access [`LeftBrace`]."] @@ -10338,13 +10802,24 @@ pub mod rules_impl { } } } - :: pest_typed :: rule ! (r#Block , "Corresponds to expression: `(pattBlock | utilBlock | diagBlock)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Block , super :: super :: generics :: Choice3 :: < super :: super :: rules :: r#pattBlock :: < 'i , INHERITED > , super :: super :: rules :: r#utilBlock :: < 'i , INHERITED > , super :: super :: rules :: r#diagBlock :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Expression , true); + :: pest_typed :: rule ! (r#Block , "Corresponds to expression: `(pattBlock | utilBlock | opsBlock | diagBlock)`. Normal rule." "" , super :: super :: Rule , super :: super :: Rule :: r#Block , super :: super :: generics :: Choice4 :: < super :: super :: rules :: r#pattBlock :: < 'i , INHERITED > , super :: super :: rules :: r#utilBlock :: < 'i , INHERITED > , super :: super :: rules :: r#opsBlock :: < 'i , INHERITED > , super :: super :: rules :: r#diagBlock :: < 'i , INHERITED > , > , super :: super :: generics :: Skipped :: < 'i > , INHERITED , Expression , true); impl<'i, const INHERITED: ::core::primitive::usize> r#Block<'i, INHERITED> { #[doc = "A helper function to access [`diagBlock`]."] #[allow(non_snake_case)] pub fn r#diagBlock<'s>( &'s self, ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#diagBlock<'i, INHERITED>> { + let res = &*self.content; + { + let res = res._3().map(|res| res); + res + } + } + #[doc = "A helper function to access [`opsBlock`]."] + #[allow(non_snake_case)] + pub fn r#opsBlock<'s>( + &'s self, + ) -> ::pest_typed::re_exported::Option<&'s super::super::rules::r#opsBlock<'i, INHERITED>> { let res = &*self.content; { let res = res._2().map(|res| res); diff --git a/crates/rpl_parser/tests/test.rs b/crates/rpl_parser/tests/test.rs index 5ae722af..71acff57 100644 --- a/crates/rpl_parser/tests/test.rs +++ b/crates/rpl_parser/tests/test.rs @@ -505,3 +505,77 @@ fn rvalue_cast() { fn mir_local_decl() { full_test!(MirLocalDecl, "let $q: DstVec = move $p as DstVec (Transmute);"); } + +#[test] +fn ops_block_basic() { + full_test!( + opsBlock, + "\ +ops { + sync[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + fn $unlock(&mut $U) -> _; + } +}" + ); +} + +#[test] +fn ops_block_no_meta_vars() { + full_test!( + opsBlock, + "\ +ops { + sync = { + fn $lock(); + } +}" + ); +} + +#[test] +fn ops_block_multiple_groups() { + full_test!( + opsBlock, + "\ +ops { + sync[$T: type] = { fn $lock(&mut $T) -> _; } + logger[$L: type] = { fn $log(&$L); } +}" + ); +} + +#[test] +fn ops_block_missing_semicolon_fails() { + use pest_typed::TypedParser as _; + let res = Grammar::try_parse::("ops { sync = { fn $lock() } }"); + assert!(res.is_err(), "expected parse error for missing semicolon"); +} + +#[test] +fn op_ref_as_callee() { + // $sync::$lock parses as an OpRef. + full_test!(OpRef, "$sync::$lock"); +} + +#[test] +fn op_ref_with_single_colon_fails() { + use pest_typed::TypedParser as _; + let res = Grammar::try_parse::("$sync:$lock"); + assert!(res.is_err(), "expected parse error: single colon is not allowed"); +} + +#[test] +fn op_ref_inside_let_rhs() { + full_test!( + main, + "\ +pattern foo +patt { + p[$T: type, $U: type] = fn _ (..) -> _ { + let $obj: $T = _; + let $g: $U = $sync::$lock(move $obj); + } +}" + ); +} diff --git a/crates/rpl_resolve/Cargo.toml b/crates/rpl_resolve/Cargo.toml index 982c7784..6495d4d4 100644 --- a/crates/rpl_resolve/Cargo.toml +++ b/crates/rpl_resolve/Cargo.toml @@ -10,6 +10,10 @@ repository.workspace = true [dependencies] +[dev-dependencies] +rpl_context.workspace = true +rpl_meta.workspace = true + [package.metadata.rust-analyzer] # This crate uses #[feature(rustc_private)] rustc_private = true \ No newline at end of file diff --git a/crates/rpl_resolve/tests/common/mod.rs b/crates/rpl_resolve/tests/common/mod.rs new file mode 100644 index 00000000..3d93f560 --- /dev/null +++ b/crates/rpl_resolve/tests/common/mod.rs @@ -0,0 +1,47 @@ +//! Shared boilerplate for ops integration tests. +//! +//! Mirrors `crates/rpl_context/tests/common/mod.rs`. See that file for the +//! design rationale. Duplicated here because Cargo integration tests in +//! different crates are independent binaries and cannot share a `tests/` +//! sub-module across crate boundaries without a dedicated dev-dep crate +//! (which would be heavier than the ~50 LOC duplicated below). + +#![allow(dead_code)] // not every test consumes every helper + +use std::path::PathBuf; +use std::sync::LazyLock; + +use rpl_meta::RPLMetaError; +use rpl_meta::arena::Arena; +use rpl_meta::context::MetaContext; + +/// Returns a shared, lazily-initialised `&'static Arena<'static>` for the +/// current integration-test binary. +pub fn shared_arena() -> &'static Arena<'static> { + static ARENA: LazyLock<&'static Arena<'static>> = LazyLock::new(|| Box::leak(Box::>::default())); + *ARENA +} + +/// Parse `src` and return a `'static` [`MetaContext`]. Panics on any +/// parse/collect error. +pub fn make_static_mctx(filename: &str, src: &str) -> &'static MetaContext<'static> { + make_static_mctx_with(filename, src, |err| { + panic!("RPL parse/collect error: {err}"); + }) +} + +/// Like [`make_static_mctx`] but lets the caller supply a custom error +/// handler. Used by R6 fixtures that intentionally feed malformed input. +pub fn make_static_mctx_with( + filename: &str, + src: &str, + handler: impl FnMut(&RPLMetaError<'static>), +) -> &'static MetaContext<'static> { + let path_and_content: &'static Vec<(PathBuf, String)> = + Box::leak(Box::new(vec![(PathBuf::from(filename), src.to_string())])); + Box::leak(Box::new(rpl_meta::parse_and_collect( + shared_arena(), + path_and_content, + handler, + ))) +} diff --git a/crates/rpl_resolve/tests/ops_resolve.rs b/crates/rpl_resolve/tests/ops_resolve.rs new file mode 100644 index 00000000..e7176e54 --- /dev/null +++ b/crates/rpl_resolve/tests/ops_resolve.rs @@ -0,0 +1,305 @@ +//! Resolver well-formedness checks for `ops { ... }` blocks. +//! +//! Tests R1, R2, and R3 — the checks that guard `OpsMetaLookup`'s +//! `unreachable!()` contracts against malformed input. +//! +//! These tests delegate to `rpl_context::pat::check_ops_block`, which is the +//! pre-lowering validator. The `rpl_resolve` crate itself handles Rust +//! def-path resolution (path → `DefId`); the ops well-formedness rules are +//! pattern-AST concerns that live in `rpl_context`. This file keeps the +//! specified test locations while delegating to the correct crate. + +#![allow(internal_features)] +#![feature(rustc_private)] +#![feature(rustc_attrs)] +#![feature(let_chains)] +#![feature(box_patterns)] +#![feature(debug_closure_helpers)] +#![recursion_limit = "256"] + +extern crate rustc_data_structures; +extern crate rustc_span; + +use rpl_context::PatternCtxt; +use rpl_context::pat::{check_ops_block, check_r6_patt_vs_ops}; + +mod common; +use common::{make_static_mctx, make_static_mctx_with}; + +// --------------------------------------------------------------------------- +// Helper: pre-lowering R1–R3 checks (ops block well-formedness) +// --------------------------------------------------------------------------- + +/// Parse `src`, run `check_ops_block` on every `opsBlock` found, and return +/// all error messages as display strings. +fn run_resolver_on_src(src: &str) -> Vec { + let mctx = make_static_mctx("test.rpl", src); + let mut errors = Vec::new(); + for syntax_tree in mctx.syntax_trees.iter() { + let (_, _, ops, _) = rpl_meta::meta::collect_blocks(syntax_tree); + for ops_block in ops { + let errs = check_ops_block(ops_block); + errors.extend(errs.into_iter().map(|e| e.to_string())); + } + } + errors +} + +// --------------------------------------------------------------------------- +// Helper: post-lowering R4–R5 checks (op-ref use-site validation) +// --------------------------------------------------------------------------- + +/// Parse, lower, and run R4/R5 use-site checks on `src`. +/// +/// `add_parsed_patterns` now automatically calls `check_and_populate_op_refs` +/// internally and stores errors in `Pattern::op_ref_errors`. This helper +/// collects them into a `Vec` for assertion. +/// +/// Panics if the source fails to parse (that's a test-fixture bug). +fn run_r4_r5_checks(src: &str) -> Vec { + let mctx = make_static_mctx("test_r4r5.rpl", src); + let mut all_errors: Vec = Vec::new(); + + PatternCtxt::entered_no_tcx(|pcx| { + pcx.add_parsed_patterns(mctx); + pcx.for_each_rpl_pattern(|_, pattern| { + all_errors.extend(pattern.op_ref_errors().iter().map(|e| e.to_string())); + }); + }); + + all_errors +} + +// --------------------------------------------------------------------------- +// Helper: pre-lowering R6 check (op-level meta-var leak into pattern body) +// --------------------------------------------------------------------------- + +/// Parse `src`, run `check_r6_patt_vs_ops`, and return all R6 error messages. +/// +/// Uses a **non-panicking** error handler so that `NonLocalMetaVariableNotDeclared` +/// errors from `parse_and_collect` do not abort the check. The R6 function +/// runs at parse-tree level — before any lowering that would panic. +fn run_r6_check(src: &str) -> Vec { + // Use a collecting (non-panicking) handler so the meta-collection phase + // does not abort even when undeclared meta-vars are encountered. + // Undeclared pattern-level meta-vars are exactly what R6 is meant to flag, + // so we want the collection phase to keep going. + let mctx = make_static_mctx_with("test_r6.rpl", src, |_err| {}); + + let mut errors = Vec::new(); + for syntax_tree in mctx.syntax_trees.iter() { + let (_, patts, ops, _) = rpl_meta::meta::collect_blocks(syntax_tree); + let errs = check_r6_patt_vs_ops(&ops, &patts); + errors.extend(errs.into_iter().map(|e| e.to_string())); + } + errors +} + +// --------------------------------------------------------------------------- +// R1: op-level meta-vars must be of kind `type` +// --------------------------------------------------------------------------- + +#[test] +fn r1_non_type_op_meta_var_is_rejected() { + let src = r#" +pattern test +ops { + sync[$N: const(usize)] = { fn $lock() -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errs = run_resolver_on_src(src); + assert!( + errs.iter().any(|e| e.contains("must be of kind 'type'")), + "R1: expected an error about non-type op-level meta-var, got: {errs:?}" + ); +} + +// --------------------------------------------------------------------------- +// R2: op signatures may only reference meta-vars from the same group +// --------------------------------------------------------------------------- + +#[test] +fn r2_op_signature_uses_undeclared_meta_var() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut $Z) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errs = run_resolver_on_src(src); + assert!( + errs.iter() + .any(|e| e.contains("'$Z' is not declared in op group 'sync'")), + "R2: expected undeclared-meta-var error, got: {errs:?}" + ); +} + +// --------------------------------------------------------------------------- +// R3: op signatures must not contain concrete Rust paths/types +// --------------------------------------------------------------------------- + +#[test] +fn r3_op_signature_with_concrete_path_is_rejected() { + let src = r#" +pattern test +ops { + sync[$T: type] = { fn $lock(&mut std::sync::Mutex<$T>) -> _; } +} +patt { p[] = fn _ () -> _ {} } +"#; + let errs = run_resolver_on_src(src); + assert!( + errs.iter().any(|e| e.contains("concrete types belong in rpl.toml")), + "R3: expected concrete-path error, got: {errs:?}" + ); +} + +// --------------------------------------------------------------------------- +// R4: $group::$op references must resolve to declared op groups and ops +// --------------------------------------------------------------------------- + +#[test] +fn r4_undeclared_op_group_is_rejected() { + // `$undeclared` is not in the ops block — R4a should fire. + let src = r#" +pattern test +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = $undeclared::$op(_); + } +} +"#; + let errs = run_r4_r5_checks(src); + assert!( + errs.iter().any(|e| e.contains("op group 'undeclared' is not declared")), + "R4: expected undeclared-group error, got: {errs:?}" + ); +} + +#[test] +fn r4_undeclared_op_in_group_is_rejected() { + // `$sync` group is declared but has no `$try_lock` — R4b should fire. + let src = r#" +pattern test +ops { sync[$T: type] = { fn $lock(&mut $T) -> _; } } +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = $sync::$try_lock(_); + } +} +"#; + let errs = run_r4_r5_checks(src); + assert!( + errs.iter() + .any(|e| e.contains("op 'try_lock' is not declared in op group 'sync'")), + "R4: expected undeclared-op-in-group error, got: {errs:?}" + ); +} + +#[test] +fn r4_valid_op_ref_is_accepted() { + // A valid `$sync::$lock` should produce no R4 errors. + let src = r#" +pattern test +ops { sync[$T: type] = { fn $lock(&mut $T) -> _; } } +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = $sync::$lock(_); + } +} +"#; + let errs = run_r4_r5_checks(src); + let r4_errs: Vec<_> = errs.iter().filter(|e| e.contains("is not declared")).collect(); + assert!( + r4_errs.is_empty(), + "R4: no error expected for valid op ref, got: {r4_errs:?}" + ); +} + +// --------------------------------------------------------------------------- +// R5: Op-call arity must match the op signature's arity +// --------------------------------------------------------------------------- + +#[test] +fn r5_arity_mismatch_at_call_site() { + // `$sync::$lock` expects 1 arg (`&mut $T`) but is called with 0. + let src = r#" +pattern test +ops { sync[$T: type] = { fn $lock(&mut $T) -> _; } } +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = $sync::$lock(); + } +} +"#; + let errs = run_r4_r5_checks(src); + assert!( + errs.iter().any(|e| e.contains("arity")), + "R5: expected arity-mismatch error, got: {errs:?}" + ); +} + +#[test] +fn r5_correct_arity_is_accepted() { + // `$sync::$lock` expects 1 arg and is called with 1. + let src = r#" +pattern test +ops { sync[$T: type] = { fn $lock(&mut $T) -> _; } } +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = $sync::$lock(_); + } +} +"#; + let errs = run_r4_r5_checks(src); + let r5_errs: Vec<_> = errs.iter().filter(|e| e.contains("arity")).collect(); + assert!(r5_errs.is_empty(), "R5: no arity error expected, got: {r5_errs:?}"); +} + +// --------------------------------------------------------------------------- +// R6: Pattern bodies must not reference op-level meta-vars +// --------------------------------------------------------------------------- + +#[test] +fn r6_op_level_meta_var_leaks_into_pattern_body() { + // `$T` is declared in `sync[$T]` (op-level) but NOT in `p[]`. + // Using `$T` in the pattern body is an R6 violation. + let src = r#" +pattern test +ops { sync[$T: type] = { fn $lock(&mut $T) -> _; } } +patt { + p[] = fn _ (..) -> _ { + let $x: $T = _; + } +} +"#; + let errs = run_r6_check(src); + assert!( + errs.iter() + .any(|e| e.contains("op-level meta-var '$T' cannot appear in a pattern body")), + "R6: expected op-level-leak error, got: {errs:?}" + ); +} + +#[test] +fn r6_pattern_level_meta_var_is_accepted() { + // `$T` is declared at both pattern level `p[$T]` and op level `sync[$T]`. + // The pattern body's `$T` refers to the pattern-level one — no R6 error. + let src = r#" +pattern test +ops { sync[$T: type] = { fn $lock(&mut $T) -> _; } } +patt { + p[$T: type] = fn _ (..) -> _ { + let $x: $T = _; + } +} +"#; + let errs = run_r6_check(src); + let r6_errs: Vec<_> = errs.iter().filter(|e| e.contains("op-level meta-var")).collect(); + assert!( + r6_errs.is_empty(), + "R6: no error expected when pattern-level $T shadows op-level $T, got: {r6_errs:?}" + ); +} diff --git a/rpl.toml b/rpl.toml new file mode 100644 index 00000000..1e0b80b5 --- /dev/null +++ b/rpl.toml @@ -0,0 +1,141 @@ +# RPL workspace configuration. +# +# [[ops.]] entries provide concrete instances of abstract op groups +# declared in .rpl pattern files. Any pattern file that declares +# `ops { [...] = { ... } }` will receive these instances at match time. +# +# Substitution model (three layers, see resolve_one in ops_resolved.rs): +# +# 1. `type = ["$1", "$2", ...]` declares the EXISTENTIAL "free" placeholders +# that remain in the final expanded paths. At match time the matcher +# strips `<...>` brackets and splits on `::` before DefId comparison, so +# these placeholders are effectively wildcards on the generic args. +# +# 2. Each TYPE meta-var binding (the bare-uppercase keys: `T`, `U`, `L`, +# `G`, `List`, ...) is a string that may reference the existential +# placeholders (`$1`, `$2`, ...) declared above. These bindings define +# the *concrete* path each abstract type meta-var resolves to. +# +# 3. Each OP-NAME binding (the lowercase keys: `lock`, `unlock`, `log`, ...) +# is a string that may reference any of the TYPE meta-vars (`$T`, `$L`, +# ...) AND the existential placeholders (`$1`, ...). This lets each +# op binding be written once in terms of its type meta-var, so the +# concrete path only needs to be spelled out at the type-binding layer. +# +# The resolver runs a fixed-point textual substitution over all bindings (up +# to 16 passes) — every `$` reference is expanded into its +# binding value before the matcher sees the result. `$` +# references (like `$1`) are NEVER substituted at config-resolve time; they +# travel through to the matcher as wildcards. + +[[ops.sync]] +type = ["$1"] +T = "std::sync::Mutex<$1>" +U = "std::sync::MutexGuard<$1>" +lock = "$T::lock" + +# --------------------------------------------------------------------------- +# folded test +# NOTE: There are intentionally NO [[ops.sync_folded]] entries here. +# The cartesian product over an empty instance list yields zero combinations, +# so the ops_folded pattern produces no diagnostics (fold-on-no-instances). +# --------------------------------------------------------------------------- + +# --------------------------------------------------------------------------- +# partial_bad test — three instances, one malformed (missing `unlock`). +# C3 (resolver's missing-op-binding check) should warn and skip the third. +# --------------------------------------------------------------------------- + +[[ops.sync_pb]] +type = ["$1"] +T = "std::sync::Mutex<$1>" +U = "std::sync::MutexGuard<$1>" +lock = "$T::lock" +unlock = "$U::drop" + +[[ops.sync_pb]] +type = ["$1"] +T = "parking_lot::Mutex<$1>" +U = "parking_lot::MutexGuard<$1>" +lock = "$T::lock" +unlock = "$U::drop" + +[[ops.sync_pb]] +# missing `unlock` — C3 check should warn and skip this instance +type = ["$1"] +T = "std::sync::RwLock<$1>" +U = "std::sync::RwLockReadGuard<$1>" +lock = "$T::read" + +# --------------------------------------------------------------------------- +# set_op_with_ops test — composition via `p_lock - p_uncovered`. +# `unlock` here is bound to a free function (`std::intrinsics::black_box`) +# rather than a method on `$U`, so it cannot use the `$U::method` form. +# --------------------------------------------------------------------------- + +[[ops.sync_so]] +type = ["$1"] +T = "std::sync::Mutex<$1>" +U = "std::sync::MutexGuard<$1>" +lock = "$T::lock" +unlock = "std::intrinsics::black_box" + +# --------------------------------------------------------------------------- +# two_groups test — cartesian product over two op groups. +# sync_2g: 2 instances (Mutex, RwLock) +# logger_2g: 1 instance (std::intrinsics::black_box) +# Total combinations: 2 × 1 = 2. Only (Mutex, black_box) fires in the test +# body; (RwLock, black_box) has no matching RwLock call site. +# +# In `logger_2g`, `$L` is bound to the bare existential `$1` (a wildcard +# type) and `log` is bound to a free function — neither uses the +# `$L::method` form, by design. +# --------------------------------------------------------------------------- + +[[ops.sync_2g]] +type = ["$1"] +T = "std::sync::Mutex<$1>" +U = "std::sync::MutexGuard<$1>" +lock = "$T::lock" + +[[ops.sync_2g]] +type = ["$1"] +T = "std::sync::RwLock<$1>" +U = "std::sync::RwLockReadGuard<$1>" +lock = "$T::read" + +[[ops.logger_2g]] +type = ["$1"] +L = "$1" +log = "std::intrinsics::black_box" + +# --------------------------------------------------------------------------- +# CVE-2025-68260 POC — two op groups +# +# sync_cve: models the lock/unlock primitive. +# lock = $L::lock (a method on the Mutex type, $L resolves to Mutex<$1>) +# unlock = std::intrinsics::black_box (opaque sink representing explicit +# guard consumption; used because MutexGuard::drop is inlined and +# this is a free function, not a method on $G) +# +# intrusive_list_cve: models the intermediate-list transfer/drain operations. +# transfer_to_temp / drain_temp are free functions defined in the test +# binary itself. "crate::" resolves to LOCAL_CRATE in def_path_res, so +# any binary that defines these two functions at the crate root will match. +# Since they're free functions (not methods on $List / $TempList), they +# cannot use the `$List::method` form. +# --------------------------------------------------------------------------- + +[[ops.sync_cve]] +type = ["$1"] +L = "std::sync::Mutex<$1>" +G = "std::sync::MutexGuard<$1>" +lock = "$L::lock" +unlock = "std::intrinsics::black_box" + +[[ops.intrusive_list_cve]] +type = ["$1", "$2"] +List = "$1" +TempList = "$2" +transfer_to_temp = "crate::transfer_to_temp" +drain_temp = "crate::drain_temp" diff --git a/tests/features/ops/folded.rpl b/tests/features/ops/folded.rpl new file mode 100644 index 00000000..43eb5882 --- /dev/null +++ b/tests/features/ops/folded.rpl @@ -0,0 +1,20 @@ +pattern folded + +ops { + sync_folded[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + } +} + +patt { + p[$U: type] = fn _ (..) -> _ { + let $guard: $U = $sync_folded::$lock(move _); + } +} + +diag { + p = { + primary(p) = "folded pattern (this should never fire)", + name = "ops_folded", + } +} diff --git a/tests/features/ops/folded.rs b/tests/features/ops/folded.rs new file mode 100644 index 00000000..46f9d2ff --- /dev/null +++ b/tests/features/ops/folded.rs @@ -0,0 +1,7 @@ +//@compile-flags: -Zinline-mir=false +use std::sync::Mutex; + +fn main() { + let m: Mutex = Mutex::new(0); + let _g = m.lock().unwrap(); +} diff --git a/tests/features/ops/lock_unlock.rpl b/tests/features/ops/lock_unlock.rpl new file mode 100644 index 00000000..e528949f --- /dev/null +++ b/tests/features/ops/lock_unlock.rpl @@ -0,0 +1,21 @@ +pattern lock_unlock + +ops { + sync[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + } +} + +patt { + p[$U: type] = fn _ (..) -> _ { + 'lock: + let $guard: $U = $sync::$lock(move _); + } +} + +diag { + p = { + primary(lock) = "lock-unlock pair detected via abstract op", + name = "ops_lock_unlock", + } +} diff --git a/tests/features/ops/lock_unlock.rs b/tests/features/ops/lock_unlock.rs new file mode 100644 index 00000000..8b2f0bdc --- /dev/null +++ b/tests/features/ops/lock_unlock.rs @@ -0,0 +1,8 @@ +//@compile-flags: -Zinline-mir=false +use std::sync::Mutex; + +fn main() { + let m: Mutex = Mutex::new(0); + let _g = m.lock().unwrap(); + //~^ ops_lock_unlock +} diff --git a/tests/features/ops/partial_bad.rpl b/tests/features/ops/partial_bad.rpl new file mode 100644 index 00000000..1f56e2ed --- /dev/null +++ b/tests/features/ops/partial_bad.rpl @@ -0,0 +1,22 @@ +pattern partial_bad + +ops { + sync_pb[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + fn $unlock(&mut $U) -> _; + } +} + +patt { + p[$U: type] = fn _ (..) -> _ { + 'lock: + let $guard: $U = $sync_pb::$lock(move _); + } +} + +diag { + p = { + primary(lock) = "partial_bad pattern matched", + name = "ops_partial_bad", + } +} diff --git a/tests/features/ops/partial_bad.rs b/tests/features/ops/partial_bad.rs new file mode 100644 index 00000000..144e0cc7 --- /dev/null +++ b/tests/features/ops/partial_bad.rs @@ -0,0 +1,8 @@ +//@compile-flags: -Zinline-mir=false +use std::sync::Mutex; + +fn main() { + let m: Mutex = Mutex::new(0); + let _g = m.lock().unwrap(); + //~^ ops_partial_bad +} diff --git a/tests/features/ops/set_op_with_ops.rpl b/tests/features/ops/set_op_with_ops.rpl new file mode 100644 index 00000000..f9a7e6ce --- /dev/null +++ b/tests/features/ops/set_op_with_ops.rpl @@ -0,0 +1,31 @@ +pattern set_op_with_ops + +ops { + sync_so[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + fn $unlock($U) -> _; + } +} + +util { + p_lock[$U: type] = fn _ (..) -> _ { + 'lock: + let $guard: $U = $sync_so::$lock(move _); + } + p_uncovered[$U: type] = fn _ (..) -> _ { + 'lock: + let $guard: $U = $sync_so::$lock(move _); + _ = $sync_so::$unlock(move $guard); + } +} + +patt { + p[$U: type] = p_lock[] - p_uncovered[] +} + +diag { + p = { + primary(lock) = "lock without explicit release", + name = "ops_lock_no_unlock", + } +} diff --git a/tests/features/ops/set_op_with_ops.rs b/tests/features/ops/set_op_with_ops.rs new file mode 100644 index 00000000..41c87952 --- /dev/null +++ b/tests/features/ops/set_op_with_ops.rs @@ -0,0 +1,31 @@ +//@compile-flags: -Zinline-mir=false +#![feature(core_intrinsics)] +#![allow(internal_features)] +use std::sync::Mutex; + +// Locks without explicit "mark" — should match (p_lock matches, p_uncovered doesn't). +fn lock_only() { + let m: Mutex = Mutex::new(0); + let _g = m.lock(); + //~^ ops_lock_no_unlock +} + +// Locks and then calls black_box on the guard (the "covered" marker). +// p_uncovered matches because both the lock call AND the black_box call are present. +// p_lock - p_uncovered subtracts this match → no diagnostic. +// +// Uses `std::intrinsics::black_box` to align with the path bound in +// `rpl.toml`'s [[ops.sync_so]] `unlock = "std::intrinsics::black_box"`. +// The `std::hint::black_box` re-export resolves to a different DefId at MIR +// level, so the matcher would not recognise it (and the test would fail +// silently if MIR inlining ever changed devirtualisation behaviour). +fn lock_and_mark() { + let m: Mutex = Mutex::new(0); + let g = m.lock(); + let _r = std::intrinsics::black_box(g); +} + +fn main() { + lock_only(); + lock_and_mark(); +} diff --git a/tests/features/ops/two_groups.rpl b/tests/features/ops/two_groups.rpl new file mode 100644 index 00000000..4291726f --- /dev/null +++ b/tests/features/ops/two_groups.rpl @@ -0,0 +1,26 @@ +pattern two_groups + +ops { + sync_2g[$T: type, $U: type] = { + fn $lock(&mut $T) -> $U; + } + logger_2g[$L: type] = { + fn $log($L) -> _; + } +} + +patt { + p[$U: type, $L: type] = fn _ (..) -> _ { + 'lock: + let $guard: $U = $sync_2g::$lock(move _); + let $msg: $L = _; + _ = $logger_2g::$log(move $msg); + } +} + +diag { + p = { + primary(lock) = "two-groups match: lock and log in same function", + name = "ops_two_groups", + } +} diff --git a/tests/features/ops/two_groups.rs b/tests/features/ops/two_groups.rs new file mode 100644 index 00000000..ad40eb73 --- /dev/null +++ b/tests/features/ops/two_groups.rs @@ -0,0 +1,21 @@ +//@compile-flags: -Zinline-mir=false +// two_groups test: exercises cartesian-product matching across TWO op groups. +// sync_2g has 2 instances (Mutex, RwLock). +// logger_2g has 1 instance (std::intrinsics::black_box). +// Total combinations: 2 × 1 = 2. +// Only the (Mutex, black_box) combination fires; (RwLock, black_box) has no RwLock call. +// +// Uses `std::intrinsics::black_box` to align with the path bound in +// `rpl.toml`'s [[ops.logger_2g]] `log = "std::intrinsics::black_box"`. +// See set_op_with_ops.rs for the DefId-mismatch rationale. +#![feature(core_intrinsics)] +#![allow(internal_features)] +use std::sync::Mutex; + +fn main() { + let m: Mutex = Mutex::new(0); + let _g = m.lock(); + //~^ ops_two_groups + let msg: &str = "hi"; + let _r = std::intrinsics::black_box(msg); +} diff --git a/tests/features/ops_cve_2025_68260/buggy.rs b/tests/features/ops_cve_2025_68260/buggy.rs new file mode 100644 index 00000000..0e4d7bb3 --- /dev/null +++ b/tests/features/ops_cve_2025_68260/buggy.rs @@ -0,0 +1,55 @@ +//@compile-flags: -Zinline-mir=false +//! CVE-2025-68260 POC — buggy variant. +//! +//! Mirrors the pre-fix shape of Linux kernel Node::release: +//! 1. Acquire lock. +//! 2. Transfer nodes to a temporary list (under the lock). +//! 3. Release the lock (black_box as opaque unlock sink). +//! 4. Drain the temporary list OUTSIDE the lock — the race window. +//! +//! The `ops_cve_2025_68260` pattern should fire here. +#![feature(core_intrinsics)] +#![allow(internal_features, dead_code, unused_must_use)] +use std::sync::Mutex; + +// Stand-ins for the kernel's intrusive-list operations. +// #[inline(never)] ensures stable, non-inlined MIR call sites even +// when the driver compiles with MIR inlining enabled. +#[inline(never)] +fn transfer_to_temp(_owning: &mut L, _temp: &mut T) {} + +#[inline(never)] +fn drain_temp(_temp: &mut T) {} + +struct OwningList { + dummy: i32, +} + +struct TempList { + dummy: i32, +} + +fn buggy_release() { + let mtx: Mutex = Mutex::new(OwningList { dummy: 0 }); + + // Step 1: acquire lock — pattern matches $sync_cve::$lock. + let g = mtx.lock(); + //~^ ops_cve_2025_68260 + + let mut list_inner = OwningList { dummy: 0 }; + let mut temp = TempList { dummy: 0 }; + + // Step 2: transfer nodes to temp list under the lock. + transfer_to_temp(&mut list_inner, &mut temp); + + // Step 3: release the lock — std::intrinsics::black_box as the opaque unlock sink. + // The guard (g) is moved into the intrinsic, which acts as an opaque consumer. + std::intrinsics::black_box(g); + + // Step 4: drain the temp list OUTSIDE the lock — the bug window. + drain_temp(&mut temp); +} + +fn main() { + buggy_release(); +} diff --git a/tests/features/ops_cve_2025_68260/fixed.rs b/tests/features/ops_cve_2025_68260/fixed.rs new file mode 100644 index 00000000..88e0a0c1 --- /dev/null +++ b/tests/features/ops_cve_2025_68260/fixed.rs @@ -0,0 +1,53 @@ +//@compile-flags: -Zinline-mir=false +//! CVE-2025-68260 POC — fixed variant. +//! +//! Mirrors the post-fix shape: +//! 1. Acquire lock. +//! 2. Transfer nodes to a temporary list (under the lock). +//! 3. Drain the temporary list UNDER the lock — no race window. +//! 4. Release the lock (guard drops naturally — no explicit unlock sink call). +//! +//! The `ops_cve_2025_68260` pattern requires an explicit $sync_cve::$unlock call +//! (bound to std::intrinsics::black_box) between transfer and drain. Since this +//! fixed variant lets the guard drop naturally (no black_box call), the pattern +//! cannot match — demonstrating the structural asymmetry. +#![feature(core_intrinsics)] +#![allow(internal_features, dead_code, unused_must_use)] +use std::sync::Mutex; + +#[inline(never)] +fn transfer_to_temp(_owning: &mut L, _temp: &mut T) {} + +#[inline(never)] +fn drain_temp(_temp: &mut T) {} + +struct OwningList { + dummy: i32, +} + +struct TempList { + dummy: i32, +} + +fn fixed_release() { + let mtx: Mutex = Mutex::new(OwningList { dummy: 0 }); + + // Step 1: acquire lock. + let _owning = mtx.lock(); + + let mut list_inner = OwningList { dummy: 0 }; + let mut temp = TempList { dummy: 0 }; + + // Step 2: transfer nodes to temp list (still under the lock). + transfer_to_temp(&mut list_inner, &mut temp); + + // Step 3: drain the temp list WHILE THE LOCK IS HELD — no race window. + drain_temp(&mut temp); + + // Step 4: lock is released here by natural drop of _owning. + // No explicit black_box call → no $sync_cve::$unlock match → pattern cannot fire. +} + +fn main() { + fixed_release(); +} diff --git a/tests/features/ops_cve_2025_68260/pattern.rpl b/tests/features/ops_cve_2025_68260/pattern.rpl new file mode 100644 index 00000000..73cae4eb --- /dev/null +++ b/tests/features/ops_cve_2025_68260/pattern.rpl @@ -0,0 +1,38 @@ +pattern cve_2025_68260 + +ops { + sync_cve[$L: type, $G: type] = { + fn $lock(&mut $L) -> $G; + fn $unlock($G) -> _; + } + intrusive_list_cve[$List: type, $TempList: type] = { + fn $transfer_to_temp(&mut $List, &mut $TempList) -> _; + fn $drain_temp(&mut $TempList) -> _; + } +} + +patt { + p[$G: type] = fn _ (..) -> _ { + // 1. Acquire the lock on the owning list. + 'lock: + let $guard: $G = $sync_cve::$lock(move _); + + // 2. Transfer nodes out to a temporary list (under the lock). + _ = $intrusive_list_cve::$transfer_to_temp(_, _); + + // 3. Release the lock. Any argument (wildcard) since the optimized MIR + // may introduce an intermediate local before the unlock sink. + _ = $sync_cve::$unlock(_); + + // 4. Drain the temporary list OUTSIDE the lock — the bug window. + _ = $intrusive_list_cve::$drain_temp(_); + } +} + +diag { + p = { + primary(lock) = "intrusive list drained outside the lock that owns it (CVE-2025-68260 bug class)", + help = "extract elements directly from the owning list under the lock; do not transit through an intermediate stack list", + name = "ops_cve_2025_68260", + } +} diff --git a/tests/features/test.sh b/tests/features/test.sh index f860d372..5ef6f2fd 100644 --- a/tests/features/test.sh +++ b/tests/features/test.sh @@ -1,6 +1,9 @@ clear -set -euxo pipefail +set -uxo pipefail +# Note: -e is intentionally omitted — rpl-driver exits 1 when it fires a lint +# (this is the expected behaviour for test targets that contain flagged code). +# Use || true after invocations that are expected to produce diagnostics. export RUSTC_ICE=0 @@ -11,5 +14,59 @@ export RUST_BACKTRACE=1 # RPL_PATS="tests/ui/features/diff_pat/default.rpl" cargo +rpl-dbg uitest -- "tests/ui/features/diff_pat" 2>&1 | tee .ansi # RPL_PATS="tests/ui/features/diff_pat/meta_var.rpl" cargo +rpl-dbg uitest -- "tests/ui/features/diff_pat" 2>&1 | tee .ansi # RPL_PATS="tests/ui/features/diff_pat/label.rpl" cargo +rpl-dbg uitest -- "tests/ui/features/diff_pat" 2>&1 | tee .ansi -RPL_PATS="tests/ui/features/diff_pat/label.rpl" cargo +rpl-dbg run --bin rpl-driver -- "tests/ui/features/diff_pat/test.rs" 2>&1 | tee .ansi +# RPL_PATS="tests/ui/features/diff_pat/label.rpl" cargo +rpl-dbg run --bin rpl-driver -- "tests/ui/features/diff_pat/test.rs" 2>&1 | tee .ansi # RPL_PATS="tests/ui/features/diff_pat" cargo +rpl-dbg uitest -- "tests/ui/features/diff_pat" 2>&1 | tee .ansi + +# Task 13: lock_unlock end-to-end ops test +# Exercises the abstract-ops feature: parser, lowering, OpRef IR, OpsConfig +# substitution, cartesian iteration, and matcher OpRef resolution against +# std::sync::Mutex. The workspace rpl.toml provides the [[ops.sync]] instance. +# Expected: lint fires at m.lock() → rpl-driver exits 1 (|| true is intentional). +RPL_PATS="tests/features/ops/lock_unlock.rpl" \ + cargo run --bin rpl-driver -- "tests/features/ops/lock_unlock.rs" 2>&1 | tee .ansi || true + +# --------------------------------------------------------------------------- +# Task 14: four end-to-end UI tests for abstract-ops properties +# --------------------------------------------------------------------------- + +# folded: ops group declared in .rpl, NO [[ops.sync_folded]] in rpl.toml. +# Cartesian product of zero instances → zero matches → no diagnostics (exit 0). +RPL_PATS="tests/features/ops/folded.rpl" \ + cargo run --bin rpl-driver -- "tests/features/ops/folded.rs" 2>&1 | tee .ansi + +# partial_bad: three [[ops.sync_pb]] entries, one malformed (missing unlock). +# C3 validation skips the third instance; the first (Mutex) still fires. +# Expected: lint at m.lock() → exit 1 (|| true is intentional). +RPL_PATS="tests/features/ops/partial_bad.rpl" \ + cargo run --bin rpl-driver -- "tests/features/ops/partial_bad.rs" 2>&1 | tee .ansi || true + +# set_op_with_ops: util patterns p_lock / p_uncovered use ops; patt = p_lock - p_uncovered. +# lock_only() matches p_lock but NOT p_uncovered → diagnostic fires. +# lock_and_mark() matches BOTH → subtracted → no diagnostic. +# Expected: one lint at lock_only → exit 1 (|| true is intentional). +RPL_PATS="tests/features/ops/set_op_with_ops.rpl" \ + cargo run --bin rpl-driver -- "tests/features/ops/set_op_with_ops.rs" 2>&1 | tee .ansi || true + +# two_groups: two op groups (sync_2g × logger_2g); cartesian-product expansion. +# Mutex × black_box combination in main() is the only one that fires (RwLock +# also has an instance, but no matching call site is present). +# Expected: one lint → exit 1 (|| true is intentional). +RPL_PATS="tests/features/ops/two_groups.rpl" \ + cargo run --bin rpl-driver -- "tests/features/ops/two_groups.rs" 2>&1 | tee .ansi || true + +# --------------------------------------------------------------------------- +# Task 15: CVE-2025-68260 POC — abstract intrusive-list-under-lock pattern +# --------------------------------------------------------------------------- + +# buggy.rs: mirrors the pre-fix Node::release shape (lock → transfer → unlock → drain). +# sync_cve bound to Mutex::lock + std::intrinsics::black_box (opaque unlock sink). +# intrusive_list_cve bound to crate::transfer_to_temp + crate::drain_temp. +# Expected: ops_cve_2025_68260 lint fires → exit 1 (|| true is intentional). +RPL_PATS="tests/features/ops_cve_2025_68260/pattern.rpl" \ + cargo run --bin rpl-driver -- "tests/features/ops_cve_2025_68260/buggy.rs" 2>&1 | tee .ansi || true + +# fixed.rs: guard drops naturally (no black_box call) — no $sync_cve::$unlock match. +# Pattern cannot fire without an explicit unlock call site. +# Expected: NO ops_cve_2025_68260 lint → exit 0. +RPL_PATS="tests/features/ops_cve_2025_68260/pattern.rpl" \ + cargo run --bin rpl-driver -- "tests/features/ops_cve_2025_68260/fixed.rs" 2>&1 | tee .ansi