-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Analyzer: strict_raw_types difficult to comply with atomically #36445
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
Comments
Sounds good to me as long as there is a single flag we can enable in the future |
The first three aren't raw type issues, they're implicit dynamic issues, right? I'm fine with splitting things up, but I do wonder whether, if this is turning out to be such a bitter pill, we should reconsider and perhaps do something at least incrementally more sophisticated? |
Yeah I was wondering that as well, Leaf. @jmesserly committed a lot of tests with the mode, so you can see some examples: var rawConstructorCall = /*info:STRICT_RAW_TYPE*/C();
var rawList = /*info:STRICT_RAW_TYPE*/[];
var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/[42 as dynamic];
var rawSetOfSets = </*info:STRICT_RAW_TYPE*/Set>{};
var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/{42 as dynamic};
var rawMap = /*info:STRICT_RAW_TYPE*/{};
dynamic d;
var upwardsInfersDynamic1 = /*info:STRICT_RAW_TYPE*/{d: 2}; Not sure why I didn't comment on this during code review; I think all the "strict" modes have just been swimming around in my head. I agree these should be |
Oh, and my plan, @leafpetersen, is to bring up strict codes one by one for review by a few user teams. I personally enjoy complying with, e.g., strict-raw-types, but for very complex type hierarchies, I'd like team input. And I think |
Yeah, everything except STRICT_RAW_TYPE_NAME in @srawlins' list above could be argued to fall under It may still be worth separate error codes within strict-inference, so constructors/literals are separate from generic functions/methods? I've noticed that users seem to conceptualize constructor/literal inference as distinct from generic method inference (even though they're essentially the same inference algorithm). So we may wish to reflect that in the error UX.
This has been my worry. Conceptually there is nothing wrong with If we find those are still too hard to roll out, we could focus more narrowly. Implicit Overall, checking for implicit downcasts and unintended dynamic dispatch should also cover all of the potential runtime problems related to dynamic. (Of course, "unintended dynamic dispatch" is very tricky to define.) |
I have confidence that we can land the (now) strict inference literals internally; not a hard sell. And I think a further split of STRICT_RAW_TYPE_NAME, as @jmesserly suggests, would help to pinpoint any spots where it might be less beneficial; but I think there could be a dozen :P e.g
Personally, I'm up for this; I can ask the "strict" teams about each individual check for their opinion or experience; I can mail out targeted changes which eliminate violations of each individual code. Regarding dynamic invocation; this would be a pretty sweet check, but I think orthogonal; strict-raw-types and strict-inference are primarily designed to catch unintentional casts. |
This seems right to me. For the examples above, I would think of them as follows: var rawConstructorCall = /*info:STRICT_RAW_TYPE*/C(); // raw type
var rawList = /*info:STRICT_RAW_TYPE*/[]; // strict inference
var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/[42 as dynamic]; // probably no implicit dynamic
var rawSetOfSets = </*info:STRICT_RAW_TYPE*/Set>{}; // raw type
var upwardsInfersDynamic = /*info:STRICT_RAW_TYPE*/{42 as dynamic}; // no implicit dynamic
var rawMap = /*info:STRICT_RAW_TYPE*/{}; // strict inference
dynamic d;
var upwardsInfersDynamic1 = /*info:STRICT_RAW_TYPE*/{d: 2}; // no implicit dynamic Splitting out the additional raw types could be useful, not sure. |
@leafpetersen -- just for curiosity's sake, what's the mental model for treating list/set/map literals as distinct from constructor invocations? We don't have rest parameters, but if we did, these two seem equivalent: class C<T> {
C(List<T> ...args); // made up syntax for rest parameters.
}
f() {
// with some variables: x, y, and z in scope
var list = [x, y, z];
var c = C(x, y, z);
} It seems like they're all conceptually constructor invocations, and use the same inference algorithm. But maybe that's my bias towards semantics :). Syntactically "C" is an identifier referring to a class (similar to "List"), whereas "[]" does not refer to a class directly (i.e. it implies the List class, but does not name it explicitly). |
Thinking about this more... in |
Oops, yes, 100% agree, @jmesserly ; I would mark those as strict-inference; I'll make this change. |
I'm not sure I am treating them differently, but maybe I am. My thinking is this: class C<T> {
C([T x]);
C.named();
}
void test() {
new C();
new C.named();
} I think I would definitely argue that the first constructor call is definitely a strict inference failure: inference has to guess. It is also arguably a strict raw type failure, since the way that inference guess is by treating it as a raw type. The second constructor call feels a little different to me, but probably isn't. Inference still has to guess, but in this case it always has to guess (unless there's a downward context). So probably should still be a strict inference failure? And also could arguably a strict raw type failure.
I think they should definitely fall under strict inference. If we allow people to specify strict raw types independently of strict inference, we could flag them there as well, but I think this is probably not worthwhile. I'd say make strict raw types strictly about types. |
Bug: #36445 #33749 Change-Id: I127d671840bfcfe3857225932164fa4098963715 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99085 Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
…_CREATION Bug: #33749 #36445 Change-Id: Ic34f0e07b1cc5cbbc265ab2c32cabc61d7901c0f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99264 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
Bug: #36445 Change-Id: Ic716d89b1a6d00945a74c7484f8301403b8ea371 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101420 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
Basically I'd like to split up the STRICT_RAW_TYPE code into a few more, to make it an easier pill to swallow. Teams can either make their code compliant incrementally, or opt out of individual checks they feel they are too onerous. Something like:
STRICT_RAW_TYPE_LIST_LITERAL
forvar foo = [];
STRICT_RAW_TYPE_MAP_LITERAL
forvar foo = {};
STRICT_RAW_TYPE_SET_LITERAL
STRICT_RAW_TYPE_NAME
forfoo is List
,foo as List
,List foo
,Future main()
,main(List args)
, perhapsSTRICT_RAW_TYPE_CONSTRUCTOR
forFuture.value()
,Set()
The text was updated successfully, but these errors were encountered: