DanielKeep.github.io
DanielKeep.github.io copied to clipboard
error: `$inits:expr` may be followed by `...`, which is not allowed for `expr` fragments
Hi, first thanks a lot for your helpful doc: https://danielkeep.github.io/practical-intro-to-macros.html !
I got build error: (using rustc 1.19.0-nightly (03abb1bd7 2017-06-13))
error: `$inits:expr` may be followed by `...`, which is not allowed for `expr` fragments
--> /home/z/code/learn_rust/fib.rs:2:40
|
2 | ( a[n]: $sty:ty = $($inits:expr),+ ... $recur:expr ) => {
| ^^^
when tried the code:
macro_rules! recurrence {
( a[n]: $sty:ty = $($inits:expr),+ ... $recur:expr ) => {
{
/*
What follows here is *literally* the code from before,
cut and pasted into a new position. No other changes
have been made.
*/
use std::ops::Index;
struct Recurrence {
mem: [u64; 2],
pos: usize,
}
struct IndexOffset<'a> {
slice: &'a [u64; 2],
offset: usize,
}
impl<'a> Index<usize> for IndexOffset<'a> {
type Output = u64;
#[inline(always)]
fn index<'b>(&'b self, index: usize) -> &'b u64 {
use std::num::Wrapping;
let index = Wrapping(index);
let offset = Wrapping(self.offset);
let window = Wrapping(2);
let real_index = index - offset + window;
&self.slice[real_index.0]
}
}
impl Iterator for Recurrence {
type Item = u64;
#[inline]
fn next(&mut self) -> Option<u64> {
if self.pos < 2 {
let next_val = self.mem[self.pos];
self.pos += 1;
Some(next_val)
} else {
let next_val = {
let n = self.pos;
let a = IndexOffset { slice: &self.mem, offset: n };
(a[n-1] + a[n-2])
};
{
use std::mem::swap;
let mut swap_tmp = next_val;
for i in (0..2).rev() {
swap(&mut swap_tmp, &mut self.mem[i]);
}
}
self.pos += 1;
Some(next_val)
}
}
}
Recurrence { mem: [0, 1], pos: 0 }
}
};
}
fn main() {
let fib = recurrence![a[n]: u64 = 0, 1 ... a[n-1] + a[n-2]];
for e in fib.take(10) { println!("{}", e) }
}
It's just the complier prevents you from doing so. Early(relatively to now) version of complier gives a warning, and another version after that gives a error.