diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs index fff62b11c647..750308026eec 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 3c7333022402..eda680425796 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs index b9a98f88be76..f0003dae3f36 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs @@ -143,7 +143,7 @@ fn foo() {} file_id: FileId( 1, ), - range: 135..140, + range: 446..451, }, ), ), diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index adc581309d15..1ccd20c25e90 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index 269ca466c31a..20566f3acec1 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/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: PointeeSized { + pub trait AsRef: 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 { @@ -447,7 +446,7 @@ pub mod mem { pub mod ptr { // region:drop #[lang = "drop_in_place"] - pub unsafe fn drop_in_place(to_drop: *mut T) { + pub unsafe fn drop_in_place(to_drop: *mut T) { unsafe { drop_in_place(to_drop) } } pub const unsafe fn read(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 { + pub struct NonNull { pointer: *const T, } // region:coerce_unsized - impl crate::ops::CoerceUnsized> for NonNull where - T: crate::marker::Unsize + impl + crate::ops::CoerceUnsized> for NonNull + where + T: crate::marker::Unsize, { } // 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 {} @@ -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 {} @@ -1044,6 +1047,8 @@ pub mod ops { // region:eq pub mod cmp { + use crate::marker::PointeeSized; + #[lang = "eq"] pub trait PartialEq: 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 {