Skip to content
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

Don't do intra-pass validation on MIR shims #115005

Merged
merged 1 commit into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/rustc_mir_transform/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
};
debug!("make_shim({:?}) = untransformed {:?}", instance, result);

pm::run_passes(
// We don't validate MIR here because the shims may generate code that's
// only valid in a reveal-all param-env. However, since we do initial
// validation with the MirBuilt phase, which uses a user-facing param-env.
Copy link
Contributor

Choose a reason for hiding this comment

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

What about setting body.phase to Runtime(Initial)?

Copy link
Member Author

Choose a reason for hiding this comment

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

That probably works. I'm not sure if that breaks any other invariants of validation, let me try it.

Copy link
Member Author

Choose a reason for hiding this comment

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

This does not work, because validation fails before the Derefer is run.

Copy link
Member

Choose a reason for hiding this comment

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

I went down this path last week but wasn't very happy with the result as I had to run Derefer and then it seemed wise to run the other passes to actually put us in the same state as we should be when phase = Runtime(Initial) but that required either duplicating the list of passes or splitting up run_runtime_lowering_passes() since running ElaborateDrops again caused other issues. In the end, it felt pretty hacky and I think @compiler-errors's solution here is better.

// This causes validation errors when TAITs are involved.
pm::run_passes_no_validate(
Copy link
Member Author

Choose a reason for hiding this comment

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

We could, perhaps, only do this for drop shims. Other shims are (probably?) alright to do validation on.

But I'm fine with ignoring all shims -- we still do final validation after passes are run since we're transitioning to MirPhase::Runtime(RuntimePhase::Optimized).

tcx,
&mut result,
&[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// crate foo

#![feature(type_alias_impl_trait)]

type Tait = impl Sized;
fn _constrain() -> Tait {}

struct WrapperWithDrop<T>(T);
impl<T> Drop for WrapperWithDrop<T> {
fn drop(&mut self) {}
}

pub struct Foo(WrapperWithDrop<Tait>);

trait Id {
type Id: ?Sized;
}
impl<T: ?Sized> Id for T {
type Id = T;
}
pub struct Bar(WrapperWithDrop<<Tait as Id>::Id>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// aux-build:drop-shim-relates-opaque-aux.rs
// compile-flags: -Zvalidate-mir --crate-type=lib
// build-pass

extern crate drop_shim_relates_opaque_aux;

pub fn drop_foo(_: drop_shim_relates_opaque_aux::Foo) {}
pub fn drop_bar(_: drop_shim_relates_opaque_aux::Bar) {}

fn main() {}