383: Have users of `SalsaStruct` specify allowed options r=XFFXFF a=DropDemBits

This allows adding new options exclusively to `tracked`, `input`, `interned`, or any combination of them, without having to add support code to `SalsaStruct`.

The motivating example is #337, where `input` needs to accept a new `singleton` option, but `tracked` and `interned` should reject it.

Co-authored-by: DropDemBits <r3usrlnd@gmail.com>
This commit is contained in:
bors[bot] 2022-08-25 23:39:01 +00:00 committed by GitHub
commit 6ee0889948
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 30 deletions

View file

@ -17,16 +17,36 @@ pub(crate) fn input(
} }
} }
struct InputStruct(SalsaStruct); struct InputStruct(SalsaStruct<Self>);
impl std::ops::Deref for InputStruct { impl std::ops::Deref for InputStruct {
type Target = SalsaStruct; type Target = SalsaStruct<Self>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
} }
impl crate::options::AllowedOptions for InputStruct {
const RETURN_REF: bool = false;
const SPECIFY: bool = false;
const NO_EQ: bool = false;
const JAR: bool = true;
const DATA: bool = true;
const DB: bool = false;
const RECOVERY_FN: bool = false;
const LRU: bool = false;
const CONSTRUCTOR_NAME: bool = true;
}
impl InputStruct { impl InputStruct {
fn generate_input(&self) -> syn::Result<TokenStream> { fn generate_input(&self) -> syn::Result<TokenStream> {
self.validate_input()?; self.validate_input()?;

View file

@ -20,16 +20,36 @@ pub(crate) fn interned(
} }
} }
struct InternedStruct(SalsaStruct); struct InternedStruct(SalsaStruct<Self>);
impl std::ops::Deref for InternedStruct { impl std::ops::Deref for InternedStruct {
type Target = SalsaStruct; type Target = SalsaStruct<Self>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
} }
impl crate::options::AllowedOptions for InternedStruct {
const RETURN_REF: bool = false;
const SPECIFY: bool = false;
const NO_EQ: bool = false;
const JAR: bool = true;
const DATA: bool = true;
const DB: bool = false;
const RECOVERY_FN: bool = false;
const LRU: bool = false;
const CONSTRUCTOR_NAME: bool = true;
}
impl InternedStruct { impl InternedStruct {
fn generate_interned(&self) -> syn::Result<TokenStream> { fn generate_interned(&self) -> syn::Result<TokenStream> {
self.validate_interned()?; self.validate_interned()?;

View file

@ -29,37 +29,20 @@ use heck::ToUpperCamelCase;
use proc_macro2::{Ident, Literal, Span, TokenStream}; use proc_macro2::{Ident, Literal, Span, TokenStream};
use syn::spanned::Spanned; use syn::spanned::Spanned;
use crate::{configuration, options::Options}; use crate::{
configuration,
options::{AllowedOptions, Options},
};
pub(crate) struct SalsaStruct { pub(crate) struct SalsaStruct<A: AllowedOptions> {
args: Options<Self>, args: Options<A>,
struct_item: syn::ItemStruct, struct_item: syn::ItemStruct,
fields: Vec<SalsaField>, fields: Vec<SalsaField>,
} }
impl crate::options::AllowedOptions for SalsaStruct {
const RETURN_REF: bool = false;
const SPECIFY: bool = false;
const NO_EQ: bool = false;
const JAR: bool = true;
const DATA: bool = true;
const DB: bool = false;
const RECOVERY_FN: bool = false;
const LRU: bool = false;
const CONSTRUCTOR_NAME: bool = true;
}
const BANNED_FIELD_NAMES: &[&str] = &["from", "new"]; const BANNED_FIELD_NAMES: &[&str] = &["from", "new"];
impl SalsaStruct { impl<A: AllowedOptions> SalsaStruct<A> {
pub(crate) fn new( pub(crate) fn new(
args: proc_macro::TokenStream, args: proc_macro::TokenStream,
input: proc_macro::TokenStream, input: proc_macro::TokenStream,

View file

@ -19,16 +19,36 @@ pub(crate) fn tracked(
} }
} }
struct TrackedStruct(SalsaStruct); struct TrackedStruct(SalsaStruct<Self>);
impl std::ops::Deref for TrackedStruct { impl std::ops::Deref for TrackedStruct {
type Target = SalsaStruct; type Target = SalsaStruct<Self>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
} }
impl crate::options::AllowedOptions for TrackedStruct {
const RETURN_REF: bool = false;
const SPECIFY: bool = false;
const NO_EQ: bool = false;
const JAR: bool = true;
const DATA: bool = true;
const DB: bool = false;
const RECOVERY_FN: bool = false;
const LRU: bool = false;
const CONSTRUCTOR_NAME: bool = true;
}
impl TrackedStruct { impl TrackedStruct {
fn generate_tracked(&self) -> syn::Result<TokenStream> { fn generate_tracked(&self) -> syn::Result<TokenStream> {
self.validate_tracked()?; self.validate_tracked()?;