mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 20:42:04 +00:00
support nonzero* niche optimizations
This commit is contained in:
parent
86b5b609f1
commit
f2c9502185
3 changed files with 73 additions and 0 deletions
|
@ -4,6 +4,7 @@ use std::{
|
||||||
cmp::{self, Ordering},
|
cmp::{self, Ordering},
|
||||||
iter,
|
iter,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
|
ops::Bound,
|
||||||
};
|
};
|
||||||
|
|
||||||
use chalk_ir::TyKind;
|
use chalk_ir::TyKind;
|
||||||
|
@ -18,6 +19,8 @@ use hir_def::{
|
||||||
};
|
};
|
||||||
use la_arena::{ArenaMap, RawIdx};
|
use la_arena::{ArenaMap, RawIdx};
|
||||||
|
|
||||||
|
struct X(Option<NonZeroUsize>);
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
lang_items::is_unsafe_cell,
|
lang_items::is_unsafe_cell,
|
||||||
|
@ -137,7 +140,38 @@ pub fn layout_of_adt_query(
|
||||||
Abi::Aggregate { sized: _ } => {}
|
Abi::Aggregate { sized: _ } => {}
|
||||||
}
|
}
|
||||||
st.largest_niche = None;
|
st.largest_niche = None;
|
||||||
|
return Ok(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (start, end) = layout_scalar_valid_range(db, def);
|
||||||
|
match st.abi {
|
||||||
|
Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
|
||||||
|
if let Bound::Included(start) = start {
|
||||||
|
let valid_range = scalar.valid_range_mut();
|
||||||
|
valid_range.start = start;
|
||||||
|
}
|
||||||
|
if let Bound::Included(end) = end {
|
||||||
|
let valid_range = scalar.valid_range_mut();
|
||||||
|
valid_range.end = end;
|
||||||
|
}
|
||||||
|
// Update `largest_niche` if we have introduced a larger niche.
|
||||||
|
let niche = Niche::from_scalar(dl, Size::ZERO, *scalar);
|
||||||
|
if let Some(niche) = niche {
|
||||||
|
match st.largest_niche {
|
||||||
|
Some(largest_niche) => {
|
||||||
|
// Replace the existing niche even if they're equal,
|
||||||
|
// because this one is at a lower offset.
|
||||||
|
if largest_niche.available(dl) <= niche.available(dl) {
|
||||||
|
st.largest_niche = Some(niche);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => st.largest_niche = Some(niche),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => user_error!("nonscalar layout for layout_scalar_valid_range"),
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(st);
|
return Ok(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,6 +625,22 @@ pub fn layout_of_adt_query(
|
||||||
Ok(best_layout.layout)
|
Ok(best_layout.layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layout_scalar_valid_range(db: &dyn HirDatabase, def: AdtId) -> (Bound<u128>, Bound<u128>) {
|
||||||
|
let attrs = db.attrs(def.into());
|
||||||
|
let get = |name| {
|
||||||
|
let attr = attrs.by_key(name).tt_values();
|
||||||
|
for tree in attr {
|
||||||
|
if let Some(x) = tree.token_trees.first() {
|
||||||
|
if let Ok(x) = x.to_string().parse() {
|
||||||
|
return Bound::Included(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bound::Unbounded
|
||||||
|
};
|
||||||
|
(get("rustc_layout_scalar_valid_range_start"), get("rustc_layout_scalar_valid_range_end"))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn layout_of_adt_recover(
|
pub fn layout_of_adt_recover(
|
||||||
_: &dyn HirDatabase,
|
_: &dyn HirDatabase,
|
||||||
_: &[String],
|
_: &[String],
|
||||||
|
|
|
@ -146,6 +146,19 @@ fn tuple() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn non_zero() {
|
||||||
|
check_size_and_align(
|
||||||
|
r#"
|
||||||
|
//- minicore: non_zero, option
|
||||||
|
use core::num::NonZeroU8;
|
||||||
|
struct Goal(Option<NonZeroU8>);
|
||||||
|
"#,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn niche_optimization() {
|
fn niche_optimization() {
|
||||||
check_size_and_align(
|
check_size_and_align(
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
//! index: sized
|
//! index: sized
|
||||||
//! iterator: option
|
//! iterator: option
|
||||||
//! iterators: iterator, fn
|
//! iterators: iterator, fn
|
||||||
|
//! non_zero:
|
||||||
//! option:
|
//! option:
|
||||||
//! ord: eq, option
|
//! ord: eq, option
|
||||||
//! pin:
|
//! pin:
|
||||||
|
@ -680,6 +681,15 @@ mod macros {
|
||||||
}
|
}
|
||||||
// endregion:derive
|
// endregion:derive
|
||||||
|
|
||||||
|
// region:non_zero
|
||||||
|
pub mod num {
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[rustc_layout_scalar_valid_range_start(1)]
|
||||||
|
#[rustc_nonnull_optimization_guaranteed]
|
||||||
|
pub struct NonZeroU8(u8);
|
||||||
|
}
|
||||||
|
// endregion:non_zero
|
||||||
|
|
||||||
// region:bool_impl
|
// region:bool_impl
|
||||||
#[lang = "bool"]
|
#[lang = "bool"]
|
||||||
impl bool {
|
impl bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue