Comments (12)
So how about doing what
serde
did and allow users to customize their trait bounds?
I like this idea, it's pragmatic and solves the problem. It does expose a bigger "API" to users which is always good to avoid. I don't have your deep knowledge/intuition about the possible future pitfalls so if you're convinced parsing the source is eventually going to fail then let's not go there. :)
from scale-info.
@thiolliere You are correct and my example above is wrong. The code that I was trying to rewrite as a test is this.
To repeat:
- remove the manual
impl
here - add
#[cfg_attr(feature = "dogfood", derive(scale_info_derive::TypeInfo))]
here - run
cargo c --features=dogfood
from scale-info.
It seems to me it is lacking:
Vec<T::Type>
, but I may be wrong.
The underlying issue here, I think, is a very good illustration of Robins point about syntactical vs semantical analysis.
The code here defines a type named Type
and makes use of a trait with an associated type that is also called Type
. The missing bound comes from this check where we end up missing the generic because it has the same Ident
as the type we're deriving.
I am sure there's a hacky way around that (using the full PathSegment
?) but it's likely just going to be a stop-gap solution until the next corner case pops up.
To see this bug in action, change the name of this associated type from A
to Assoc
: the derived bounds will be wrong.
@thiolliere It could be that parity-scale-codec
has a variant of the same issue somewhere around here, or maybe I'm reading the code wrong?
from scale-info.
Notice the odd Vec<P::Property>: ::scale_info::TypeInfo + 'static, in the expansion.
This is to be expected since the macro generates (as all standard proc. macros) trait bounds for all fields and their types.
I think the best we can do is to allow users to customize their trait bounds manually since any hackery to solve this automatically will eventually break other scenarios. The same is done for example in serde
.
from scale-info.
I was a bit surprised that Vec<T>: TypeInfo + 'static
is not enough, given that we already have impl<T> TypeInfo for Vec<T> where T: TypeInfo + 'static,
.
Either way, what do you think about trying a Visit
-or on the type of each field to recursively collect all the GenericParam
and add the bounds?
from scale-info.
Either way, what do you think about trying a Visit-or on the type of each field to recursively collect all the GenericParam and add the bounds?
I am always against doing syntactic analysis in proc. macros since you will always break your neck somewhere (mostly in some special cases) and end up with a half-baked solution anyways that will cause confusion to people and make things less transparent. So how about doing what serde
did and allow users to customize their trait bounds?
from scale-info.
This issue is a bit related to paritytech/parity-scale-codec#217
I actually think parity-scale-codec bounds too much generics in some context by visiting every types when it is not needed.
But I never took the time to be sure of this.
The derive macro however does not provide the last one,
P::Property: TypeInfo + 'static
I actually don't understand why you want to bound this, is it needed? AFAICT the Vec<P::Property>: ::scale_info::TypeInfo + 'static
should be enough to ensure that the field properties has type info.
Either way, what do you think about trying a Visit-or on the type of each field to recursively collect all the GenericParam and add the bounds?
My 2 cents is that this macro should do similar bounding than parity-scale-codec.
And I agree that allowing user to define bounds manually similarly to serde can be useful. Maybe we should do this here and in parity-scale-codec.
from scale-info.
The derive macro however does not provide the last one,
P::Property: TypeInfo + 'static
I actually don't understand why you want to bound this, is it needed? AFAICT the
Vec<P::Property>: ::scale_info::TypeInfo + 'static
should be enough to ensure that the field properties has type info.
rustc
seems to think it is needed, but I agree with you that the impl on Vec<T>
should be enough. Maybe there's something deeper going on here. :/
And I agree that allowing user to define bounds manually similarly to serde can be useful. Maybe we should do this here and in parity-scale-codec.
We had a call just now about scale-info
in general and agreed that adding this is useful. I don't think I'll have time to work on it before middle of next week so if you get it done first I'm always happy to steal code! :)
from scale-info.
EDIT: unrelated thus deleted
from scale-info.
@thiolliere yeah that's a different bug, #71
from scale-info.
ah ok, in your example when I look at the expanded code I see:
impl <T: Form> crate::TypeInfo for Type<T> where
Path<T>: crate::TypeInfo + 'static,
TypeDef<T>: crate::TypeInfo + 'static,
T: Form + crate::TypeInfo + 'static
It seems to me it is lacking: Vec<T::Type>
, but I may be wrong.
Also the issue I linked paritytech/parity-scale-codec#217 is not really related, it is about recursive types.
from scale-info.
I tried locally:
trait Types {
type Assoc;
}
#[derive(Encode, Decode)]
struct Assoc<T: Types> {
a: Vec<T::Assoc>,
}
And parity-scale-codec bounds Vec<T::Assoc>
correctly, because it checks that the first segment is of name "Assoc"
.
But
#[derive(Encode, Decode)]
struct Assoc<T: Types> {
a: Vec<<T>::Assoc>,
}
Fails indeed, we should ensure qself is empty.
I open an issue: paritytech/parity-scale-codec#257
from scale-info.
Related Issues (20)
- Add UI tests for crate renaming
- Support `r#` in the module path HOT 2
- Regression from latest release with crate resolution HOT 5
- trait bound `H256: TypeInfo` is not satisfied; `TypeInfo` is not implemented for `H256, H160, H64, ethereum_types::U256` HOT 3
- Could we have a rename function? HOT 4
- Strip pretty-printed invisible delimiters for type names
- I found a little flaws in `scale-info` doc V2.1.2
- bitvec 1.0 HOT 1
- Should PortableType be pub use?
- Can scale-info support `skip` or `ignore` for some struct field? HOT 1
- Don't enable bitvec when "std" feature is enabled
- Generated metadata includes `struct NonZeroU64(NonZeroU64)`, which is impossible to construct HOT 3
- Implement stable type id HOT 6
- Implement `TypeInfo` for `Duration`
- Update CI
- scale info is no longer no_std compatible HOT 1
- Optionally allow encoding `PhantomData<T>` types HOT 3
- What are `I256` and `U256` for? HOT 1
- Not an issue, but can you type info to have reflections in rust ? HOT 2
- New release? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from scale-info.