diff --git a/gen/src/write.rs b/gen/src/write.rs index 7b0b49b39..9f9c03913 100644 --- a/gen/src/write.rs +++ b/gen/src/write.rs @@ -3,7 +3,7 @@ use crate::gen::nested::NamespaceEntries; use crate::gen::out::OutFile; use crate::gen::{builtin, include, Opt}; use crate::syntax::atom::Atom::{self, *}; -use crate::syntax::instantiate::ImplKey; +use crate::syntax::instantiate::{ImplKey, NamedImplKey}; use crate::syntax::map::UnorderedMap as Map; use crate::syntax::set::UnorderedSet; use crate::syntax::symbol::Symbol; @@ -1349,7 +1349,7 @@ fn write_generic_instantiations(out: &mut OutFile) { out.begin_block(Block::ExternC); for impl_key in out.types.impls.keys() { out.next_section(); - match impl_key { + match *impl_key { ImplKey::RustBox(ident) => write_rust_box_extern(out, ident), ImplKey::RustVec(ident) => write_rust_vec_extern(out, ident), ImplKey::UniquePtr(ident) => write_unique_ptr(out, ident), @@ -1363,7 +1363,7 @@ fn write_generic_instantiations(out: &mut OutFile) { out.begin_block(Block::Namespace("rust")); out.begin_block(Block::InlineNamespace("cxxbridge1")); for impl_key in out.types.impls.keys() { - match impl_key { + match *impl_key { ImplKey::RustBox(ident) => write_rust_box_impl(out, ident), ImplKey::RustVec(ident) => write_rust_vec_impl(out, ident), _ => {} @@ -1373,8 +1373,8 @@ fn write_generic_instantiations(out: &mut OutFile) { out.end_block(Block::Namespace("rust")); } -fn write_rust_box_extern(out: &mut OutFile, ident: &Ident) { - let resolve = out.types.resolve(ident); +fn write_rust_box_extern(out: &mut OutFile, key: NamedImplKey) { + let resolve = out.types.resolve(&key); let inner = resolve.name.to_fully_qualified(); let instance = resolve.name.to_symbol(); @@ -1395,7 +1395,8 @@ fn write_rust_box_extern(out: &mut OutFile, ident: &Ident) { ); } -fn write_rust_vec_extern(out: &mut OutFile, element: &Ident) { +fn write_rust_vec_extern(out: &mut OutFile, key: NamedImplKey) { + let element = key.rust; let inner = element.to_typename(out.types); let instance = element.to_mangled(out.types); @@ -1438,8 +1439,8 @@ fn write_rust_vec_extern(out: &mut OutFile, element: &Ident) { ); } -fn write_rust_box_impl(out: &mut OutFile, ident: &Ident) { - let resolve = out.types.resolve(ident); +fn write_rust_box_impl(out: &mut OutFile, key: NamedImplKey) { + let resolve = out.types.resolve(&key); let inner = resolve.name.to_fully_qualified(); let instance = resolve.name.to_symbol(); @@ -1470,7 +1471,8 @@ fn write_rust_box_impl(out: &mut OutFile, ident: &Ident) { writeln!(out, "}}"); } -fn write_rust_vec_impl(out: &mut OutFile, element: &Ident) { +fn write_rust_vec_impl(out: &mut OutFile, key: NamedImplKey) { + let element = key.rust; let inner = element.to_typename(out.types); let instance = element.to_mangled(out.types); @@ -1547,8 +1549,8 @@ fn write_rust_vec_impl(out: &mut OutFile, element: &Ident) { writeln!(out, "}}"); } -fn write_unique_ptr(out: &mut OutFile, ident: &Ident) { - let ty = UniquePtr::Ident(ident); +fn write_unique_ptr(out: &mut OutFile, key: NamedImplKey) { + let ty = UniquePtr::Ident(key.rust); write_unique_ptr_common(out, ty); } @@ -1663,7 +1665,8 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { writeln!(out, "}}"); } -fn write_shared_ptr(out: &mut OutFile, ident: &Ident) { +fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) { + let ident = key.rust; let resolve = out.types.resolve(ident); let inner = resolve.name.to_fully_qualified(); let instance = resolve.name.to_symbol(); @@ -1735,8 +1738,8 @@ fn write_shared_ptr(out: &mut OutFile, ident: &Ident) { writeln!(out, "}}"); } -fn write_weak_ptr(out: &mut OutFile, ident: &Ident) { - let resolve = out.types.resolve(ident); +fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) { + let resolve = out.types.resolve(&key); let inner = resolve.name.to_fully_qualified(); let instance = resolve.name.to_symbol(); @@ -1794,7 +1797,8 @@ fn write_weak_ptr(out: &mut OutFile, ident: &Ident) { writeln!(out, "}}"); } -fn write_cxx_vector(out: &mut OutFile, element: &Ident) { +fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) { + let element = key.rust; let inner = element.to_typename(out.types); let instance = element.to_mangled(out.types); diff --git a/macro/src/expand.rs b/macro/src/expand.rs index 1ffd44f5f..32f9b9278 100644 --- a/macro/src/expand.rs +++ b/macro/src/expand.rs @@ -1,8 +1,7 @@ -use crate::derive; use crate::syntax::atom::Atom::*; use crate::syntax::attrs::{self, OtherAttrs}; use crate::syntax::file::Module; -use crate::syntax::instantiate::ImplKey; +use crate::syntax::instantiate::{ImplKey, NamedImplKey}; use crate::syntax::qualified::QualifiedName; use crate::syntax::report::Errors; use crate::syntax::symbol::Symbol; @@ -11,6 +10,7 @@ use crate::syntax::{ Struct, Trait, Type, TypeAlias, Types, }; use crate::type_id::Crate; +use crate::{derive, generics}; use proc_macro2::{Ident, Span, TokenStream}; use quote::{format_ident, quote, quote_spanned, ToTokens}; use std::mem; @@ -85,7 +85,7 @@ fn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types) } for (impl_key, &explicit_impl) in &types.impls { - match impl_key { + match *impl_key { ImplKey::RustBox(ident) => { hidden.extend(expand_rust_box(ident, types, explicit_impl)); } @@ -1125,7 +1125,8 @@ fn type_id(name: &Pair) -> TokenStream { crate::type_id::expand(Crate::Cxx, qualified) } -fn expand_rust_box(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { +fn expand_rust_box(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { + let ident = key.rust; let resolve = types.resolve(ident); let link_prefix = format!("cxxbridge1$box${}$", resolve.name.to_symbol()); let link_alloc = format!("{}alloc", link_prefix); @@ -1137,15 +1138,10 @@ fn expand_rust_box(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) - let local_dealloc = format_ident!("{}dealloc", local_prefix); let local_drop = format_ident!("{}drop", local_prefix); - let (impl_generics, ty_generics) = if let Some(imp) = explicit_impl { - (&imp.impl_generics, &imp.ty_generics) - } else { - (resolve.generics, resolve.generics) - }; + let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); - let begin_span = - explicit_impl.map_or_else(Span::call_site, |explicit| explicit.impl_token.span); - let end_span = explicit_impl.map_or_else(Span::call_site, |explicit| explicit.brace_token.span); + let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); + let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span); let unsafe_token = format_ident!("unsafe", span = begin_span); quote_spanned! {end_span=> @@ -1169,7 +1165,8 @@ fn expand_rust_box(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) - } } -fn expand_rust_vec(elem: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { +fn expand_rust_vec(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { + let elem = key.rust; let resolve = types.resolve(elem); let link_prefix = format!("cxxbridge1$rust_vec${}$", resolve.name.to_symbol()); let link_new = format!("{}new", link_prefix); @@ -1189,15 +1186,10 @@ fn expand_rust_vec(elem: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> let local_reserve_total = format_ident!("{}reserve_total", local_prefix); let local_set_len = format_ident!("{}set_len", local_prefix); - let (impl_generics, ty_generics) = if let Some(imp) = explicit_impl { - (&imp.impl_generics, &imp.ty_generics) - } else { - (resolve.generics, resolve.generics) - }; + let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); - let begin_span = - explicit_impl.map_or_else(Span::call_site, |explicit| explicit.impl_token.span); - let end_span = explicit_impl.map_or_else(Span::call_site, |explicit| explicit.brace_token.span); + let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); + let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span); let unsafe_token = format_ident!("unsafe", span = begin_span); quote_spanned! {end_span=> @@ -1241,7 +1233,12 @@ fn expand_rust_vec(elem: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> } } -fn expand_unique_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { +fn expand_unique_ptr( + key: NamedImplKey, + types: &Types, + explicit_impl: Option<&Impl>, +) -> TokenStream { + let ident = key.rust; let name = ident.to_string(); let resolve = types.resolve(ident); let prefix = format!("cxxbridge1$unique_ptr${}$", resolve.name.to_symbol()); @@ -1252,11 +1249,7 @@ fn expand_unique_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) let link_release = format!("{}release", prefix); let link_drop = format!("{}drop", prefix); - let (impl_generics, ty_generics) = if let Some(imp) = explicit_impl { - (&imp.impl_generics, &imp.ty_generics) - } else { - (resolve.generics, resolve.generics) - }; + let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); let can_construct_from_value = types.structs.contains_key(ident) || types.enums.contains_key(ident) @@ -1278,9 +1271,8 @@ fn expand_unique_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) None }; - let begin_span = - explicit_impl.map_or_else(Span::call_site, |explicit| explicit.impl_token.span); - let end_span = explicit_impl.map_or_else(Span::call_site, |explicit| explicit.brace_token.span); + let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); + let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span); let unsafe_token = format_ident!("unsafe", span = begin_span); quote_spanned! {end_span=> @@ -1338,7 +1330,12 @@ fn expand_unique_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) } } -fn expand_shared_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { +fn expand_shared_ptr( + key: NamedImplKey, + types: &Types, + explicit_impl: Option<&Impl>, +) -> TokenStream { + let ident = key.rust; let name = ident.to_string(); let resolve = types.resolve(ident); let prefix = format!("cxxbridge1$shared_ptr${}$", resolve.name.to_symbol()); @@ -1348,11 +1345,7 @@ fn expand_shared_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) let link_get = format!("{}get", prefix); let link_drop = format!("{}drop", prefix); - let (impl_generics, ty_generics) = if let Some(imp) = explicit_impl { - (&imp.impl_generics, &imp.ty_generics) - } else { - (resolve.generics, resolve.generics) - }; + let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); let can_construct_from_value = types.structs.contains_key(ident) || types.enums.contains_key(ident) @@ -1372,9 +1365,8 @@ fn expand_shared_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) None }; - let begin_span = - explicit_impl.map_or_else(Span::call_site, |explicit| explicit.impl_token.span); - let end_span = explicit_impl.map_or_else(Span::call_site, |explicit| explicit.brace_token.span); + let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); + let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span); let unsafe_token = format_ident!("unsafe", span = begin_span); quote_spanned! {end_span=> @@ -1420,7 +1412,8 @@ fn expand_shared_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) } } -fn expand_weak_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { +fn expand_weak_ptr(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { + let ident = key.rust; let name = ident.to_string(); let resolve = types.resolve(ident); let prefix = format!("cxxbridge1$weak_ptr${}$", resolve.name.to_symbol()); @@ -1430,15 +1423,10 @@ fn expand_weak_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) - let link_upgrade = format!("{}upgrade", prefix); let link_drop = format!("{}drop", prefix); - let (impl_generics, ty_generics) = if let Some(imp) = explicit_impl { - (&imp.impl_generics, &imp.ty_generics) - } else { - (resolve.generics, resolve.generics) - }; + let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); - let begin_span = - explicit_impl.map_or_else(Span::call_site, |explicit| explicit.impl_token.span); - let end_span = explicit_impl.map_or_else(Span::call_site, |explicit| explicit.brace_token.span); + let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); + let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span); let unsafe_token = format_ident!("unsafe", span = begin_span); quote_spanned! {end_span=> @@ -1491,7 +1479,12 @@ fn expand_weak_ptr(ident: &Ident, types: &Types, explicit_impl: Option<&Impl>) - } } -fn expand_cxx_vector(elem: &Ident, explicit_impl: Option<&Impl>, types: &Types) -> TokenStream { +fn expand_cxx_vector( + key: NamedImplKey, + explicit_impl: Option<&Impl>, + types: &Types, +) -> TokenStream { + let elem = key.rust; let name = elem.to_string(); let resolve = types.resolve(elem); let prefix = format!("cxxbridge1$std$vector${}$", resolve.name.to_symbol()); @@ -1507,15 +1500,10 @@ fn expand_cxx_vector(elem: &Ident, explicit_impl: Option<&Impl>, types: &Types) let link_unique_ptr_release = format!("{}release", unique_ptr_prefix); let link_unique_ptr_drop = format!("{}drop", unique_ptr_prefix); - let (impl_generics, ty_generics) = if let Some(imp) = explicit_impl { - (&imp.impl_generics, &imp.ty_generics) - } else { - (resolve.generics, resolve.generics) - }; + let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); - let begin_span = - explicit_impl.map_or_else(Span::call_site, |explicit| explicit.impl_token.span); - let end_span = explicit_impl.map_or_else(Span::call_site, |explicit| explicit.brace_token.span); + let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); + let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span); let unsafe_token = format_ident!("unsafe", span = begin_span); quote_spanned! {end_span=> diff --git a/macro/src/generics.rs b/macro/src/generics.rs new file mode 100644 index 000000000..6c391fc72 --- /dev/null +++ b/macro/src/generics.rs @@ -0,0 +1,55 @@ +use crate::syntax::instantiate::NamedImplKey; +use crate::syntax::resolve::Resolution; +use crate::syntax::Impl; +use proc_macro2::TokenStream; +use quote::ToTokens; + +pub struct ImplGenerics<'a> { + explicit_impl: Option<&'a Impl>, + resolve: Resolution<'a>, +} + +pub struct TyGenerics<'a> { + key: NamedImplKey<'a>, + explicit_impl: Option<&'a Impl>, + resolve: Resolution<'a>, +} + +pub fn split_for_impl<'a>( + key: NamedImplKey<'a>, + explicit_impl: Option<&'a Impl>, + resolve: Resolution<'a>, +) -> (ImplGenerics<'a>, TyGenerics<'a>) { + let impl_generics = ImplGenerics { + explicit_impl, + resolve, + }; + let ty_generics = TyGenerics { + key, + explicit_impl, + resolve, + }; + (impl_generics, ty_generics) +} + +impl<'a> ToTokens for ImplGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + if let Some(imp) = self.explicit_impl { + imp.impl_generics.to_tokens(tokens); + } else { + self.resolve.generics.to_tokens(tokens); + } + } +} + +impl<'a> ToTokens for TyGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + if let Some(imp) = self.explicit_impl { + imp.ty_generics.to_tokens(tokens); + } else { + self.key.lt_token.to_tokens(tokens); + self.resolve.generics.lifetimes.to_tokens(tokens); + self.key.gt_token.to_tokens(tokens); + } + } +} diff --git a/macro/src/lib.rs b/macro/src/lib.rs index c24a6075e..f8e790346 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -32,6 +32,7 @@ extern crate proc_macro; mod derive; mod expand; +mod generics; mod syntax; mod type_id; diff --git a/syntax/instantiate.rs b/syntax/instantiate.rs index e9c6f29c7..b6cbf24b5 100644 --- a/syntax/instantiate.rs +++ b/syntax/instantiate.rs @@ -1,43 +1,80 @@ -use crate::syntax::Type; -use proc_macro2::Ident; +use crate::syntax::{NamedType, Ty1, Type}; +use proc_macro2::{Ident, Span}; +use std::hash::{Hash, Hasher}; +use syn::Token; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum ImplKey<'a> { - RustBox(&'a Ident), - RustVec(&'a Ident), - UniquePtr(&'a Ident), - SharedPtr(&'a Ident), - WeakPtr(&'a Ident), - CxxVector(&'a Ident), + RustBox(NamedImplKey<'a>), + RustVec(NamedImplKey<'a>), + UniquePtr(NamedImplKey<'a>), + SharedPtr(NamedImplKey<'a>), + WeakPtr(NamedImplKey<'a>), + CxxVector(NamedImplKey<'a>), +} + +#[derive(Copy, Clone)] +pub struct NamedImplKey<'a> { + pub begin_span: Span, + pub rust: &'a Ident, + pub lt_token: Option, + pub gt_token: Option]>, + pub end_span: Span, } impl Type { pub(crate) fn impl_key(&self) -> Option { if let Type::RustBox(ty) = self { if let Type::Ident(ident) = &ty.inner { - return Some(ImplKey::RustBox(&ident.rust)); + return Some(ImplKey::RustBox(NamedImplKey::new(ty, ident))); } } else if let Type::RustVec(ty) = self { if let Type::Ident(ident) = &ty.inner { - return Some(ImplKey::RustVec(&ident.rust)); + return Some(ImplKey::RustVec(NamedImplKey::new(ty, ident))); } } else if let Type::UniquePtr(ty) = self { if let Type::Ident(ident) = &ty.inner { - return Some(ImplKey::UniquePtr(&ident.rust)); + return Some(ImplKey::UniquePtr(NamedImplKey::new(ty, ident))); } } else if let Type::SharedPtr(ty) = self { if let Type::Ident(ident) = &ty.inner { - return Some(ImplKey::SharedPtr(&ident.rust)); + return Some(ImplKey::SharedPtr(NamedImplKey::new(ty, ident))); } } else if let Type::WeakPtr(ty) = self { if let Type::Ident(ident) = &ty.inner { - return Some(ImplKey::WeakPtr(&ident.rust)); + return Some(ImplKey::WeakPtr(NamedImplKey::new(ty, ident))); } } else if let Type::CxxVector(ty) = self { if let Type::Ident(ident) = &ty.inner { - return Some(ImplKey::CxxVector(&ident.rust)); + return Some(ImplKey::CxxVector(NamedImplKey::new(ty, ident))); } } None } } + +impl<'a> PartialEq for NamedImplKey<'a> { + fn eq(&self, other: &Self) -> bool { + PartialEq::eq(self.rust, other.rust) + } +} + +impl<'a> Eq for NamedImplKey<'a> {} + +impl<'a> Hash for NamedImplKey<'a> { + fn hash(&self, hasher: &mut H) { + self.rust.hash(hasher); + } +} + +impl<'a> NamedImplKey<'a> { + fn new(outer: &Ty1, inner: &'a NamedType) -> Self { + NamedImplKey { + begin_span: outer.name.span(), + rust: &inner.rust, + lt_token: inner.generics.lt_token, + gt_token: inner.generics.gt_token, + end_span: outer.rangle.span, + } + } +} diff --git a/syntax/mod.rs b/syntax/mod.rs index 5422681f2..3d5629316 100644 --- a/syntax/mod.rs +++ b/syntax/mod.rs @@ -20,7 +20,7 @@ mod parse; mod pod; pub mod qualified; pub mod report; -mod resolve; +pub mod resolve; pub mod set; pub mod symbol; mod tokens; diff --git a/syntax/resolve.rs b/syntax/resolve.rs index 08fcf1650..821f54276 100644 --- a/syntax/resolve.rs +++ b/syntax/resolve.rs @@ -1,3 +1,4 @@ +use crate::syntax::instantiate::NamedImplKey; use crate::syntax::{Lifetimes, NamedType, Pair, Types}; use proc_macro2::Ident; @@ -31,3 +32,9 @@ impl UnresolvedName for NamedType { &self.rust } } + +impl<'a> UnresolvedName for NamedImplKey<'a> { + fn ident(&self) -> &Ident { + self.rust + } +} diff --git a/syntax/types.rs b/syntax/types.rs index 196a1db99..af7916d76 100644 --- a/syntax/types.rs +++ b/syntax/types.rs @@ -171,7 +171,7 @@ impl<'a> Types<'a> { | ImplKey::SharedPtr(ident) | ImplKey::WeakPtr(ident) | ImplKey::CxxVector(ident) => { - Atom::from(ident).is_none() && !aliases.contains_key(ident) + Atom::from(ident.rust).is_none() && !aliases.contains_key(ident.rust) } }; if implicit_impl && !impls.contains_key(&impl_key) { diff --git a/tests/ui/nonlocal_rust_type.rs b/tests/ui/nonlocal_rust_type.rs new file mode 100644 index 000000000..d8a238aee --- /dev/null +++ b/tests/ui/nonlocal_rust_type.rs @@ -0,0 +1,18 @@ +pub struct MyBuilder<'a> { + _s: &'a str, +} + +type OptBuilder<'a> = Option>; + +#[cxx::bridge] +mod ffi { + extern "Rust" { + type OptBuilder<'a>; + } + + struct MyBuilder<'a> { + rs: Box>, + } +} + +fn main() {} diff --git a/tests/ui/nonlocal_rust_type.stderr b/tests/ui/nonlocal_rust_type.stderr new file mode 100644 index 000000000..d266353c2 --- /dev/null +++ b/tests/ui/nonlocal_rust_type.stderr @@ -0,0 +1,21 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/nonlocal_rust_type.rs:10:9 + | +10 | type OptBuilder<'a>; + | ^^^^^-------------- + | | | + | | `Option` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/nonlocal_rust_type.rs:14:13 + | +14 | rs: Box>, + | ^^^^--------------- + | | | + | | `Option` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead