forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#110930 - b-naber:normalize-elaborate-drops,…
… r=cjgillot Don't expect normalization to succeed in elaborate_drops Fixes rust-lang#110682 This was exposed through the changes in rust-lang#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](https://github.com/rust-lang/rust/blob/033aa092ab23ba14cdad27073c5e37ba0eddb428/compiler/rustc_mir_dataflow/src/elaborate_drops.rs#L278) to `normalize_erasing_regions`, which ICEs when normalization fails. The types are used to infer [whether the type needs a drop](https://github.com/rust-lang/rust/blob/033aa092ab23ba14cdad27073c5e37ba0eddb428/compiler/rustc_mir_dataflow/src/elaborate_drops.rs#L374), where `needs_drop` itself [uses `try_normalize_erasing_regions`](https://github.com/rust-lang/rust/blob/033aa092ab23ba14cdad27073c5e37ba0eddb428/compiler/rustc_middle/src/ty/util.rs#L1121). ~[`instance_mir`](https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.instance_mir) isn't explicit about whether it expects the instances corresponding to the `InstanceDef`s 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.~
- Loading branch information
Showing
3 changed files
with
119 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// build-pass | ||
// compile-flags: -Zmir-opt-level=3 | ||
|
||
use std::fmt::Debug; | ||
use std::mem::ManuallyDrop; | ||
use std::ptr; | ||
|
||
pub trait BitRegister {} | ||
|
||
macro_rules! register { | ||
($($t:ty),+ $(,)?) => { $( | ||
impl BitRegister for $t { | ||
} | ||
)* }; | ||
} | ||
|
||
register!(u8, u16, u32); | ||
|
||
pub trait BitStore: Sized + Debug { | ||
/// The register type that the implementor describes. | ||
type Mem: BitRegister + Into<Self>; | ||
} | ||
|
||
macro_rules! store { | ||
($($t:ty),+ $(,)?) => { $( | ||
impl BitStore for $t { | ||
type Mem = Self; | ||
} | ||
)+ }; | ||
} | ||
|
||
store!(u8, u16, u32,); | ||
|
||
#[repr(C)] | ||
pub struct BitVec<T> | ||
where | ||
T: BitStore, | ||
{ | ||
/// Region pointer describing the live portion of the owned buffer. | ||
pointer: ptr::NonNull<T>, | ||
/// Allocated capacity, in elements `T`, of the owned buffer. | ||
capacity: usize, | ||
} | ||
|
||
impl<T> BitVec<T> | ||
where | ||
T: BitStore, | ||
{ | ||
pub fn new() -> Self { | ||
let pointer = ptr::NonNull::<T>::new(ptr::null_mut()).unwrap(); | ||
|
||
BitVec { pointer, capacity: 10 } | ||
} | ||
|
||
pub fn clear(&mut self) { | ||
unsafe { | ||
self.set_len(0); | ||
} | ||
} | ||
|
||
#[inline] | ||
pub unsafe fn set_len(&mut self, new_len: usize) {} | ||
|
||
fn with_vec<F, R>(&mut self, func: F) -> R | ||
where | ||
F: FnOnce(&mut ManuallyDrop<Vec<T::Mem>>) -> R, | ||
{ | ||
let cap = self.capacity; | ||
let elts = 10; | ||
let mut vec = ManuallyDrop::new(unsafe { Vec::from_raw_parts(ptr::null_mut(), elts, cap) }); | ||
let out = func(&mut vec); | ||
|
||
out | ||
} | ||
} | ||
|
||
impl<T> Drop for BitVec<T> | ||
where | ||
T: BitStore, | ||
{ | ||
#[inline] | ||
fn drop(&mut self) { | ||
// The buffer elements do not have destructors. | ||
self.clear(); | ||
// Run the `Vec` destructor to deällocate the buffer. | ||
self.with_vec(|vec| unsafe { ManuallyDrop::drop(vec) }); | ||
} | ||
} | ||
|
||
fn main() { | ||
let bitvec = BitVec::<u32>::new(); | ||
} |