Unnamed repository; edit this file 'description' to name the repository.
Backport new sized-hierarchy trait bounds in old ways
Shoyu Vanilla 10 months ago
parent d3e6dcd · commit 953e9d1
-rw-r--r--crates/hir-def/src/lang_item.rs2
-rw-r--r--crates/hir-ty/src/lower.rs53
-rw-r--r--crates/ide/src/inlay_hints/bounds.rs2
-rw-r--r--crates/intern/src/symbol/symbols.rs2
-rw-r--r--crates/test-utils/src/minicore.rs43
5 files changed, 78 insertions, 24 deletions
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index fff62b11c6..750308026e 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -308,6 +308,8 @@ impl LangItem {
language_item_table! {
// Variant name, Name, Getter method name, Target Generic requirements;
Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
+ MetaSized, sym::meta_sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
+ PointeeSized, sym::pointee_sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
/// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 3c73330224..eda6804257 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -581,11 +581,28 @@ impl<'a> TyLoweringContext<'a> {
match bound {
&TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
// FIXME Don't silently drop the hrtb lifetimes here
- if let Some((trait_ref, ctx)) = self.lower_trait_ref_from_path(path, self_ty) {
- if !ignore_bindings {
- assoc_bounds = ctx.assoc_type_bindings_from_type_bound(trait_ref.clone());
+ if let Some((trait_ref, mut ctx)) =
+ self.lower_trait_ref_from_path(path, self_ty.clone())
+ {
+ // FIXME(sized-hierarchy): Remove this bound modifications once we have implemented
+ // sized-hierarchy correctly.
+ let meta_sized = LangItem::MetaSized
+ .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
+ let pointee_sized = LangItem::PointeeSized
+ .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
+ if meta_sized.is_some_and(|it| it == trait_ref.hir_trait_id()) {
+ // Ignore this bound
+ } else if pointee_sized.is_some_and(|it| it == trait_ref.hir_trait_id()) {
+ // Regard this as `?Sized` bound
+ ctx.ty_ctx().unsized_types.insert(self_ty);
+ } else {
+ if !ignore_bindings {
+ assoc_bounds =
+ ctx.assoc_type_bindings_from_type_bound(trait_ref.clone());
+ }
+ clause =
+ Some(crate::wrap_empty_binders(WhereClause::Implemented(trait_ref)));
}
- clause = Some(crate::wrap_empty_binders(WhereClause::Implemented(trait_ref)));
}
}
&TypeBound::Path(path, TraitBoundModifier::Maybe) => {
@@ -945,8 +962,32 @@ pub(crate) fn generic_predicates_for_param_query(
| WherePredicate::TypeBound { target, bound, .. } => {
let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
if invalid_target {
- // If this is filtered out without lowering, `?Sized` is not gathered into `ctx.unsized_types`
- if let TypeBound::Path(_, TraitBoundModifier::Maybe) = bound {
+ // FIXME(sized-hierarchy): Revisit and adjust this properly once we have implemented
+ // sized-hierarchy correctly.
+ // If this is filtered out without lowering, `?Sized` or `PointeeSized` is not gathered into
+ // `ctx.unsized_types`
+ let lower = || -> bool {
+ match bound {
+ TypeBound::Path(_, TraitBoundModifier::Maybe) => true,
+ TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
+ let TypeRef::Path(path) = &ctx.store[path.type_ref()] else {
+ return false;
+ };
+ let Some(pointee_sized) =
+ LangItem::PointeeSized.resolve_trait(ctx.db, ctx.resolver.krate())
+ else {
+ return false;
+ };
+ // Lower the path directly with `Resolver` instead of PathLoweringContext`
+ // to prevent diagnostics duplications.
+ ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path).is_some_and(
+ |it| matches!(it, TypeNs::TraitId(tr) if tr == pointee_sized),
+ )
+ }
+ _ => false,
+ }
+ }();
+ if lower {
ctx.lower_where_predicate(pred, true).for_each(drop);
}
return false;
diff --git a/crates/ide/src/inlay_hints/bounds.rs b/crates/ide/src/inlay_hints/bounds.rs
index b9a98f88be..f0003dae3f 100644
--- a/crates/ide/src/inlay_hints/bounds.rs
+++ b/crates/ide/src/inlay_hints/bounds.rs
@@ -143,7 +143,7 @@ fn foo<T>() {}
file_id: FileId(
1,
),
- range: 135..140,
+ range: 446..451,
},
),
),
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index adc581309d..1ccd20c25e 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -438,6 +438,8 @@ define_symbols! {
shr,
simd,
sized,
+ meta_sized,
+ pointee_sized,
skip,
slice_len_fn,
Some,
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 269ca466c3..20566f3ace 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -26,7 +26,7 @@
//! deref: sized
//! derive:
//! discriminant:
-//! drop:
+//! drop: sized
//! env: option
//! eq: sized
//! error: fmt
@@ -37,7 +37,7 @@
//! future: pin
//! coroutine: pin
//! dispatch_from_dyn: unsize, pin
-//! hash:
+//! hash: sized
//! include:
//! index: sized
//! infallible:
@@ -80,24 +80,18 @@ pub mod marker {
#[lang = "pointee_sized"]
#[fundamental]
#[rustc_specialization_trait]
- #[rustc_deny_explicit_impl]
- #[rustc_do_not_implement_via_object]
#[rustc_coinductive]
pub trait PointeeSized {}
#[lang = "meta_sized"]
#[fundamental]
#[rustc_specialization_trait]
- #[rustc_deny_explicit_impl]
- #[rustc_do_not_implement_via_object]
#[rustc_coinductive]
pub trait MetaSized: PointeeSized {}
#[lang = "sized"]
#[fundamental]
#[rustc_specialization_trait]
- #[rustc_deny_explicit_impl]
- #[rustc_do_not_implement_via_object]
#[rustc_coinductive]
pub trait Sized: MetaSized {}
// endregion:sized
@@ -139,7 +133,7 @@ pub mod marker {
// endregion:derive
mod copy_impls {
- use super::Copy;
+ use super::{Copy, PointeeSized};
macro_rules! impl_copy {
($($t:ty)*) => {
@@ -225,6 +219,8 @@ pub mod default {
// region:hash
pub mod hash {
+ use crate::marker::PointeeSized;
+
pub trait Hasher {}
pub trait Hash: PointeeSized {
@@ -240,6 +236,7 @@ pub mod hash {
// region:cell
pub mod cell {
+ use crate::marker::PointeeSized;
use crate::mem;
#[lang = "unsafe_cell"]
@@ -376,7 +373,7 @@ pub mod convert {
// endregion:from
// region:as_ref
- pub trait AsRef<T: PointeeSized>: PointeeSized {
+ pub trait AsRef<T: crate::marker::PointeeSized>: crate::marker::PointeeSized {
fn as_ref(&self) -> &T;
}
// endregion:as_ref
@@ -387,6 +384,8 @@ pub mod convert {
pub mod mem {
// region:manually_drop
+ use crate::marker::PointeeSized;
+
#[lang = "manually_drop"]
#[repr(transparent)]
pub struct ManuallyDrop<T: PointeeSized> {
@@ -447,7 +446,7 @@ pub mod mem {
pub mod ptr {
// region:drop
#[lang = "drop_in_place"]
- pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
+ pub unsafe fn drop_in_place<T: crate::marker::PointeeSized>(to_drop: *mut T) {
unsafe { drop_in_place(to_drop) }
}
pub const unsafe fn read<T>(src: *const T) -> T {
@@ -463,7 +462,7 @@ pub mod ptr {
// region:pointee
#[lang = "pointee_trait"]
#[rustc_deny_explicit_impl(implement_via_object = false)]
- pub trait Pointee: PointeeSized {
+ pub trait Pointee: crate::marker::PointeeSized {
#[lang = "metadata_type"]
type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
}
@@ -471,12 +470,14 @@ pub mod ptr {
// region:non_null
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
- pub struct NonNull<T: PointeeSized> {
+ pub struct NonNull<T: crate::marker::PointeeSized> {
pointer: *const T,
}
// region:coerce_unsized
- impl<T: PointeeSized, U: PointeeSized> crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T> where
- T: crate::marker::Unsize<U>
+ impl<T: crate::marker::PointeeSized, U: crate::marker::PointeeSized>
+ crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T>
+ where
+ T: crate::marker::Unsize<U>,
{
}
// endregion:coerce_unsized
@@ -497,7 +498,7 @@ pub mod ptr {
pub mod ops {
// region:coerce_unsized
mod unsize {
- use crate::marker::Unsize;
+ use crate::marker::{PointeeSized, Unsize};
#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {}
@@ -519,6 +520,8 @@ pub mod ops {
// region:deref
mod deref {
+ use crate::marker::PointeeSized;
+
#[lang = "deref"]
pub trait Deref: PointeeSized {
#[lang = "deref_target"]
@@ -1025,7 +1028,7 @@ pub mod ops {
// region:dispatch_from_dyn
mod dispatch_from_dyn {
- use crate::marker::Unsize;
+ use crate::marker::{PointeeSized, Unsize};
#[lang = "dispatch_from_dyn"]
pub trait DispatchFromDyn<T> {}
@@ -1044,6 +1047,8 @@ pub mod ops {
// region:eq
pub mod cmp {
+ use crate::marker::PointeeSized;
+
#[lang = "eq"]
pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
fn eq(&self, other: &Rhs) -> bool;
@@ -1090,6 +1095,8 @@ pub mod cmp {
// region:fmt
pub mod fmt {
+ use crate::marker::PointeeSized;
+
pub struct Error;
pub type Result = crate::result::Result<(), Error>;
pub struct Formatter<'a>;
@@ -1531,6 +1538,8 @@ pub mod iter {
mod traits {
mod iterator {
+ use crate::marker::PointeeSized;
+
#[doc(notable_trait)]
#[lang = "iterator"]
pub trait Iterator {