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

Remove type parameter defaults #71

Merged
merged 5 commits into from
Mar 5, 2021

Conversation

dvdplm
Copy link
Contributor

@dvdplm dvdplm commented Mar 2, 2021

Defaults for type parameter bounds are only allowed in structs, enums, type and trait definitions, not in impl blocks, so when deriving the TypeInfo impl we have to remove them.

See rust-lang/rust#36887 for details.

@dvdplm dvdplm self-assigned this Mar 2, 2021
@dvdplm dvdplm requested a review from ascjones March 2, 2021 19:26
// Remove any type parameter defaults, we don't want those. E.g. `impl<T: Stuff = WutEven>`
ast.generics.type_params_mut().for_each(|type_param| {
type_param.default = None;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to use ImplGenerics from split_for_impl() above to avoid this? Not sure whether it will work with our modified lifetimes or not.

Copy link
Contributor Author

@dvdplm dvdplm Mar 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct that ImplGenerics takes care of removing the defaults and it takes care of const parameter defaults too, so it's strictly better.

However there's another problem: we replace all lifetimes with 'static and this means that given this input:

struct Goat<'bar, T: SomeTrait = SomeDefault>

we get this in the expansion:

impl<'static, T: SomeTrait>

(which is invalid syntax)

So ImplGenerics is the right tool for the job, but using it will require cloning&munging elsewhere. Not sure what is least worse tbh. :/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have an idea: remove the replacing of lifetimes and add something like this to make_where_clause:

for lifetime in generics.lifetimes() {
        where_clause
            .predicates
            .push(parse_quote!(#lifetime : 'static));
    }

That way we should be able to use ImplGenerics and remove completely the two mutable bits.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are completely right. And as an extra bonus we now don't need to clone the input anymore. ❤️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With your suggestion we get an expansion like this:

    struct Assoc<'bar, T: Types> {
        a: T::A,
        b: &'bar u64,
    }
    
    const _: () = {
        impl<'bar, T: Types> ::scale_info::TypeInfo for Assoc<'bar, T>
        where
            'bar: 'static,
            T::A: ::scale_info::TypeInfo + 'static,
            T: Types + ::scale_info::TypeInfo + 'static,
			…
			…

That 'bar: 'static looks a bit funny but it's valid syntax so all good.

Copy link
Contributor

@ascjones ascjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#![cfg_attr(not(feature = "std"), no_std)]
// #![cfg_attr(not(feature = "std"), no_std)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, my bad.

But while we're at it: we should probably remove this anyway. The derive crate doesn't need to be no-std I think (only its output must be no-std). And as we're using proc-macro-crate already it's perhaps good to acknowledge the fact that scale-info-derive isn't actually no-std?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm not sure why that's there in the first place, but if we remove it should not be hidden in this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #69 (comment) – I removed it in that PR.

@dvdplm dvdplm merged commit 713921e into master Mar 5, 2021
@dvdplm dvdplm deleted the dp-remove-type-parameter-defaults-from-impl branch March 5, 2021 12:26
@ascjones ascjones mentioned this pull request Jun 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants