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 build drop shim for polymorphic types #110930

Merged
merged 3 commits into from
May 17, 2023

Conversation

b-naber
Copy link
Contributor

@b-naber b-naber commented Apr 28, 2023

Fixes #110682

This was exposed through the changes in #109247, which causes more things to be inlined. Inlining can happen before monomorphization, so we can't expect normalization to succeed. In the elaborate_drops analysis we currently have this call to normalize_erasing_regions, which ICEs when normalization fails. The types are used to infer whether the type needs a drop, where needs_drop itself uses try_normalize_erasing_regions.

instance_mir isn't explicit about whether it expects the instances corresponding to the InstanceDefs to be monomorphized (though I think in all other contexts the function is used post-monomorphization), so the use of instance_mir in inlining doesn't necessarily seem wrong to me.

@rustbot
Copy link
Collaborator

rustbot commented Apr 28, 2023

r? @davidtwco

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 28, 2023
@b-naber
Copy link
Contributor Author

b-naber commented Apr 28, 2023

Actually I think this might not be the proper fix for this. Inlining actually is only done post-monomorphization afaict (its only called through instance_mir (the earliest call of that function should be this one), so we have fully non-generic substs at each call site of instance_mir. We discard those substs for the call though and then only use non substituted param_envs throughout inlining (and all other optimizations too I think), which seems wrong to me. I'm not really that familiar with the code in rustc_mir_transform. Can anybody more familiar with this share some light on whether this might be wrong? cc @oli-obk @JakobDegen

@JakobDegen
Copy link
Contributor

The reported issue is a dupe of #106444 , which has a draft PR up to fix it.

We definitely do try to inline pre-mono Mir, and normally that works fine. The problem is just that drop shim generation specifically is not set up to deal with that at all, which is what causes the problems. I don't know what the right fix is either, you'll probably have to coordinate that with Camille.

@tmiasko
Copy link
Contributor

tmiasko commented Apr 28, 2023

Originally instance_mir was used with monomorphic instances only. That changed since, but inlining is the only exception, so there might be latent issues like the one fixed here. In general, I would expect the instance_mir to be fixed to support non-monomorphic instances. Unless it is impossible to construct the MIR shim at this point, in which case some other approach should be explored.

In this particular case, a field type determines whether to build or omit a drop terminator. When drop terminator is built, but eventually the type doesn't need to be dropped, the drop terminator is a no-op. That seems fine.

It might be worth pointing out, that the de-facto behavior of the drop shim will be different if it is created when not monomorphic. Consider the example below. If shim is generated at the point when A and B are not known to be Copy, then the drop shim will read a discriminant. In contrast, when drop shim is constructed when A and B are known to be Copy, it will do no such thing (demonstration might require increased inlining threshold -Zinline-mir-threshold):

pub enum E<A, B> {
    X(A),
    Y(B),
}
pub unsafe fn f<A, B>(e: *mut E<A, B>) {
    std::ptr::drop_in_place(e);
}

@cjgillot cjgillot self-assigned this Apr 28, 2023
@cjgillot
Copy link
Contributor

#106905 stumbled on this ICE #106905 (comment). This PR may have a similar one.

@b-naber
Copy link
Contributor Author

b-naber commented May 1, 2023

#106905 stumbled on this ICE #106905 (comment). This PR may have a similar one.

I think this change wouldn't be affected by that, as we keep normalizing as we previously do, so this should not introduce any other normalization related ICEs, though it might lead to other problems.

I've tried to familiarize myself more with the inlining and drop elaboration code and I believe the current behaviour of not being able to normalize during inlining introduces some inconsistencies. When we process_blocks during inlining we rely on Instance::resolve to determine callsites. If we're working with generic projections, then we can't resolve those callsites, which will result in the compiler not inlining calls it could (should?) inline. E.g.:

use std::mem::ManuallyDrop;
use std::ops::Drop;

#[inline(always)]
fn called_when_dropped() {
    let _s = "this is inlined";
}

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        called_when_dropped()
    }
}

fn func(arg: Foo) {
    let mut md = unsafe { ManuallyDrop::new(arg) };
    unsafe { ManuallyDrop::drop(&mut md) };
}

fn main() {
    let v = Foo {};
    func(v);
}

results in the following mir after inlining for func:

// MIR for `func` after Inline

fn func(_1: Foo) -> () {
    debug arg => _1;                     // in scope 0 at inline-no-generics-no-vec.rs:17:9: 17:12
    let mut _0: ();                      // return place in scope 0 at inline-no-generics-no-vec.rs:17:19: 17:19
    let mut _2: std::mem::ManuallyDrop<Foo>; // in scope 0 at inline-no-generics-no-vec.rs:18:9: 18:15
    let mut _3: Foo;                     // in scope 0 at inline-no-generics-no-vec.rs:18:45: 18:48
    let _4: ();                          // in scope 0 at inline-no-generics-no-vec.rs:19:14: 19:41
    let mut _5: &mut std::mem::ManuallyDrop<Foo>; // in scope 0 at inline-no-generics-no-vec.rs:19:33: 19:40
    let mut _6: &mut std::mem::ManuallyDrop<Foo>; // in scope 0 at inline-no-generics-no-vec.rs:19:33: 19:40
    scope 1 {
        debug md => _2;                  // in scope 1 at inline-no-generics-no-vec.rs:18:9: 18:15
        scope 3 {
            scope 5 (inlined ManuallyDrop::<Foo>::drop) { // at inline-no-generics-no-vec.rs:19:14: 19:41
                debug slot => _5;        // in scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:140:24: 140:28
                let mut _7: *mut Foo;    // in scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
                let mut _8: &mut Foo;    // in scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
                scope 6 {
                    scope 7 (inlined std::ptr::drop_in_place::<Foo> - shim(Some(Foo))) { // at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:53
                        let mut _9: &mut Foo; // in scope 7 at /home/gh-b-naber/rust/library/core/src/ptr/mod.rs:490:1: 490:56
                        let mut _10: (); // in scope 7 at /home/gh-b-naber/rust/library/core/src/ptr/mod.rs:490:1: 490:56
                    }
                }
            }
        }
    }
    scope 2 {
        scope 4 (inlined ManuallyDrop::<Foo>::new) { // at inline-no-generics-no-vec.rs:18:27: 18:49
            debug value => _3;           // in scope 4 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:70:22: 70:27
        }
    }

    bb0: {
        StorageLive(_2);                 // scope 0 at inline-no-generics-no-vec.rs:18:9: 18:15
        StorageLive(_3);                 // scope 2 at inline-no-generics-no-vec.rs:18:45: 18:48
        _3 = move _1;                    // scope 2 at inline-no-generics-no-vec.rs:18:45: 18:48
        _2 = ManuallyDrop::<Foo> { value: move _3 }; // scope 4 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:71:9: 71:31
        StorageDead(_3);                 // scope 2 at inline-no-generics-no-vec.rs:18:48: 18:49
        StorageLive(_4);                 // scope 1 at inline-no-generics-no-vec.rs:19:5: 19:43
        StorageLive(_5);                 // scope 3 at inline-no-generics-no-vec.rs:19:33: 19:40
        StorageLive(_6);                 // scope 3 at inline-no-generics-no-vec.rs:19:33: 19:40
        _6 = &mut _2;                    // scope 3 at inline-no-generics-no-vec.rs:19:33: 19:40
        _5 = &mut (*_6);                 // scope 3 at inline-no-generics-no-vec.rs:19:33: 19:40
        StorageLive(_7);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        StorageLive(_8);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        _8 = &mut ((*_5).0: Foo);        // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        _7 = &raw mut (*_8);             // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        StorageLive(_9);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:53
        StorageLive(_10);                // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:53
        _9 = &mut (*_7);                 // scope 7 at /home/gh-b-naber/rust/library/core/src/ptr/mod.rs:490:1: 490:56
        _10 = <Foo as Drop>::drop(move _9) -> [return: bb2, unwind: bb1]; // scope 7 at /home/gh-b-naber/rust/library/core/src/ptr/mod.rs:490:1: 490:56
                                         // mir::Constant
                                         // + span: /home/gh-b-naber/rust/library/core/src/ptr/mod.rs:490:1: 490:56
                                         // + literal: Const { ty: for<'a> fn(&'a mut Foo) {<Foo as Drop>::drop}, val: Value(<ZST>) }
    }

    bb1 (cleanup): {
        resume;                          // scope 0 at inline-no-generics-no-vec.rs:17:1: 20:2
    }

    bb2: {
        StorageDead(_10);                // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:53
        StorageDead(_9);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:53
        StorageDead(_7);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:52: 144:53
        StorageDead(_8);                 // scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:145:5: 145:6
        StorageDead(_5);                 // scope 3 at inline-no-generics-no-vec.rs:19:40: 19:41
        StorageDead(_6);                 // scope 1 at inline-no-generics-no-vec.rs:19:43: 19:44
        StorageDead(_4);                 // scope 1 at inline-no-generics-no-vec.rs:19:43: 19:44
        _0 = const ();                   // scope 0 at inline-no-generics-no-vec.rs:17:19: 20:2
        StorageDead(_2);                 // scope 0 at inline-no-generics-no-vec.rs:20:1: 20:2
        return;                          // scope 0 at inline-no-generics-no-vec.rs:20:2: 20:2
    }
}

So here we do inline the call to drop_in_place for Foo.

Whereas for the following example we do not, but we could if we would properly normalize this:

use std::mem::ManuallyDrop;
use std::ops::Drop;

#[inline(always)]
fn must_be_inlined() {
    let _s = "this should be inlined";
}

struct Foo;

struct Bar {
    a: u32,
}

impl Drop for Bar {
    fn drop(&mut self) {
        must_be_inlined()
    }
}

impl A for Foo {
    type MyType = Bar;
}

trait A {
    type MyType;
}

fn func<T: A>(foo: T, arg: <T as A>::MyType) {
    let mut to_drop = unsafe { ManuallyDrop::new(arg) };
    unsafe { ManuallyDrop::drop(&mut to_drop) }
}

fn main() {
    let bar = Bar { a: 1 };
    let foo = Foo {};
    func(foo, bar);
}

which results in the following post-inline mir:

// MIR for `func` after Inline

fn func(_1: T, _2: <T as A>::MyType) -> () {
    debug foo => _1;                     // in scope 0 at manual-drop-associated-type.rs:29:15: 29:18
    debug arg => _2;                     // in scope 0 at manual-drop-associated-type.rs:29:23: 29:26
    let mut _0: ();                      // return place in scope 0 at manual-drop-associated-type.rs:29:46: 29:46
    let mut _3: std::mem::ManuallyDrop<<T as A>::MyType>; // in scope 0 at manual-drop-associated-type.rs:30:9: 30:20
    let mut _4: <T as A>::MyType;        // in scope 0 at manual-drop-associated-type.rs:30:50: 30:53
    let mut _5: &mut std::mem::ManuallyDrop<<T as A>::MyType>; // in scope 0 at manual-drop-associated-type.rs:31:33: 31:45
    let mut _6: &mut std::mem::ManuallyDrop<<T as A>::MyType>; // in scope 0 at manual-drop-associated-type.rs:31:33: 31:45
    scope 1 {
        debug to_drop => _3;             // in scope 1 at manual-drop-associated-type.rs:30:9: 30:20
        scope 3 {
            scope 5 (inlined ManuallyDrop::<<T as A>::MyType>::drop) { // at manual-drop-associated-type.rs:31:14: 31:46
                debug slot => _5;        // in scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:140:24: 140:28
                let mut _7: *mut <T as A>::MyType; // in scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
                let mut _8: &mut <T as A>::MyType; // in scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
                scope 6 {
                }
            }
        }
    }
    scope 2 {
        scope 4 (inlined ManuallyDrop::<<T as A>::MyType>::new) { // at manual-drop-associated-type.rs:30:32: 30:54
            debug value => _4;           // in scope 4 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:70:22: 70:27
        }
    }

    bb0: {
        StorageLive(_3);                 // scope 0 at manual-drop-associated-type.rs:30:9: 30:20
        StorageLive(_4);                 // scope 2 at manual-drop-associated-type.rs:30:50: 30:53
        _4 = move _2;                    // scope 2 at manual-drop-associated-type.rs:30:50: 30:53
        _3 = ManuallyDrop::<<T as A>::MyType> { value: move _4 }; // scope 4 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:71:9: 71:31
        StorageDead(_4);                 // scope 2 at manual-drop-associated-type.rs:30:53: 30:54
        StorageLive(_5);                 // scope 3 at manual-drop-associated-type.rs:31:33: 31:45
        StorageLive(_6);                 // scope 3 at manual-drop-associated-type.rs:31:33: 31:45
        _6 = &mut _3;                    // scope 3 at manual-drop-associated-type.rs:31:33: 31:45
        _5 = &mut (*_6);                 // scope 3 at manual-drop-associated-type.rs:31:33: 31:45
        StorageLive(_7);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        StorageLive(_8);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        _8 = &mut ((*_5).0: <T as A>::MyType); // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        _7 = &raw mut (*_8);             // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:37: 144:52
        _0 = std::ptr::drop_in_place::<<T as A>::MyType>(move _7) -> [return: bb4, unwind: bb2]; // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:53
                                         // mir::Constant
                                         // + span: /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:36
                                         // + literal: Const { ty: unsafe fn(*mut <T as A>::MyType) {std::ptr::drop_in_place::<<T as A>::MyType>}, val: Value(<ZST>) }
    }

    bb1: {
        return;                          // scope 0 at manual-drop-associated-type.rs:32:2: 32:2
    }

    bb2 (cleanup): {
        drop(_1) -> [return: bb3, unwind terminate]; // scope 0 at manual-drop-associated-type.rs:32:1: 32:2
    }

    bb3 (cleanup): {
        resume;                          // scope 0 at manual-drop-associated-type.rs:29:1: 32:2
    }

    bb4: {
        StorageDead(_7);                 // scope 6 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:52: 144:53
        StorageDead(_8);                 // scope 5 at /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:145:5: 145:6
        StorageDead(_5);                 // scope 3 at manual-drop-associated-type.rs:31:45: 31:46
        StorageDead(_3);                 // scope 0 at manual-drop-associated-type.rs:32:1: 32:2
        StorageDead(_6);                 // scope 0 at manual-drop-associated-type.rs:32:1: 32:2
        drop(_1) -> [return: bb1, unwind: bb3]; // scope 0 at manual-drop-associated-type.rs:32:1: 32:2
    }
}

This is because after having inlined ManuallyDrop::<<T as A>::MyType>::drop to:

│ │ │ │ │ │ │ │ │ │ │ │             BasicBlockData {
│ │ │ │ │ │ │ │ │ │ │ │                 statements: [
│ │ │ │ │ │ │ │ │ │ │ │                     StorageLive(_7),
│ │ │ │ │ │ │ │ │ │ │ │                     StorageLive(_8),
│ │ │ │ │ │ │ │ │ │ │ │                     _8 = &mut ((*_5).0: <T as A>::MyType),
│ │ │ │ │ │ │ │ │ │ │ │                     _7 = &raw mut (*_8),
│ │ │ │ │ │ │ │ │ │ │ │                 ],
│ │ │ │ │ │ │ │ │ │ │ │                 terminator: Some(
│ │ │ │ │ │ │ │ │ │ │ │                     Terminator {
│ │ │ │ │ │ │ │ │ │ │ │                         source_info: SourceInfo {
│ │ │ │ │ │ │ │ │ │ │ │                             span: /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:144:18: 144:53 (#30),
│ │ │ │ │ │ │ │ │ │ │ │                             scope: scope[6],
│ │ │ │ │ │ │ │ │ │ │ │                         },
│ │ │ │ │ │ │ │ │ │ │ │                         kind: _0 = std::ptr::drop_in_place::<<T as A>::MyType>(move _7) -> [return: bb8, unwind: bb4],
│ │ │ │ │ │ │ │ │ │ │ │                     },
│ │ │ │ │ │ │ │ │ │ │ │                 ),
│ │ │ │ │ │ │ │ │ │ │ │                 is_cleanup: false,
│ │ │ │ │ │ │ │ │ │ │ │             },
│ │ │ │ │ │ │ │ │ │ │ │             BasicBlockData {
│ │ │ │ │ │ │ │ │ │ │ │                 statements: [
│ │ │ │ │ │ │ │ │ │ │ │                     StorageDead(_7),
│ │ │ │ │ │ │ │ │ │ │ │                     StorageDead(_8),
│ │ │ │ │ │ │ │ │ │ │ │                 ],
│ │ │ │ │ │ │ │ │ │ │ │                 terminator: Some(
│ │ │ │ │ │ │ │ │ │ │ │                     Terminator {
│ │ │ │ │ │ │ │ │ │ │ │                         source_info: SourceInfo {
│ │ │ │ │ │ │ │ │ │ │ │                             span: /home/gh-b-naber/rust/library/core/src/mem/manually_drop.rs:145:6: 145:6 (#0),
│ │ │ │ │ │ │ │ │ │ │ │                             scope: scope[0],
│ │ │ │ │ │ │ │ │ │ │ │                         },
│ │ │ │ │ │ │ │ │ │ │ │                         kind: goto -> bb2,
│ │ │ │ │ │ │ │ │ │ │ │                     },
│ │ │ │ │ │ │ │ │ │ │ │                 ),
│ │ │ │ │ │ │ │ │ │ │ │                 is_cleanup: false,
│ │ │ │ │ │ │ │ │ │ │ │             },

we cannot resolve the callsite for DefId(2:2136 ~ core[f82a]::ptr::drop_in_place), param_env=ParamEnv { caller_bounds: [Binder(TraitPredicate(<T as A>, polarity:Positive), []), Binder(TraitPredicate(<T as std::marker::Sized>, polarity:Positive), [])], reveal: All, constness: NotConst }, substs=[<T as A>::MyType], so we never create the drop shim here for the callee_body and stop inlining here.

Is this inconsistent?

When do we actually start to inline at the earliest? AFAICT the earliest call that would result in inlining is this one in collect_neighbors. So we should always have concrete substs available when calling instance_mir. Is that correct?

If it is, then I think the proper fix is to have a version of instance_mir that takes substs and then enforces normalization to succeed everywhere.

@cjgillot
Copy link
Contributor

cjgillot commented May 1, 2023

I think this change wouldn't be affected by that, as we keep normalizing as we previously do, so this should not introduce any other normalization related ICEs, though it might lead to other problems.

Falling back to the unnormalized type may cause the other ICE: if for some reason, we cannot normalize and drop elaboration expects and ADT, boom.

...
Is this inconsistent?

I don't think this is inconsistent. The whole point of working on MIR that we optimize MIR in its polymorphic form. The <T as A>::MyType in your example stays because we want inlining to be accurate for any generic type T, and we have no way of knowing that it will just be used for Foo.

If polymorphism prevents some inlining, then we leave to LLVM to perform the monomorphic inlining.

However, specifically for drop shims, if trying to manufacture polymorphic drop shims is an issue, we may need to check that the instance is monomorphic enough and skip trying to inline it if it isn't.

Comment on lines 278 to 279
let field_ty = match tcx
.try_normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs))
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit

Suggested change
let field_ty = match tcx
.try_normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs))
let field_ty = match tcx
.try_normalize_erasing_regions(self.elaborator.param_env(), fty)

@davidtwco davidtwco removed their assignment May 2, 2023
@rustbot
Copy link
Collaborator

rustbot commented May 4, 2023

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

) -> Result<&'tcx Body<'tcx>, &'static str> {
match instance {
ty::InstanceDef::DropGlue(_, Some(ty)) => match ty.kind() {
ty::Adt(def, substs) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure if we want to do this in a more generalized way. I believe the normalization in move_paths_for_fields is the only place where building drop shims can go wrong, so rejecting those types here should be sufficient (though this change feels a little hacky).

Rejecting these here seemed preferable to me compared to making changes in the shim/drop elaboration code.

@rust-log-analyzer

This comment has been minimized.

@rust-cloud-vms rust-cloud-vms bot force-pushed the normalize-elaborate-drops branch from 0ff8a6f to a20ce57 Compare May 4, 2023 22:27
@cjgillot
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented May 16, 2023

📌 Commit e7a2f52 has been approved by cjgillot

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 16, 2023
bors added a commit to rust-lang-ci/rust that referenced this pull request May 17, 2023
Rollup of 6 pull requests

Successful merges:

 - rust-lang#110930 (Don't expect normalization to succeed in elaborate_drops)
 - rust-lang#111557 (Revert "Validate resolution for SelfCtor too.")
 - rust-lang#111565 (rustdoc-json: Add tests for visibility of impls)
 - rust-lang#111588 (Emits E0599 when meeting `MyTrait::missing_method`)
 - rust-lang#111625 (Move rustc_middle/src/ty/query.rs to rustc_middle/src/query/plumbing.rs)
 - rust-lang#111674 (Add missing backslash in HTML string)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 828caa8 into rust-lang:master May 17, 2023
11 checks passed
@bors
Copy link
Contributor

bors commented May 17, 2023

⌛ Testing commit e7a2f52 with merge ad23942...

@rustbot rustbot added this to the 1.71.0 milestone May 17, 2023
@b-naber b-naber changed the title Don't expect normalization to succeed in elaborate_drops Don't build drop shim for polymorphic types Jun 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ICE: Failed to normalize, maybe try to call try_normalize_erasing_regions instead
8 participants