csharplang/meetings/2021/LDM-2021-10-13.md
2021-10-13 15:34:01 -07:00

6.2 KiB

C# Language Design Meeting for October 13th, 2021

Agenda

  1. Revisiting DoesNotReturn
  2. Warning on lowercase type names
  3. Length pattern backcompat

Quote of the Day

  • "You're opinionated against opinionated features" "I see the irony, but..."

Discussion

Revisiting DoesNotReturn

https://github.com/dotnet/csharplang/issues/5231

We wanted to revisit this design decision after a few years and some reports of customer confusion around this attribute. While it's not an overwhelming amount of confusion, it's non-zero. When last this attribute was discussed, we decided that we couldn't use it to broadly enforce the concept of a method that does not return: instead, it could only influence nullable analysis. Much like the rest of the features nullable analysis added, it cannot make strong guarantees. Changing this behavior now wouldn't really solve any of the issues with it, as code exists today that is attributed with DoesNotReturn that cannot be statically-proven to never return.

Instead, we think that https://github.com/dotnet/csharplang/issues/538 would be needed to make progress here: once we have a never type, these guarantees can be statically proven, the runtime can abort if an instance of never is ever created, and we can introduce a warning wave at that point to suggest that methods attributed with DoesNotReturn should have a return type of never. This would prevent us from introducing another loose generalized analysis that can't be statically relied upon before later adding a more strict version that can be relied upon.

Conclusion

No changes.

Warning on lowercase type names

https://github.com/dotnet/roslyn/issues/56653

This is an issue that we've been kicking around for a long time to try and protect language design space, and we've recently started to make more breaks in this space. For example, C# 9 introduced record as a type specifier, and made it illegal to declare a type named record without escaping it. We've heard no complaints about this change, and this has given us more confidence to go ahead with a warning in this area.

And important point is that this change is not motivated by style. C# as a language tries hard not to be opinionated on coding styles; we have defaults for formatting that are part of VS and dotnet new editorconfig, but these are highly customizable and we try not to punish users for taking advantage of that customizability. Instead, this warning is about trying to ensure that C# has design space to work with that doesn't break users who upgrade to new C# versions. This goal means we're trying to help 2 sets of customers:

  1. People who author types with lowercase names. These authors should be informed that they could be causing issues for their users by using a lowercase name.
  2. People who use types with lowercase names. These users should be informed that, if a future version of C# adds the type they're using as a keyword, their code could change meaning or no longer compile.

Some other points of consideration we brought up:

  • Should we do this for just public types?
    • Answer: we are trying to protect users from both themselves and others. This means we want to warn everywhere.
  • Should we have codefixers to prepend @ in front of identifiers?
    • Ultimately this will be up to the IDE team, but we think that each set of customers above should have a different answer here. For set 1, we don't want to encourage this type of naming, even when escaped, so we would not want to see a fixer on type definitions. However, for set 2, they're just using a type someone else defined. We don't want to unreasonably punish them, so a fixer to prepend @ for these users seems appropriate.

Conclusion

The compiler will issue a diagnostic for types named all lowercase letters. We may simplify that to be just types named all ASCII lowercase characters, to avoid worrying about lowercase characters in other encodings and because we don't believe C# will be interested in adding non-ASCII keywords.

Length pattern backcompat

https://github.com/dotnet/csharplang/issues/5226

There are user tradeoffs here. In our previous discussion, we expressed a desire to have a similar ability to nullable, whereby a missing negative Length test would not count against exhaustive matching, but if one was present it would then cause negative values to need to be fully matched against. However, describing these rules and implementing them is quite complex, to the point that we are concerned both about the code complexity and the explanation of the rules to users. We therefore think that the simpler implementation, where we just consider the domain of Count/Length for indexable and countable types to be non-negative integers, to be the better approach.

While we were discussing this, we also brought up the inherent flaw of structural typing, where types that do not satisfy the contract of indexable and countable but still have the correct shape end up having incorrect behavior. For example, the BCL recently approved a Vector2<T> type. That type has an indexer, and it has a property called Length that returns an integer. This Length property is not the length of the Vector: that's always 2. Instead, this is the euclidean length of the vector, ie the distance from (0, 0). Our knowledge of Length and combining subsumption with list patterns will behave incorrectly here. However, we note that this type is already broken with structural typing in C# today. For example, vector[^1] would work on the type, but it wouldn't have the expected behavior. Instead of trying to solve something here, we instead think we should see what other uses customers have for opting out of structural typing, and started a discussion about that here.

Conclusion

We will accept the existing breaking change on subsumption for indexable and countable types, and treat Length/Count on types that are both indexable and countable as if they can only have non-negative values. We would like to get this change in preview sooner rather than later so that we can receive feedback on the change.