Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve span of errors on implicitly generated shim impls #786

Merged
merged 7 commits into from
Mar 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions gen/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand All @@ -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),
_ => {}
Expand All @@ -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();

Expand All @@ -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);

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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);

Expand Down
102 changes: 45 additions & 57 deletions macro/src/expand.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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);
Expand All @@ -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=>
Expand All @@ -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);
Expand All @@ -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=>
Expand Down Expand Up @@ -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());
Expand All @@ -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)
Expand All @@ -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=>
Expand Down Expand Up @@ -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());
Expand All @@ -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)
Expand All @@ -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=>
Expand Down Expand Up @@ -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());
Expand All @@ -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=>
Expand Down Expand Up @@ -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());
Expand All @@ -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=>
Expand Down
55 changes: 55 additions & 0 deletions macro/src/generics.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
1 change: 1 addition & 0 deletions macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern crate proc_macro;

mod derive;
mod expand;
mod generics;
mod syntax;
mod type_id;

Expand Down
Loading