#[macro_use]
extern crate syn;

use syn::{
    parse::{Parse, ParseStream},
    parse::discouraged::Speculative,
    Result,
};

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor_between_sources() {
    // don't do this ever this is very unsafe and fails anyway
    struct Smuggled(ParseStream<'static>);
    impl Parse for Smuggled {
        fn parse(input: ParseStream) -> Result<Self> {
            Ok(Smuggled(unsafe { std::mem::transmute_copy(input) }))
        }
    }

    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let Smuggled(fork) = syn::parse_str("").unwrap();
            input.advance_to(fork);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("").unwrap();
}

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor_between_brackets() {
    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let a;
            let b;
            parenthesized!(a in input);
            parenthesized!(b in input);
            a.advance_to(&b);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("()()").unwrap();
}

extern crate syn;

use syn::{
    parse::{Parse, ParseStream},
    parse::discouraged::Speculative,
    Result,
};

#[test]
#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
fn smuggled_speculative_cursor() {
    struct Smuggled(ParseStream<'static>);
    impl Parse for Smuggled {
        fn parse(input: ParseStream) -> Result<Self> {
            Ok(Smuggled(unsafe { std::mem::transmute_copy(input) }))
        }
    }

    struct BreakRules;
    impl Parse for BreakRules {
        fn parse(input: ParseStream) -> Result<Self> {
            let Smuggled(fork) = syn::parse_str("").unwrap();
            input.advance_to(fork);
            Ok(Self)
        }
    }

    syn::parse_str::<BreakRules>("").unwrap();
}

--- 
+++ 
@@ -1,3 +1,4 @@
+#[macro_use]
 extern crate syn;
 
 use syn::{
@@ -8,7 +9,8 @@
 
 #[test]
 #[should_panic(expected = "Fork was not derived from the advancing parse stream")]
-fn smuggled_speculative_cursor() {
+fn smuggled_speculative_cursor_between_sources() {
+    // don't do this ever this is very unsafe and fails anyway
     struct Smuggled(ParseStream<'static>);
     impl Parse for Smuggled {
         fn parse(input: ParseStream) -> Result<Self> {
@@ -27,3 +29,21 @@
 
     syn::parse_str::<BreakRules>("").unwrap();
 }
+
+#[test]
+#[should_panic(expected = "Fork was not derived from the advancing parse stream")]
+fn smuggled_speculative_cursor_between_brackets() {
+    struct BreakRules;
+    impl Parse for BreakRules {
+        fn parse(input: ParseStream) -> Result<Self> {
+            let a;
+            let b;
+            parenthesized!(a in input);
+            parenthesized!(b in input);
+            a.advance_to(&b);
+            Ok(Self)
+        }
+    }
+
+    syn::parse_str::<BreakRules>("()()").unwrap();
+}
Add speculative smuggling test between bracket contexts
