-
-
Notifications
You must be signed in to change notification settings - Fork 51
virtualize the trait Reid was stuck on #648
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
virtualize the trait Reid was stuck on #648
Conversation
py/tools/py/src/venv.rs
Outdated
) -> miette::Result<Vec<Command>>; | ||
} | ||
|
||
pub trait PthEntryHandlerExt: PthEntryHandler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be stripped. I wrote it when I first made the real trait virtualizable, so that call sites would continue to compile. The gist is that the blanket impl on 510 makes the .path<_, _>()
method continue to exist on everything that had it, and because that method has a different typesig and fully qualified name (<T as PthEntryHandlerExt>::plan<_, _>(...)
vs <T as PthEntryHandler>::path(...)
, it's not actually an ambiguous symbol to call. But now that all the callers are using the monomorph form rather than the generic, it doesn't do anything.
fn venv_cmd_handler(args: VenvArgs) -> miette::Result<()> { | ||
let pth_file = py::PthFile::new(&args.pth_file, args.pth_entry_prefix); | ||
match args.mode { | ||
if let VenvMode::DynamicSymlink = args.mode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By switching from a match with one arm acting and the other arm doing-work-then-matching-again to if let
with a return
, I took out one level of indentation with no other code changes. The second match still needs the unreachable!
in it because rustc doesn't have the ability to statically strip enum variants in cases like these. Annoying but c'est la vie. Beats writing Haskal
let venv = py::venv::create_empty_venv( | ||
args.repo | ||
.as_deref() | ||
.expect("The --repo argument is required for static venvs!"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
quit calling Option::expect()
in -> Result
functions. that is what .ok_or()?
and .ok_or_else()?
are for.
py/tools/venv_bin/src/main.rs
Outdated
args.include_user_site_packages, | ||
)?; | ||
|
||
let strat: Box<dyn PthEntryHandler> = match args.mode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you have to annotate the virtual type here, because if you don't, the match will type-hint off the first real type it returns. The first arm types as !
, which isn't real. The second arm is Box<py::venv::PthStrategy>
, which means all other arms need to type as that concrete instance. !
types that way, but Box<py::venv::FirstPartyThirdPartyStrategy>
does not.
You can dodge this by typing the binding site (let strat: ...
) or by as-casting the box. Box::new(...) as Box<dyn ...>
is more annoying, imo
py/tools/venv_bin/src/main.rs
Outdated
venv, | ||
pth_file, | ||
args.bin_dir.unwrap(), | ||
&*strat, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
goofy but it works. Unfortunately, &dyn Trait
does not actually count as an implementor of Trait
unless you explicitly write an impl block for it. You Typically Do Not Want To Do This. There are exceptions in libstd but it's really not common.
|
Code review per request