Skip to content

[REPLCompletions] fix #51548, set up a mode to limit the scope of the aggressive inference #51581

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

Merged
merged 5 commits into from
Oct 6, 2023

Conversation

aviatesk
Copy link
Member

@aviatesk aviatesk commented Oct 4, 2023

It appears that #51503 was too aggressive, because it fails to account for inconsistencies that arise from mutable values, leading to potential inaccuracies in results (refer to #51548 for examples).

In addressing this issue, I've came up with the following options:

  1. Introduce a new lattice element, perhaps termed ConstUntilModified. This would represent mutable values until they're modified, at which point they could be widened to their native type and discard constant information. While it may be an option, it feels like and overkill for this particular issue although ConstUntilModified may not be generally useful as mutable values shouldn't be considered as Const-like in other inference contexts in general.
  2. Simply reverts the changes in [REPLCompletions] enable aggressive inference for uncached child frames #51503. This doesn't completely resolve the problem since REPLInterpreter might still overlook inconsistencies with mutable values at the top-level frame. However, given that repl_eval_ex is mostly used for simple expressions, this hasn't posed significant issues.

I would like to go with the second option and so this commit reverts the changes from #51503 and adds new test cases also.

Fixes #51548.

@vtjnash
Copy link
Member

vtjnash commented Oct 4, 2023

It appears that #51503 was too aggressive, because it fails to account for inconsistencies that arise from mutable values,

Isn't that the goal? I thought the whole point of doing this over mutable values is that we can derive results that are only correct in a loose sense, but will tend to give some concrete answer (which is more useful for tab-completing than getting something abstract and not being able to do anything with it)

@brenhinkeller brenhinkeller added the REPL Julia's REPL (Read Eval Print Loop) label Oct 5, 2023
@aviatesk
Copy link
Member Author

aviatesk commented Oct 5, 2023

Isn't that the goal?

Right. I initially believed that this aggressive inference wouldn't lead to incorrect completions in most scenarios, so I expanded its scope beyond top-level frames that represent input code (as mentioned in #51503). But as reported by #51548 it seems to (often) lead to wrong inference result, which may potentially cause wrong completions in cases like:

julia> function trick_repl_interp(T, a)
           xs = T[]
           if a isa T
               push!(xs, a)
           end
           if isempty(xs)
               return a
           else
               return xs
           end
       end;

julia> trick_repl_interp(Any, r"").

compile_options
match_options
pattern
regex

julia> trick_repl_interp(Any, r"").regex
ERROR: type Array has no field regex
Stacktrace:
 [1] getproperty(x::Vector{Any}, f::Symbol)
   @ Base ./Base.jl:37
 [2] top-level scope
   @ REPL[3]:1

Having said that, I'm honestly unsure if we should fix the current situation, because this aggressive inference does enable completions in more contexts (like the example in #51499). It's a trade-off of the benefit of increased completion capabilities at the risk of occasional incorrect results.

Do you want to keep the current state? Then I'm totally fine with closing this PR.

@vtjnash
Copy link
Member

vtjnash commented Oct 5, 2023

I think we should keep the current state. It takes a bit of effort to trick, but usually gets a better answer this way

@simeonschaub
Copy link
Member

I encountered these issues because I want to use REPLInterpreter in #51543 to complete (partially) interpolated paths in shell mode (and eventually string literals as well). There inference results with bogus values are more of an issue.

I agree that losing all this functionality would be quite unfortunate though. Perhaps it's possible to tell repl_eval_ex to care more about correctness just for certain applications?

@aviatesk
Copy link
Member Author

aviatesk commented Oct 6, 2023

How about introducing an optional argument for repl_eval_ex, such as limit_aggressive_inference::Bool=false? When set to true, it would confine the aggressive inference strictly to top-level frames. This way, when evaluating interpolated paths, we can leverage this mode to obtain paths that are most likely to be correct.

@aviatesk
Copy link
Member Author

aviatesk commented Oct 6, 2023

Ok, so I've added an optional argument limit_aggressive_inference::Bool=false to repl_eval_ex. This will allow future REPL completion code to utilize it when prioritizing correct inference results over a wider range of completion opportunities. Note that that mode is disabled by default, so our current completion capabilities are preserved.

@aviatesk aviatesk changed the title [REPLCompletions] fix #51548, disable aggressive inference in non-toplevel uncached frames [REPLCompletions] fix #51548, set up a mode to limit the scope of the aggressive inference Oct 6, 2023
Copy link
Member

@simeonschaub simeonschaub left a comment

Choose a reason for hiding this comment

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

LGTM!

@aviatesk aviatesk merged commit 5488b81 into master Oct 6, 2023
@aviatesk aviatesk deleted the avi/51548 branch October 6, 2023 14:29
simeonschaub added a commit that referenced this pull request Oct 13, 2023
simeonschaub added a commit that referenced this pull request Oct 13, 2023
simeonschaub added a commit that referenced this pull request Oct 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
REPL Julia's REPL (Read Eval Print Loop)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

REPLInterpreter can return wrong result due to mutable inconsistency
4 participants