Stream: t-lang

Topic: #66183


centril (Nov 08 2019 at 17:39, on Zulip):

@T-lang So I'm hacking on https://github.com/rust-lang/rust/pull/66183 at the moment and I was wondering how y'all feel about syntactically allowing enum E { pub V, ... } (note the visibility!) but rejecting it semantically (in ast_validation.rs to be more specific)

pnkfelix (Nov 08 2019 at 17:44, on Zulip):

Maybe I’m missing something: if it’s rejected either way, then isn’t the just an implementation Q (for T-compiler), not a Lang team Q?

pnkfelix (Nov 08 2019 at 17:45, on Zulip):

I suppose there is fallout for macro_rules (some inputs will be parsed that would have been rejected before). Anything else?

centril (Nov 08 2019 at 17:46, on Zulip):

@pnkfelix right; it changes the formal grammar to accept them

centril (Nov 08 2019 at 17:47, on Zulip):

e.g. wg-grammar would include the visibility in the "BNF"

pnkfelix (Nov 08 2019 at 17:48, on Zulip):

I’m just trying to understand the consequences for ... well I don’t know about “average developer”, but one not involved with wg-grammar, let’s say

centril (Nov 08 2019 at 17:50, on Zulip):

@pnkfelix you can write e.g.:

macro_rules! mac {
    ($v:vis $i:ident) => {
        enum E { $v $i(u8), }
    }
}

mac!(Foo);

(this isn't very interesting but I recon there might be some DSL some user might build atop of this)

centril (Nov 08 2019 at 18:00, on Zulip):

Something potentially useful someone might think to create:

#[with_struct]
enum Foo {
    pub Bar(u8),
    pub Baz(u16),
}

// expands to:

pub struct Bar(u8);
pub struct Baz(u16);
enum Foo {
    Bar(Bar),
    Baz(Baz),
}
Lokathor (Nov 08 2019 at 18:01, on Zulip):

a proc macro can be aware of what it's doing and not put visibility on the enum part

centril (Nov 08 2019 at 18:01, on Zulip):

@Lokathor how do you mean?

centril (Nov 08 2019 at 18:05, on Zulip):

( https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6f2c6f48c2af39a8679b9dd0fba1cc39 )

Lokathor (Nov 08 2019 at 18:05, on Zulip):

a macro_rules! is a "stupid" automatic system that follows an inflexible ruleset for expansion

but a proc-macro is a much more crafted and bespoke system any time they're produced, and if you're going to make a proc-macro that can accept visibility tags and also emit custom enum definitions, then you should program the proc-macro to not put visibility on the enum tags, the same as your proc-macro shouldn't emit any other invalid data

Lokathor (Nov 08 2019 at 18:06, on Zulip):

(whoops fixed)

centril (Nov 08 2019 at 18:06, on Zulip):

@Lokathor you cannot encode a procedural macro that accepts the #[with_struct] enum Foo { pub Bar(u8), ... } above.

Lokathor (Nov 08 2019 at 18:08, on Zulip):

ah! my misunderstanding then!

i have only ever used the "function style" proc-macros which accept any token tree at all.

centril (Nov 08 2019 at 18:08, on Zulip):

ah :slight_smile: yeah, bang macros do accept arbitrary tts but attributes require well-formed syntax (an :item specifically in this case)

Lokathor (Nov 08 2019 at 18:12, on Zulip):

then it seems like a good change.

also, private enum variants might even become a good idea some day once non_exhaustive has been stable for a while.

centril (Nov 08 2019 at 18:12, on Zulip):

I think it would, but it probably takes more than the 30 minutes it would take for me to allow it syntactically ^^

pnkfelix (Nov 08 2019 at 19:34, on Zulip):

Ignoring macro_rules macros, and ignoring changes to diagnostics, it seems like there’s no observable difference here, right?

pnkfelix (Nov 08 2019 at 19:37, on Zulip):

So the only thing I’ll want to double-check is what the actual effect on macro_rules is

pnkfelix (Nov 08 2019 at 19:38, on Zulip):

But I’m basically 👍 for it

centril (Nov 08 2019 at 19:42, on Zulip):

@pnkfelix two things are interesting in that respect: 1) $item can now accept enum X { pub Y }; for example, this would be valid:

macro_rules! accept_item { ($i:item) => {} }
accept_item!(enum X { pub Y });

2) when $v:vis is substituted for nothing, then enum X { $v Y } is both semantically and syntactically OK because you get VisibilityKind::Inherited (which has no new semantic effects).

centril (Nov 08 2019 at 19:42, on Zulip):

That is, ast_validation would reject anything but VisibilityKind::Inherited

centril (Nov 08 2019 at 19:43, on Zulip):

Alright; the mood seems positive, so I'll go implement it and ping everyone again on the PR

pnkfelix (Nov 08 2019 at 19:46, on Zulip):

So those points both sound like pure increases in expressive power to me. The thing I wanted to double check was if there was any way a macro with multiple arms could change behavior due to this

pnkfelix (Nov 08 2019 at 19:47, on Zulip):

If my memory is correct, our intent was that this should not be the case

pnkfelix (Nov 08 2019 at 19:47, on Zulip):

But I’ve definitely been wrong about the semantics of macros 1.0 in the past

centril (Nov 08 2019 at 20:05, on Zulip):

@pnkfelix are you thinking of follow-set troubles here?

pnkfelix (Nov 08 2019 at 20:35, on Zulip):

That’s an example of where I’ve been wrong, yeah

nikomatsakis (Nov 08 2019 at 21:08, on Zulip):

@centril I am in favor of this sort of change in general

centril (Nov 08 2019 at 21:09, on Zulip):

great :slight_smile:

centril (Nov 09 2019 at 00:02, on Zulip):

@pnkfelix seems there won't be any follow-set problems:

macro_rules! ai {
    ($i:item) => { dbg!(0); };
    (enum A { pub X }) => { dbg!(1); };
}

fn main() {
    ai!(enum A { X } );
    ai!(enum A { pub X } ); //~ ERROR unnecessary visibility qualifier
}

We should be all good.

Last update: Nov 15 2019 at 09:40UTC