mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 10:39:45 +00:00
Backport new sized-hierarchy trait bounds in old ways
This commit is contained in:
parent
d3e6dcd3ca
commit
953e9d1c36
5 changed files with 78 additions and 24 deletions
|
|
@ -308,6 +308,8 @@ impl LangItem {
|
||||||
language_item_table! {
|
language_item_table! {
|
||||||
// Variant name, Name, Getter method name, Target Generic requirements;
|
// Variant name, Name, Getter method name, Target Generic requirements;
|
||||||
Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0);
|
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);
|
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||||
/// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
|
/// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
|
||||||
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
|
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
|
||||||
|
|
|
||||||
|
|
@ -581,11 +581,28 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
match bound {
|
match bound {
|
||||||
&TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
|
&TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
|
||||||
// FIXME Don't silently drop the hrtb lifetimes here
|
// 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 let Some((trait_ref, mut ctx)) =
|
||||||
if !ignore_bindings {
|
self.lower_trait_ref_from_path(path, self_ty.clone())
|
||||||
assoc_bounds = ctx.assoc_type_bindings_from_type_bound(trait_ref.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) => {
|
&TypeBound::Path(path, TraitBoundModifier::Maybe) => {
|
||||||
|
|
@ -945,8 +962,32 @@ pub(crate) fn generic_predicates_for_param_query(
|
||||||
| WherePredicate::TypeBound { target, bound, .. } => {
|
| WherePredicate::TypeBound { target, bound, .. } => {
|
||||||
let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
|
let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
|
||||||
if invalid_target {
|
if invalid_target {
|
||||||
// If this is filtered out without lowering, `?Sized` is not gathered into `ctx.unsized_types`
|
// FIXME(sized-hierarchy): Revisit and adjust this properly once we have implemented
|
||||||
if let TypeBound::Path(_, TraitBoundModifier::Maybe) = bound {
|
// 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);
|
ctx.lower_where_predicate(pred, true).for_each(drop);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ fn foo<T>() {}
|
||||||
file_id: FileId(
|
file_id: FileId(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
range: 135..140,
|
range: 446..451,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -438,6 +438,8 @@ define_symbols! {
|
||||||
shr,
|
shr,
|
||||||
simd,
|
simd,
|
||||||
sized,
|
sized,
|
||||||
|
meta_sized,
|
||||||
|
pointee_sized,
|
||||||
skip,
|
skip,
|
||||||
slice_len_fn,
|
slice_len_fn,
|
||||||
Some,
|
Some,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
//! deref: sized
|
//! deref: sized
|
||||||
//! derive:
|
//! derive:
|
||||||
//! discriminant:
|
//! discriminant:
|
||||||
//! drop:
|
//! drop: sized
|
||||||
//! env: option
|
//! env: option
|
||||||
//! eq: sized
|
//! eq: sized
|
||||||
//! error: fmt
|
//! error: fmt
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
//! future: pin
|
//! future: pin
|
||||||
//! coroutine: pin
|
//! coroutine: pin
|
||||||
//! dispatch_from_dyn: unsize, pin
|
//! dispatch_from_dyn: unsize, pin
|
||||||
//! hash:
|
//! hash: sized
|
||||||
//! include:
|
//! include:
|
||||||
//! index: sized
|
//! index: sized
|
||||||
//! infallible:
|
//! infallible:
|
||||||
|
|
@ -80,24 +80,18 @@ pub mod marker {
|
||||||
#[lang = "pointee_sized"]
|
#[lang = "pointee_sized"]
|
||||||
#[fundamental]
|
#[fundamental]
|
||||||
#[rustc_specialization_trait]
|
#[rustc_specialization_trait]
|
||||||
#[rustc_deny_explicit_impl]
|
|
||||||
#[rustc_do_not_implement_via_object]
|
|
||||||
#[rustc_coinductive]
|
#[rustc_coinductive]
|
||||||
pub trait PointeeSized {}
|
pub trait PointeeSized {}
|
||||||
|
|
||||||
#[lang = "meta_sized"]
|
#[lang = "meta_sized"]
|
||||||
#[fundamental]
|
#[fundamental]
|
||||||
#[rustc_specialization_trait]
|
#[rustc_specialization_trait]
|
||||||
#[rustc_deny_explicit_impl]
|
|
||||||
#[rustc_do_not_implement_via_object]
|
|
||||||
#[rustc_coinductive]
|
#[rustc_coinductive]
|
||||||
pub trait MetaSized: PointeeSized {}
|
pub trait MetaSized: PointeeSized {}
|
||||||
|
|
||||||
#[lang = "sized"]
|
#[lang = "sized"]
|
||||||
#[fundamental]
|
#[fundamental]
|
||||||
#[rustc_specialization_trait]
|
#[rustc_specialization_trait]
|
||||||
#[rustc_deny_explicit_impl]
|
|
||||||
#[rustc_do_not_implement_via_object]
|
|
||||||
#[rustc_coinductive]
|
#[rustc_coinductive]
|
||||||
pub trait Sized: MetaSized {}
|
pub trait Sized: MetaSized {}
|
||||||
// endregion:sized
|
// endregion:sized
|
||||||
|
|
@ -139,7 +133,7 @@ pub mod marker {
|
||||||
// endregion:derive
|
// endregion:derive
|
||||||
|
|
||||||
mod copy_impls {
|
mod copy_impls {
|
||||||
use super::Copy;
|
use super::{Copy, PointeeSized};
|
||||||
|
|
||||||
macro_rules! impl_copy {
|
macro_rules! impl_copy {
|
||||||
($($t:ty)*) => {
|
($($t:ty)*) => {
|
||||||
|
|
@ -225,6 +219,8 @@ pub mod default {
|
||||||
|
|
||||||
// region:hash
|
// region:hash
|
||||||
pub mod hash {
|
pub mod hash {
|
||||||
|
use crate::marker::PointeeSized;
|
||||||
|
|
||||||
pub trait Hasher {}
|
pub trait Hasher {}
|
||||||
|
|
||||||
pub trait Hash: PointeeSized {
|
pub trait Hash: PointeeSized {
|
||||||
|
|
@ -240,6 +236,7 @@ pub mod hash {
|
||||||
|
|
||||||
// region:cell
|
// region:cell
|
||||||
pub mod cell {
|
pub mod cell {
|
||||||
|
use crate::marker::PointeeSized;
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
|
|
||||||
#[lang = "unsafe_cell"]
|
#[lang = "unsafe_cell"]
|
||||||
|
|
@ -376,7 +373,7 @@ pub mod convert {
|
||||||
// endregion:from
|
// endregion:from
|
||||||
|
|
||||||
// region:as_ref
|
// region:as_ref
|
||||||
pub trait AsRef<T: PointeeSized>: PointeeSized {
|
pub trait AsRef<T: crate::marker::PointeeSized>: crate::marker::PointeeSized {
|
||||||
fn as_ref(&self) -> &T;
|
fn as_ref(&self) -> &T;
|
||||||
}
|
}
|
||||||
// endregion:as_ref
|
// endregion:as_ref
|
||||||
|
|
@ -387,6 +384,8 @@ pub mod convert {
|
||||||
|
|
||||||
pub mod mem {
|
pub mod mem {
|
||||||
// region:manually_drop
|
// region:manually_drop
|
||||||
|
use crate::marker::PointeeSized;
|
||||||
|
|
||||||
#[lang = "manually_drop"]
|
#[lang = "manually_drop"]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct ManuallyDrop<T: PointeeSized> {
|
pub struct ManuallyDrop<T: PointeeSized> {
|
||||||
|
|
@ -447,7 +446,7 @@ pub mod mem {
|
||||||
pub mod ptr {
|
pub mod ptr {
|
||||||
// region:drop
|
// region:drop
|
||||||
#[lang = "drop_in_place"]
|
#[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) }
|
unsafe { drop_in_place(to_drop) }
|
||||||
}
|
}
|
||||||
pub const unsafe fn read<T>(src: *const T) -> T {
|
pub const unsafe fn read<T>(src: *const T) -> T {
|
||||||
|
|
@ -463,7 +462,7 @@ pub mod ptr {
|
||||||
// region:pointee
|
// region:pointee
|
||||||
#[lang = "pointee_trait"]
|
#[lang = "pointee_trait"]
|
||||||
#[rustc_deny_explicit_impl(implement_via_object = false)]
|
#[rustc_deny_explicit_impl(implement_via_object = false)]
|
||||||
pub trait Pointee: PointeeSized {
|
pub trait Pointee: crate::marker::PointeeSized {
|
||||||
#[lang = "metadata_type"]
|
#[lang = "metadata_type"]
|
||||||
type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
|
type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
|
||||||
}
|
}
|
||||||
|
|
@ -471,12 +470,14 @@ pub mod ptr {
|
||||||
// region:non_null
|
// region:non_null
|
||||||
#[rustc_layout_scalar_valid_range_start(1)]
|
#[rustc_layout_scalar_valid_range_start(1)]
|
||||||
#[rustc_nonnull_optimization_guaranteed]
|
#[rustc_nonnull_optimization_guaranteed]
|
||||||
pub struct NonNull<T: PointeeSized> {
|
pub struct NonNull<T: crate::marker::PointeeSized> {
|
||||||
pointer: *const T,
|
pointer: *const T,
|
||||||
}
|
}
|
||||||
// region:coerce_unsized
|
// region:coerce_unsized
|
||||||
impl<T: PointeeSized, U: PointeeSized> crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T> where
|
impl<T: crate::marker::PointeeSized, U: crate::marker::PointeeSized>
|
||||||
T: crate::marker::Unsize<U>
|
crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T>
|
||||||
|
where
|
||||||
|
T: crate::marker::Unsize<U>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
// endregion:coerce_unsized
|
// endregion:coerce_unsized
|
||||||
|
|
@ -497,7 +498,7 @@ pub mod ptr {
|
||||||
pub mod ops {
|
pub mod ops {
|
||||||
// region:coerce_unsized
|
// region:coerce_unsized
|
||||||
mod unsize {
|
mod unsize {
|
||||||
use crate::marker::Unsize;
|
use crate::marker::{PointeeSized, Unsize};
|
||||||
|
|
||||||
#[lang = "coerce_unsized"]
|
#[lang = "coerce_unsized"]
|
||||||
pub trait CoerceUnsized<T> {}
|
pub trait CoerceUnsized<T> {}
|
||||||
|
|
@ -519,6 +520,8 @@ pub mod ops {
|
||||||
|
|
||||||
// region:deref
|
// region:deref
|
||||||
mod deref {
|
mod deref {
|
||||||
|
use crate::marker::PointeeSized;
|
||||||
|
|
||||||
#[lang = "deref"]
|
#[lang = "deref"]
|
||||||
pub trait Deref: PointeeSized {
|
pub trait Deref: PointeeSized {
|
||||||
#[lang = "deref_target"]
|
#[lang = "deref_target"]
|
||||||
|
|
@ -1025,7 +1028,7 @@ pub mod ops {
|
||||||
|
|
||||||
// region:dispatch_from_dyn
|
// region:dispatch_from_dyn
|
||||||
mod dispatch_from_dyn {
|
mod dispatch_from_dyn {
|
||||||
use crate::marker::Unsize;
|
use crate::marker::{PointeeSized, Unsize};
|
||||||
|
|
||||||
#[lang = "dispatch_from_dyn"]
|
#[lang = "dispatch_from_dyn"]
|
||||||
pub trait DispatchFromDyn<T> {}
|
pub trait DispatchFromDyn<T> {}
|
||||||
|
|
@ -1044,6 +1047,8 @@ pub mod ops {
|
||||||
|
|
||||||
// region:eq
|
// region:eq
|
||||||
pub mod cmp {
|
pub mod cmp {
|
||||||
|
use crate::marker::PointeeSized;
|
||||||
|
|
||||||
#[lang = "eq"]
|
#[lang = "eq"]
|
||||||
pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
|
pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
|
||||||
fn eq(&self, other: &Rhs) -> bool;
|
fn eq(&self, other: &Rhs) -> bool;
|
||||||
|
|
@ -1090,6 +1095,8 @@ pub mod cmp {
|
||||||
|
|
||||||
// region:fmt
|
// region:fmt
|
||||||
pub mod fmt {
|
pub mod fmt {
|
||||||
|
use crate::marker::PointeeSized;
|
||||||
|
|
||||||
pub struct Error;
|
pub struct Error;
|
||||||
pub type Result = crate::result::Result<(), Error>;
|
pub type Result = crate::result::Result<(), Error>;
|
||||||
pub struct Formatter<'a>;
|
pub struct Formatter<'a>;
|
||||||
|
|
@ -1531,6 +1538,8 @@ pub mod iter {
|
||||||
|
|
||||||
mod traits {
|
mod traits {
|
||||||
mod iterator {
|
mod iterator {
|
||||||
|
use crate::marker::PointeeSized;
|
||||||
|
|
||||||
#[doc(notable_trait)]
|
#[doc(notable_trait)]
|
||||||
#[lang = "iterator"]
|
#[lang = "iterator"]
|
||||||
pub trait Iterator {
|
pub trait Iterator {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue