mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-14 17:18:20 +00:00
Merge pull request #483 from nikomatsakis/salsa-2022-spans
improve spans for getters, constructors
This commit is contained in:
commit
45fd94120b
11 changed files with 123 additions and 27 deletions
|
@ -1,4 +1,4 @@
|
|||
use syn::ItemStruct;
|
||||
use syn::{spanned::Spanned, ItemStruct};
|
||||
|
||||
// #[salsa::accumulator(jar = Jar0)]
|
||||
// struct Accumulator(DataType);
|
||||
|
@ -86,7 +86,7 @@ fn struct_item_out(
|
|||
data_ty: &syn::Type,
|
||||
) -> syn::ItemStruct {
|
||||
let mut struct_item_out = struct_item.clone();
|
||||
struct_item_out.fields = syn::Fields::Unnamed(parse_quote! {
|
||||
struct_item_out.fields = syn::Fields::Unnamed(parse_quote_spanned! { data_ty.span() =>
|
||||
(std::marker::PhantomData<#data_ty>)
|
||||
});
|
||||
struct_item_out
|
||||
|
@ -94,7 +94,7 @@ fn struct_item_out(
|
|||
|
||||
fn inherent_impl(args: &Args, struct_ty: &syn::Type, data_ty: &syn::Type) -> syn::ItemImpl {
|
||||
let jar_ty = args.jar_ty();
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { struct_ty.span() =>
|
||||
impl #struct_ty {
|
||||
pub fn push<DB: ?Sized>(db: &DB, data: #data_ty)
|
||||
where
|
||||
|
@ -115,7 +115,7 @@ fn ingredients_for_impl(
|
|||
) -> syn::ItemImpl {
|
||||
let jar_ty = args.jar_ty();
|
||||
let debug_name = crate::literal(struct_name);
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { struct_name.span() =>
|
||||
impl salsa::storage::IngredientsFor for #struct_name {
|
||||
type Ingredients = salsa::accumulator::AccumulatorIngredient<#data_ty>;
|
||||
type Jar = #jar_ty;
|
||||
|
@ -142,7 +142,7 @@ fn ingredients_for_impl(
|
|||
|
||||
fn accumulator_impl(args: &Args, struct_ty: &syn::Type, data_ty: &syn::Type) -> syn::ItemImpl {
|
||||
let jar_ty = args.jar_ty();
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { struct_ty.span() =>
|
||||
impl salsa::accumulator::Accumulator for #struct_ty {
|
||||
type Data = #data_ty;
|
||||
type Jar = #jar_ty;
|
||||
|
|
|
@ -81,7 +81,7 @@ impl InputStruct {
|
|||
let get_field_names: Vec<_> = self.all_get_field_names();
|
||||
let field_getters: Vec<syn::ImplItemMethod> = field_indices.iter().zip(&get_field_names).zip(&field_vises).zip(&field_tys).zip(&field_clones).map(|((((field_index, get_field_name), field_vis), field_ty), is_clone_field)|
|
||||
if !*is_clone_field {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { get_field_name.span() =>
|
||||
#field_vis fn #get_field_name<'db>(self, __db: &'db #db_dyn_ty) -> &'db #field_ty
|
||||
{
|
||||
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db);
|
||||
|
@ -90,7 +90,7 @@ impl InputStruct {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { get_field_name.span() =>
|
||||
#field_vis fn #get_field_name<'db>(self, __db: &'db #db_dyn_ty) -> #field_ty
|
||||
{
|
||||
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db);
|
||||
|
@ -110,7 +110,7 @@ impl InputStruct {
|
|||
.zip(&field_tys)
|
||||
.filter_map(|(((field_index, &set_field_name), field_vis), field_ty)| {
|
||||
let set_field_name = set_field_name?;
|
||||
Some(parse_quote! {
|
||||
Some(parse_quote_spanned! { set_field_name.span() =>
|
||||
#field_vis fn #set_field_name<'db>(self, __db: &'db mut #db_dyn_ty) -> salsa::setter::Setter<'db, #ident, #field_ty>
|
||||
{
|
||||
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar_mut(__db);
|
||||
|
@ -125,7 +125,7 @@ impl InputStruct {
|
|||
let singleton = self.0.is_isingleton();
|
||||
|
||||
let constructor: syn::ImplItemMethod = if singleton {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { constructor_name.span() =>
|
||||
/// Creates a new singleton input
|
||||
///
|
||||
/// # Panics
|
||||
|
@ -143,7 +143,7 @@ impl InputStruct {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { constructor_name.span() =>
|
||||
pub fn #constructor_name(__db: &#db_dyn_ty, #(#field_names: #field_tys,)*) -> Self
|
||||
{
|
||||
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db);
|
||||
|
@ -177,6 +177,7 @@ impl InputStruct {
|
|||
};
|
||||
|
||||
parse_quote! {
|
||||
#[allow(dead_code)]
|
||||
impl #ident {
|
||||
#constructor
|
||||
|
||||
|
@ -191,6 +192,7 @@ impl InputStruct {
|
|||
}
|
||||
} else {
|
||||
parse_quote! {
|
||||
#[allow(dead_code)]
|
||||
impl #ident {
|
||||
#constructor
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ impl InternedStruct {
|
|||
let field_vis = field.vis();
|
||||
let field_get_name = field.get_name();
|
||||
if field.is_clone_field() {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { field_get_name.span() =>
|
||||
#field_vis fn #field_get_name(self, db: &#db_dyn_ty) -> #field_ty {
|
||||
let (jar, runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(db);
|
||||
let ingredients = <#jar_ty as salsa::storage::HasIngredientsFor< #id_ident >>::ingredient(jar);
|
||||
|
@ -102,7 +102,7 @@ impl InternedStruct {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { field_get_name.span() =>
|
||||
#field_vis fn #field_get_name<'db>(self, db: &'db #db_dyn_ty) -> &'db #field_ty {
|
||||
let (jar, runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(db);
|
||||
let ingredients = <#jar_ty as salsa::storage::HasIngredientsFor< #id_ident >>::ingredient(jar);
|
||||
|
@ -117,7 +117,7 @@ impl InternedStruct {
|
|||
let field_tys = self.all_field_tys();
|
||||
let data_ident = self.data_ident();
|
||||
let constructor_name = self.constructor_name();
|
||||
let new_method: syn::ImplItemMethod = parse_quote! {
|
||||
let new_method: syn::ImplItemMethod = parse_quote_spanned! { constructor_name.span() =>
|
||||
#vis fn #constructor_name(
|
||||
db: &#db_dyn_ty,
|
||||
#(#field_names: #field_tys,)*
|
||||
|
@ -131,6 +131,7 @@ impl InternedStruct {
|
|||
};
|
||||
|
||||
parse_quote! {
|
||||
#[allow(dead_code)]
|
||||
impl #id_ident {
|
||||
#(#field_getters)*
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ impl<A: AllowedOptions> SalsaStruct<A> {
|
|||
.filter(|attr| !attr.path.is_ident("customize"))
|
||||
.collect();
|
||||
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { ident.span() =>
|
||||
#(#attrs)*
|
||||
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
|
||||
#visibility struct #ident(salsa::Id);
|
||||
|
@ -206,7 +206,7 @@ impl<A: AllowedOptions> SalsaStruct<A> {
|
|||
let visibility = self.visibility();
|
||||
let all_field_names = self.all_field_names();
|
||||
let all_field_tys = self.all_field_tys();
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { ident.span() =>
|
||||
/// Internal struct used for interned item
|
||||
#[derive(Eq, PartialEq, Hash, Clone)]
|
||||
#visibility struct #ident {
|
||||
|
@ -226,14 +226,14 @@ impl<A: AllowedOptions> SalsaStruct<A> {
|
|||
pub(crate) fn constructor_name(&self) -> syn::Ident {
|
||||
match self.args.constructor_name.clone() {
|
||||
Some(name) => name,
|
||||
None => Ident::new("new", Span::call_site()),
|
||||
None => Ident::new("new", self.id_ident().span()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate `impl salsa::AsId for Foo`
|
||||
pub(crate) fn as_id_impl(&self) -> syn::ItemImpl {
|
||||
let ident = self.id_ident();
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { ident.span() =>
|
||||
impl salsa::AsId for #ident {
|
||||
fn as_id(self) -> salsa::Id {
|
||||
self.0
|
||||
|
@ -352,8 +352,8 @@ impl SalsaField {
|
|||
));
|
||||
}
|
||||
|
||||
let get_name = Ident::new(&field_name_str, Span::call_site());
|
||||
let set_name = Ident::new(&format!("set_{}", field_name_str), Span::call_site());
|
||||
let get_name = Ident::new(&field_name_str, field_name.span());
|
||||
let set_name = Ident::new(&format!("set_{}", field_name_str), field_name.span());
|
||||
let mut result = SalsaField {
|
||||
field: field.clone(),
|
||||
has_id_attr: false,
|
||||
|
|
|
@ -168,7 +168,7 @@ impl TrackedStruct {
|
|||
let field_clones: Vec<_> = self.all_fields().map(SalsaField::is_clone_field).collect();
|
||||
let field_getters: Vec<syn::ImplItemMethod> = field_indices.iter().zip(&field_get_names).zip(&field_tys).zip(&field_vises).zip(&field_clones).map(|((((field_index, field_get_name), field_ty), field_vis), is_clone_field)|
|
||||
if !*is_clone_field {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { field_get_name.span() =>
|
||||
#field_vis fn #field_get_name<'db>(self, __db: &'db #db_dyn_ty) -> &'db #field_ty
|
||||
{
|
||||
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db);
|
||||
|
@ -177,7 +177,7 @@ impl TrackedStruct {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
parse_quote! {
|
||||
parse_quote_spanned! { field_get_name.span() =>
|
||||
#field_vis fn #field_get_name<'db>(self, __db: &'db #db_dyn_ty) -> #field_ty
|
||||
{
|
||||
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar(__db);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0624]: method `field` is private
|
||||
--> tests/compile-fail/get-set-on-private-field.rs:29:11
|
||||
|
|
||||
7 | #[salsa::input(jar = Jar)]
|
||||
| -------------------------- private method defined here
|
||||
9 | field: u32,
|
||||
| ---------- private method defined here
|
||||
...
|
||||
29 | input.field(&db);
|
||||
| ^^^^^ private method
|
||||
|
@ -10,8 +10,8 @@ error[E0624]: method `field` is private
|
|||
error[E0624]: method `set_field` is private
|
||||
--> tests/compile-fail/get-set-on-private-field.rs:30:11
|
||||
|
|
||||
7 | #[salsa::input(jar = Jar)]
|
||||
| -------------------------- private method defined here
|
||||
9 | field: u32,
|
||||
| ----- private method defined here
|
||||
...
|
||||
30 | input.set_field(&mut db).to(23);
|
||||
| ^^^^^^^^^ private method
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0599]: no method named `set_id_one` found for struct `MyInput` in the current scope
|
||||
--> tests/compile-fail/input_struct_id_fields_no_setters.rs:30:11
|
||||
|
|
||||
7 | #[salsa::input(jar = Jar)]
|
||||
| -------------------------- method `set_id_one` not found for this struct
|
||||
8 | struct MyInput {
|
||||
| ------- method `set_id_one` not found for this struct
|
||||
...
|
||||
30 | input.set_id_one(1);
|
||||
| ^^^^^^^^^^ help: there is a method with a similar name: `id_one`
|
||||
|
|
27
salsa-2022-tests/tests/compile-fail/span-input-setter.rs
Normal file
27
salsa-2022-tests/tests/compile-fail/span-input-setter.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
#[salsa::jar(db = Db)]
|
||||
pub struct Jar(MyInput);
|
||||
|
||||
pub trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
impl Db for Database {}
|
||||
|
||||
#[salsa::input]
|
||||
pub struct MyInput {
|
||||
field: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut db = Database::default();
|
||||
let input = MyInput::new(&mut db, 22);
|
||||
|
||||
input.field(&db);
|
||||
input.set_field(22);
|
||||
}
|
18
salsa-2022-tests/tests/compile-fail/span-input-setter.stderr
Normal file
18
salsa-2022-tests/tests/compile-fail/span-input-setter.stderr
Normal file
|
@ -0,0 +1,18 @@
|
|||
error[E0308]: mismatched types
|
||||
--> tests/compile-fail/span-input-setter.rs:26:21
|
||||
|
|
||||
26 | input.set_field(22);
|
||||
| --------- ^^ expected `&mut dyn Db`, found integer
|
||||
| |
|
||||
| arguments to this method are incorrect
|
||||
|
|
||||
= note: expected mutable reference `&mut dyn Db`
|
||||
found type `{integer}`
|
||||
note: method defined here
|
||||
--> tests/compile-fail/span-input-setter.rs:18:5
|
||||
|
|
||||
16 | #[salsa::input]
|
||||
| ---------------
|
||||
17 | pub struct MyInput {
|
||||
18 | field: u32,
|
||||
| ^^^^^
|
30
salsa-2022-tests/tests/compile-fail/span-tracked-getter.rs
Normal file
30
salsa-2022-tests/tests/compile-fail/span-tracked-getter.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
#[salsa::jar(db = Db)]
|
||||
pub struct Jar(MyTracked, my_fn);
|
||||
|
||||
pub trait Db: salsa::DbWithJar<Jar> {}
|
||||
|
||||
#[salsa::db(Jar)]
|
||||
#[derive(Default)]
|
||||
struct Database {
|
||||
storage: salsa::Storage<Self>,
|
||||
}
|
||||
|
||||
impl salsa::Database for Database {}
|
||||
|
||||
impl Db for Database {}
|
||||
|
||||
#[salsa::tracked]
|
||||
pub struct MyTracked {
|
||||
field: u32,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn my_fn(db: &dyn crate::Db) {
|
||||
let x = MyTracked::new(db, 22);
|
||||
x.field(22);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut db = Database::default();
|
||||
my_fn(&db);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
error[E0308]: mismatched types
|
||||
--> tests/compile-fail/span-tracked-getter.rs:24:13
|
||||
|
|
||||
24 | x.field(22);
|
||||
| ----- ^^ expected `&dyn Db`, found integer
|
||||
| |
|
||||
| arguments to this method are incorrect
|
||||
|
|
||||
= note: expected reference `&dyn Db`
|
||||
found type `{integer}`
|
||||
note: method defined here
|
||||
--> tests/compile-fail/span-tracked-getter.rs:18:5
|
||||
|
|
||||
16 | #[salsa::tracked]
|
||||
| -----------------
|
||||
17 | pub struct MyTracked {
|
||||
18 | field: u32,
|
||||
| ^^^^^
|
Loading…
Reference in a new issue