Skip to content

Introduce optimistic default - #1386

Draft
aosen-xiong wants to merge 15 commits into
eisop:masterfrom
aosen-xiong:optimistic-default
Draft

Introduce optimistic default#1386
aosen-xiong wants to merge 15 commits into
eisop:masterfrom
aosen-xiong:optimistic-default

Conversation

@aosen-xiong

@aosen-xiong aosen-xiong commented Sep 4, 2025

Copy link
Copy Markdown
Collaborator

Fixes #1359.

I disable the JSpecify reference checker CI because the method name are changing. I will enable and make the change at there (if necessary) and enable the CI.

Merge #1304 first.

@wmdietl wmdietl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@aosen-xiong @thisisalexandercook We had discussed this PR in the past. Let's go through this and related PRs next week and decide which direction to go.

* @param annotationScope the element that the conservative default might apply to
* @return whether the conservative default applies to the given element
*/
public boolean applyOptimisticDefaults(Element annotationScope) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Most of this code is just copy-and-paste of applyConservativeDefaults. Can you find a way to share more of the common logic?

if (applyConservativeDefaults(annotationScope)) {
for (Default def : uncheckedCodeDefaults) {
for (Default def : conservativeUncheckedCodeDefaults) {
if (!typeVarUseDef || def.location != TypeUseLocation.TYPE_VARIABLE_USE) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This also duplicates the logic in the else branch.
Can you first set which defaults to use and then iterate over that set once?

}
}

for (TypeUseLocation loc : CONSERVATIVE_UNCHECKED_DEFAULTS_TOP) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why iterate over all these sets? Won't most of these conflict with defaults that were already set above?
I think this logic needs some cleaning up.

*/
protected void addUncheckedStandardDefaults(QualifierDefaults defs) {
defs.addUncheckedStandardDefaults();
protected void addUncheckedDefaults(QualifierDefaults defs) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why rename this method? It will still set the standard defaults. What changed?

* @param kindOfCode source or bytecode
* @return whether optimistic defaults should be used
*/
public boolean useOptimisticDefault(String kindOfCode) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Lots of duplicated code.

"checkEnclosingExpr",

// Whether to use optimistic defaults for bytecode and/or source code.
// The option takes same arguments as "useConservativeDefaultsForUncheckedCode".

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The ordering of the options should be switched, instead of having a forward reference here.

Comment thread docs/CHANGELOG.md Outdated

The new command-line option `-AuseOptimisticDefaultsForUncheckedCode` takes `source` and `bytecode` argument, similar to
`-AuseConservativeDefaultsForUnCheckedCode` but apply to optimistic default, that is, Top for method parameter type and
Bottom for method return and field type.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We also need to go through the manual and discuss this new option there.

@wmdietl wmdietl assigned aosen-xiong and unassigned wmdietl Mar 22, 2026
@aosen-xiong aosen-xiong removed their assignment May 25, 2026
@aosen-xiong
aosen-xiong marked this pull request as draft August 1, 2026 08:30
aosen-xiong and others added 2 commits August 29, 2026 22:45
The branch was 310 commits behind, and master reworked the code it changes.
Carry the optimistic defaults forward onto master's design:

- eisop#1331 removed QualifierDefaults.isElementAnnotatedForThisChecker.  The new
  applyOptimisticDefaults calls
  BaseTypeChecker.isElementAnnotatedForThisCheckerOrUpstreamChecker instead,
  as applyConservativeDefaults now does, and shares its cache.
- applyDefaultsElement now applies a memoized, precedence-ordered default list
  from fusedDefaultsFor rather than looping per call.  Its boolean parameter
  becomes a three-valued DefaultsMode, with a third empty-scope slot and a
  third identity cache; invalidateFusedDefaults clears all six.
- applyOptimisticDefaults mirrors applyConservativeDefaults, including the
  fast path on the two flags and the isParsingAnnotationFile guard.  Without
  the guard it reaches the checker before the visitor is installed and throws
  a NullPointerException; without the fast path it costs a stub-file and
  bytecode test on every defaulted type.
- master's bytecode test is atypeFactory.isFromByteCode, not the three-part
  isElementFromByteCode/declarationFromElement/isFromStubFile check.

Keep the existing method names.  Renaming addUncheckedCodeDefault and
addUncheckedStandardDefaults would break downstream checkers, and was why this
branch disabled the JSpecify reference checker in CI; the optimistic variants
are added beside them instead, and that CI script is restored.

Fix the bytecode branch of applyOptimisticDefaults, which tested the source
flag.

Regenerate the four expected outputs in checker/jtreg/nullness/onlyannotatedfor:
the added @compile directive shifts every line number by one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…icting flags

Optimistic defaults put bottom qualifiers where the conservative ones put top.
A qualifier can restrict where it may be written with @TargetLocations --
@KeyForBottom and @FBCBottom are not permitted on a RETURN or FIELD -- and
defaulting one there made BaseTypeValidator report
type.invalid.annotations.on.location on code the user never wrote.  Five of the
nine expected errors in AnnotatedForWithUseOptimisticDefault.out were that
noise.  Skip a qualifier/location pair the qualifier prohibits; the hierarchy's
other defaults still apply there.  The expected output drops to three errors,
which match what the test's own comments say case 4 should produce.

Defaulting a kind of code both optimistically and conservatively is always a
mistake, and previously the conservative defaults silently won.  Reject it in
SourceChecker.initChecker, where the other option validation lives.  An assert
would not do: assertions are disabled in a normal javac run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

Introduce optimistic default

2 participants