diff --git a/engine/src/ast_discoverer.rs b/engine/src/ast_discoverer.rs
new file mode 100644
index 0000000..8840899
--- /dev/null
+++ b/engine/src/ast_discoverer.rs
@@ -0,0 +1,726 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::{
+    directive_names::{EXTERN_RUST_FUN, EXTERN_RUST_TYPE},
+    RustFun, RustPath,
+};
+use itertools::Itertools;
+use proc_macro2::Ident;
+use syn::{
+    parse_quote, punctuated::Punctuated, Attribute, Binding, Expr, ExprAssign, ExprAssignOp,
+    ExprAwait, ExprBinary, ExprBox, ExprBreak, ExprCast, ExprField, ExprGroup, ExprLet, ExprParen,
+    ExprReference, ExprTry, ExprType, ExprUnary, ImplItem, Item, ItemEnum, ItemStruct, Pat, PatBox,
+    PatReference, PatSlice, PatTuple, Path, Receiver, ReturnType, Signature, Stmt, TraitItem, Type,
+    TypeArray, TypeGroup, TypeParamBound, TypeParen, TypePtr, TypeReference, TypeSlice,
+};
+use thiserror::Error;
+
+#[derive(Default)]
+pub(super) struct Discoveries {
+    pub(super) cpp_list: HashSet<String>,
+    pub(super) extern_rust_funs: Vec<RustFun>,
+    pub(super) extern_rust_types: Vec<RustPath>,
+}
+
+#[derive(Error, Debug)]
+pub enum DiscoveryErr {
+    #[error("#[extern_rust_function] was attached to a method in an impl block that was too complex for autocxx. autocxx supports only \"impl X {{...}}\" where X is a single identifier, not a path or more complex type.")]
+    FoundExternRustFunOnTypeWithoutClearReceiver,
+    #[error("#[extern_rust_function] was attached to a method taking no parameters.")]
+    NonReferenceReceiver,
+    #[error("#[extern_rust_function] was attached to a method taking a receiver by value.")]
+    NoParameterOnMethod,
+    #[error("#[extern_rust_function] was in an impl block nested wihtin another block. This is only supported in the outermost mod of a file, alongside the include_cpp!.")]
+    FoundExternRustFunWithinMod,
+}
+
+impl Discoveries {
+    pub(super) fn search_item(
+        &mut self,
+        item: &Item,
+        mod_path: Option<RustPath>,
+    ) -> Result<(), DiscoveryErr> {
+        let mut this_mod = PerModDiscoveries {
+            discoveries: self,
+            mod_path,
+        };
+        this_mod.search_item(item)
+    }
+
+    pub(crate) fn found_allowlist(&self) -> bool {
+        !self.cpp_list.is_empty()
+    }
+
+    pub(crate) fn found_rust(&self) -> bool {
+        !self.extern_rust_funs.is_empty() || !self.extern_rust_types.is_empty()
+    }
+
+    pub(crate) fn extend(&mut self, other: Self) {
+        self.cpp_list.extend(other.cpp_list);
+        self.extern_rust_funs.extend(other.extern_rust_funs);
+        self.extern_rust_types.extend(other.extern_rust_types);
+    }
+}
+
+struct PerModDiscoveries<'a> {
+    discoveries: &'a mut Discoveries,
+    mod_path: Option<RustPath>,
+}
+
+impl<'b> PerModDiscoveries<'b> {
+    fn deeper_path(&self, id: &Ident) -> RustPath {
+        match &self.mod_path {
+            None => RustPath::new_from_ident(id.clone()),
+            Some(mod_path) => mod_path.append(id.clone()),
+        }
+    }
+
+    fn search_item(&mut self, item: &Item) -> Result<(), DiscoveryErr> {
+        match item {
+            Item::Fn(fun) => {
+                for stmt in &fun.block.stmts {
+                    self.search_stmt(stmt)?
+                }
+                self.search_return_type(&fun.sig.output)?;
+                for i in &fun.sig.inputs {
+                    match i {
+                        syn::FnArg::Receiver(_) => {}
+                        syn::FnArg::Typed(pt) => {
+                            self.search_pat(&pt.pat)?;
+                            self.search_type(&pt.ty)?;
+                        }
+                    }
+                }
+                if Self::has_attr(&fun.attrs, EXTERN_RUST_FUN) {
+                    self.discoveries.extern_rust_funs.push(RustFun {
+                        path: self.deeper_path(&fun.sig.ident),
+                        sig: fun.sig.clone(),
+                        receiver: None,
+                    });
+                }
+            }
+            Item::Impl(imp) => {
+                let receiver = match imp.trait_ {
+                    // We do not allow 'extern_rust_fun' on trait impls
+                    Some(_) => None,
+                    None => match &*imp.self_ty {
+                        Type::Path(typ) => {
+                            let mut segs = typ.path.segments.iter();
+                            let id = segs.next();
+                            if let Some(seg) = id {
+                                if segs.next().is_some() {
+                                    None
+                                } else {
+                                    Some(self.deeper_path(&seg.ident))
+                                }
+                            } else {
+                                None
+                            }
+                        }
+                        _ => None,
+                    },
+                };
+                for item in &imp.items {
+                    self.search_impl_item(item, receiver.as_ref())?
+                }
+            }
+            Item::Mod(md) => {
+                if let Some((_, items)) = &md.content {
+                    let mod_path = Some(self.deeper_path(&md.ident));
+                    let mut new_mod = PerModDiscoveries {
+                        discoveries: self.discoveries,
+                        mod_path,
+                    };
+                    for item in items {
+                        new_mod.search_item(item)?
+                    }
+                }
+            }
+            Item::Trait(tr) => {
+                for item in &tr.items {
+                    self.search_trait_item(item)?
+                }
+            }
+            Item::Struct(ItemStruct { ident, attrs, .. })
+            | Item::Enum(ItemEnum { ident, attrs, .. })
+                if Self::has_attr(attrs, EXTERN_RUST_TYPE) =>
+            {
+                self.discoveries
+                    .extern_rust_types
+                    .push(self.deeper_path(ident));
+            }
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn search_path(&mut self, path: &Path) -> Result<(), DiscoveryErr> {
+        let mut seg_iter = path.segments.iter();
+        if let Some(first_seg) = seg_iter.next() {
+            if first_seg.ident == "ffi" {
+                self.discoveries
+                    .cpp_list
+                    .insert(seg_iter.map(|seg| seg.ident.to_string()).join("::"));
+            }
+        }
+        for seg in path.segments.iter() {
+            self.search_path_arguments(&seg.arguments)?;
+        }
+        Ok(())
+    }
+
+    fn search_trait_item(&mut self, itm: &TraitItem) -> Result<(), DiscoveryErr> {
+        if let TraitItem::Method(itm) = itm {
+            if let Some(block) = &itm.default {
+                self.search_stmts(block.stmts.iter())?
+            }
+        }
+        Ok(())
+    }
+
+    fn search_stmts<'a>(
+        &mut self,
+        stmts: impl Iterator<Item = &'a Stmt>,
+    ) -> Result<(), DiscoveryErr> {
+        for stmt in stmts {
+            self.search_stmt(stmt)?
+        }
+        Ok(())
+    }
+
+    fn search_stmt(&mut self, stmt: &Stmt) -> Result<(), DiscoveryErr> {
+        match stmt {
+            Stmt::Local(lcl) => {
+                if let Some((_, expr)) = &lcl.init {
+                    self.search_expr(expr)?
+                }
+                self.search_pat(&lcl.pat)
+            }
+            Stmt::Item(itm) => self.search_item(itm),
+            Stmt::Expr(exp) | Stmt::Semi(exp, _) => self.search_expr(exp),
+        }
+    }
+
+    fn search_expr(&mut self, expr: &Expr) -> Result<(), DiscoveryErr> {
+        match expr {
+            Expr::Path(exp) => {
+                self.search_path(&exp.path)?;
+            }
+            Expr::Macro(_) => {}
+            Expr::Array(array) => self.search_exprs(array.elems.iter())?,
+            Expr::Assign(ExprAssign { left, right, .. })
+            | Expr::AssignOp(ExprAssignOp { left, right, .. })
+            | Expr::Binary(ExprBinary { left, right, .. }) => {
+                self.search_expr(left)?;
+                self.search_expr(right)?;
+            }
+            Expr::Async(ass) => self.search_stmts(ass.block.stmts.iter())?,
+            Expr::Await(ExprAwait { base, .. }) | Expr::Field(ExprField { base, .. }) => {
+                self.search_expr(base)?
+            }
+            Expr::Block(blck) => self.search_stmts(blck.block.stmts.iter())?,
+            Expr::Box(ExprBox { expr, .. })
+            | Expr::Break(ExprBreak {
+                expr: Some(expr), ..
+            })
+            | Expr::Cast(ExprCast { expr, .. })
+            | Expr::Group(ExprGroup { expr, .. })
+            | Expr::Paren(ExprParen { expr, .. })
+            | Expr::Reference(ExprReference { expr, .. })
+            | Expr::Try(ExprTry { expr, .. })
+            | Expr::Type(ExprType { expr, .. })
+            | Expr::Unary(ExprUnary { expr, .. }) => self.search_expr(expr)?,
+            Expr::Call(exc) => {
+                self.search_expr(&exc.func)?;
+                self.search_exprs(exc.args.iter())?;
+            }
+            Expr::Closure(cls) => self.search_expr(&cls.body)?,
+            Expr::Continue(_)
+            | Expr::Lit(_)
+            | Expr::Break(ExprBreak { expr: None, .. })
+            | Expr::Verbatim(_) => {}
+            Expr::ForLoop(fl) => {
+                self.search_expr(&fl.expr)?;
+                self.search_stmts(fl.body.stmts.iter())?;
+            }
+            Expr::If(exif) => {
+                self.search_expr(&exif.cond)?;
+                self.search_stmts(exif.then_branch.stmts.iter())?;
+                if let Some((_, else_branch)) = &exif.else_branch {
+                    self.search_expr(else_branch)?;
+                }
+            }
+            Expr::Index(exidx) => {
+                self.search_expr(&exidx.expr)?;
+                self.search_expr(&exidx.index)?;
+            }
+            Expr::Let(ExprLet { expr, pat, .. }) => {
+                self.search_expr(expr)?;
+                self.search_pat(pat)?;
+            }
+            Expr::Loop(exloo) => self.search_stmts(exloo.body.stmts.iter())?,
+            Expr::Match(exm) => {
+                self.search_expr(&exm.expr)?;
+                for a in &exm.arms {
+                    self.search_expr(&a.body)?;
+                    if let Some((_, guard)) = &a.guard {
+                        self.search_expr(guard)?;
+                    }
+                }
+            }
+            Expr::MethodCall(mtc) => {
+                self.search_expr(&mtc.receiver)?;
+                self.search_exprs(mtc.args.iter())?;
+            }
+            Expr::Range(exr) => {
+                self.search_option_expr(&exr.from)?;
+                self.search_option_expr(&exr.to)?;
+            }
+            Expr::Repeat(exr) => {
+                self.search_expr(&exr.expr)?;
+                self.search_expr(&exr.len)?;
+            }
+            Expr::Return(exret) => {
+                if let Some(expr) = &exret.expr {
+                    self.search_expr(expr)?;
+                }
+            }
+            Expr::Struct(exst) => {
+                for f in &exst.fields {
+                    self.search_expr(&f.expr)?;
+                }
+                self.search_option_expr(&exst.rest)?;
+            }
+            Expr::TryBlock(extb) => self.search_stmts(extb.block.stmts.iter())?,
+            Expr::Tuple(ext) => self.search_exprs(ext.elems.iter())?,
+            Expr::Unsafe(exs) => self.search_stmts(exs.block.stmts.iter())?,
+            Expr::While(exw) => {
+                self.search_expr(&exw.cond)?;
+                self.search_stmts(exw.body.stmts.iter())?;
+            }
+            Expr::Yield(exy) => self.search_option_expr(&exy.expr)?,
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn search_option_expr(&mut self, expr: &Option<Box<Expr>>) -> Result<(), DiscoveryErr> {
+        if let Some(expr) = &expr {
+            self.search_expr(expr)?;
+        }
+        Ok(())
+    }
+
+    fn search_exprs<'a>(
+        &mut self,
+        exprs: impl Iterator<Item = &'a Expr>,
+    ) -> Result<(), DiscoveryErr> {
+        for e in exprs {
+            self.search_expr(e)?;
+        }
+        Ok(())
+    }
+
+    fn search_impl_item(
+        &mut self,
+        impl_item: &ImplItem,
+        receiver: Option<&RustPath>,
+    ) -> Result<(), DiscoveryErr> {
+        if let ImplItem::Method(itm) = impl_item {
+            if Self::has_attr(&itm.attrs, EXTERN_RUST_FUN) {
+                if self.mod_path.is_some() {
+                    return Err(DiscoveryErr::FoundExternRustFunWithinMod);
+                }
+                if let Some(receiver) = receiver {
+                    // We have a method which we want to put into the cxx::bridge's
+                    // "extern Rust" block.
+                    let sig = add_receiver(&itm.sig, receiver.get_final_ident())?;
+                    assert!(receiver.len() == 1);
+                    self.discoveries.extern_rust_funs.push(RustFun {
+                        path: self.deeper_path(&itm.sig.ident),
+                        sig,
+                        receiver: Some(receiver.get_final_ident().clone()),
+                    });
+                    self.discoveries.extern_rust_types.push(receiver.clone())
+                } else {
+                    return Err(DiscoveryErr::FoundExternRustFunOnTypeWithoutClearReceiver);
+                }
+            }
+            for stmt in &itm.block.stmts {
+                self.search_stmt(stmt)?
+            }
+        }
+        Ok(())
+    }
+
+    fn search_pat(&mut self, pat: &Pat) -> Result<(), DiscoveryErr> {
+        match pat {
+            Pat::Box(PatBox { pat, .. }) | Pat::Reference(PatReference { pat, .. }) => {
+                self.search_pat(pat)
+            }
+            Pat::Ident(_) | Pat::Lit(_) | Pat::Macro(_) | Pat::Range(_) | Pat::Rest(_) => Ok(()),
+            Pat::Or(pator) => {
+                for case in &pator.cases {
+                    self.search_pat(case)?;
+                }
+                Ok(())
+            }
+            Pat::Path(pp) => self.search_path(&pp.path),
+            Pat::Slice(PatSlice { elems, .. }) | Pat::Tuple(PatTuple { elems, .. }) => {
+                for case in elems {
+                    self.search_pat(case)?;
+                }
+                Ok(())
+            }
+            Pat::Struct(ps) => {
+                self.search_path(&ps.path)?;
+                for f in &ps.fields {
+                    self.search_pat(&f.pat)?;
+                }
+                Ok(())
+            }
+            Pat::TupleStruct(tps) => {
+                self.search_path(&tps.path)?;
+                for f in &tps.pat.elems {
+                    self.search_pat(f)?;
+                }
+                Ok(())
+            }
+            Pat::Type(pt) => {
+                self.search_pat(&pt.pat)?;
+                self.search_type(&pt.ty)
+            }
+            _ => Ok(()),
+        }
+    }
+
+    fn search_type(&mut self, ty: &Type) -> Result<(), DiscoveryErr> {
+        match ty {
+            Type::Array(TypeArray { elem, .. })
+            | Type::Group(TypeGroup { elem, .. })
+            | Type::Paren(TypeParen { elem, .. })
+            | Type::Ptr(TypePtr { elem, .. })
+            | Type::Reference(TypeReference { elem, .. })
+            | Type::Slice(TypeSlice { elem, .. }) => self.search_type(elem)?,
+            Type::BareFn(tf) => {
+                for input in &tf.inputs {
+                    self.search_type(&input.ty)?;
+                }
+                self.search_return_type(&tf.output)?;
+            }
+            Type::ImplTrait(tyit) => {
+                for b in &tyit.bounds {
+                    if let syn::TypeParamBound::Trait(tyt) = b {
+                        self.search_path(&tyt.path)?
+                    }
+                }
+            }
+            Type::Infer(_) | Type::Macro(_) | Type::Never(_) => {}
+            Type::Path(typ) => self.search_path(&typ.path)?,
+            Type::TraitObject(tto) => self.search_type_param_bounds(&tto.bounds)?,
+            Type::Tuple(tt) => {
+                for e in &tt.elems {
+                    self.search_type(e)?
+                }
+            }
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn search_type_param_bounds(
+        &mut self,
+        bounds: &Punctuated<TypeParamBound, syn::token::Add>,
+    ) -> Result<(), DiscoveryErr> {
+        for b in bounds {
+            if let syn::TypeParamBound::Trait(tpbt) = b {
+                self.search_path(&tpbt.path)?
+            }
+        }
+        Ok(())
+    }
+
+    fn search_return_type(&mut self, output: &ReturnType) -> Result<(), DiscoveryErr> {
+        if let ReturnType::Type(_, ty) = &output {
+            self.search_type(ty)
+        } else {
+            Ok(())
+        }
+    }
+
+    fn search_path_arguments(
+        &mut self,
+        arguments: &syn::PathArguments,
+    ) -> Result<(), DiscoveryErr> {
+        match arguments {
+            syn::PathArguments::None => {}
+            syn::PathArguments::AngleBracketed(paab) => {
+                for arg in &paab.args {
+                    match arg {
+                        syn::GenericArgument::Lifetime(_) => {}
+                        syn::GenericArgument::Type(ty)
+                        | syn::GenericArgument::Binding(Binding { ty, .. }) => {
+                            self.search_type(ty)?
+                        }
+                        syn::GenericArgument::Constraint(c) => {
+                            self.search_type_param_bounds(&c.bounds)?
+                        }
+                        syn::GenericArgument::Const(c) => self.search_expr(c)?,
+                    }
+                }
+            }
+            syn::PathArguments::Parenthesized(pas) => {
+                self.search_return_type(&pas.output)?;
+                for t in &pas.inputs {
+                    self.search_type(t)?;
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn has_attr(attrs: &[Attribute], attr_name: &str) -> bool {
+        attrs.iter().any(|attr| {
+            attr.path
+                .segments
+                .last()
+                .map(|seg| seg.ident == attr_name)
+                .unwrap_or_default()
+        })
+    }
+}
+
+/// Take a method signature that may be `fn a(&self)`
+/// and turn it into `fn a(self: &A)` which is what we will
+/// need to specify to cxx.
+fn add_receiver(sig: &Signature, receiver: &Ident) -> Result<Signature, DiscoveryErr> {
+    let mut sig = sig.clone();
+    match sig.inputs.iter_mut().next() {
+        Some(first_arg) => match first_arg {
+            syn::FnArg::Receiver(Receiver {
+                reference: Some(_),
+                mutability: Some(_),
+                ..
+            }) => {
+                *first_arg = parse_quote! {
+                    self: &mut #receiver
+                }
+            }
+            syn::FnArg::Receiver(Receiver {
+                reference: Some(_),
+                mutability: None,
+                ..
+            }) => {
+                *first_arg = parse_quote! {
+                    self: &#receiver
+                }
+            }
+            syn::FnArg::Receiver(..) => return Err(DiscoveryErr::NonReferenceReceiver),
+            syn::FnArg::Typed(_) => {}
+        },
+        None => return Err(DiscoveryErr::NoParameterOnMethod),
+    }
+    Ok(sig)
+}
+
+#[cfg(test)]
+mod tests {
+    use quote::{quote, ToTokens};
+    use syn::{parse_quote, ImplItemMethod};
+
+    use crate::{ast_discoverer::add_receiver, types::make_ident};
+
+    use super::Discoveries;
+
+    fn assert_cpp_found(discoveries: &Discoveries) {
+        assert!(!discoveries.cpp_list.is_empty());
+        assert!(discoveries.cpp_list.iter().next().unwrap() == "xxx");
+    }
+
+    #[test]
+    fn test_mod_plain_call() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            mod foo {
+                fn bar() {
+                    ffi::xxx()
+                }
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_plain_call() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                ffi::xxx()
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_plain_call_with_semi() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                ffi::xxx();
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_in_ns() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                ffi::a::b::xxx();
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(!discoveries.cpp_list.is_empty());
+        assert!(discoveries.cpp_list.iter().next().unwrap() == "a::b::xxx");
+    }
+
+    #[test]
+    fn test_deep_nested_thingy() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                a + 3 * foo(ffi::xxx());
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_ty_in_let() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                let foo: ffi::xxx = bar();
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_ty_in_fn() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar(a: &mut ffi::xxx) {
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_ty_in_fn_up() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar(a: cxx::UniquePtr<ffi::xxx>) {
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_extern_rust_fun() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            #[autocxx::extern_rust::extern_rust_function]
+            fn bar(a: cxx::UniquePtr<ffi::xxx>) {
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(discoveries.extern_rust_funs.get(0).unwrap().sig.ident == "bar");
+    }
+
+    #[test]
+    fn test_extern_rust_method() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            impl A {
+                #[autocxx::extern_rust::extern_rust_function]
+                fn bar(&self) {
+                }
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(discoveries.extern_rust_funs.get(0).unwrap().sig.ident == "bar");
+    }
+
+    #[test]
+    fn test_extern_rust_ty() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            #[autocxx::extern_rust::extern_rust_type]
+            struct Bar {
+
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(
+            discoveries
+                .extern_rust_types
+                .get(0)
+                .unwrap()
+                .get_final_ident()
+                == "Bar"
+        );
+    }
+
+    #[test]
+    fn test_add_receiver() {
+        let meth: ImplItemMethod = parse_quote! {
+            fn a(&self) {}
+        };
+        let a = make_ident("A");
+        assert_eq!(
+            add_receiver(&meth.sig, &a)
+                .unwrap()
+                .to_token_stream()
+                .to_string(),
+            quote! { fn a(self: &A) }.to_string()
+        );
+
+        let meth: ImplItemMethod = parse_quote! {
+            fn a(&mut self, b: u32) -> Foo {}
+        };
+        assert_eq!(
+            add_receiver(&meth.sig, &a)
+                .unwrap()
+                .to_token_stream()
+                .to_string(),
+            quote! { fn a(self: &mut A, b: u32) -> Foo }.to_string()
+        );
+
+        let meth: ImplItemMethod = parse_quote! {
+            fn a(self) {}
+        };
+        assert!(add_receiver(&meth.sig, &a).is_err());
+
+        let meth: ImplItemMethod = parse_quote! {
+            fn a() {}
+        };
+        assert!(add_receiver(&meth.sig, &a).is_err());
+    }
+}
