I often see questions along the lines of “Why do I need to explicitly write foo here, when it’s obvious the code won’t work without fooing this?” to which the usual explanation is something like “It’s important that foo appear in the function signature/type declaration because it’s part of that type’s/function’s public API”. But for types/functions that are not in any way public, this doesn’t apply.
So I wanted to ask if it seems reasonable to consider proposals to allow downgrading the lack of certain annotations on non-public items from a hard error to a mere warning. The motivation is that, although these annotations should remain mandatory in public APIs, they tend to interfere with prototyping, experimenting and refactoring. Also, while newcomers will eventually have to learn what all of these annotations do and why they exist, turning them into mere “speed bumps” in the form of warnings often seems preferable to a hard error that forces them to go learn about a certain feature/annotation before allowing them to get any further work done.
Some concrete examples to clarify what I’m talking about:
-
#[derive(Debug)]
and#[derive(Display)]
. If all I want to do is a one-offprintln!("{:?}", x);
for debugging purposes, it seems reasonable to auto-derive Debug/Display and emit a warning, as long as x is not in any way public, especially since these are “viral annotations” that may require being temporarily added to several types just to make that println! statement compile. -
Lifetime parameters in structs. If I want to experiment with changing
struct Foo{ x: T }
tostruct Foo{ x: &T }
, I have to temporarily add an<'a>
to a lot of the code that mentions this type. This is also “viral”, and also a bad idea if Foo is public. -
Unused type/lifetime parameters. I didn’t even realize until very recently that there was a good reason we force users to wrap unused parameters in PhantomData, i.e. allowing the compiler to figure out the correct variance for you. But we could also default to invariance and print a warning saying that you should use PhantomData and it might allow more code to compile if you do.
-
Orphan rule exemptions. Not really an “annotation”, and I feel like I’m missing some really obvious reason why this can’t possibly work, but it seems like I should be able to do things like
impl Serialize for Vec<Arc<MyStruct>>
as long asMyStruct
is not in any way public. Of course, it should still generate a warning so that I know I’m effectively makingMyStruct
perma-private by doing this.
I’m not necessarily proposing we implement any of these examples. I’m mostly interested in how everyone feels about the general principle of downgrading certain errors into warnings for types/functions that are not in any way public, since I see a lot of potential for improving ergonomics this way, assuming it’s not wildly unsafe to relax these rules.
When I say “not in any way public”, I’m trying to handwave away whatever problems would be caused by private-in-public rules. Unfortunately I don’t understand those rules very well.