Rollup merge of #129969 - GrigorenkoPV:boxed-ty, r=compiler-errors
Make `Ty::boxed_ty` return an `Option`
Looks like a good place to use Rust's type system.
---
Most of 4ac7bcbaad/compiler/rustc_middle/src/ty/sty.rs (L971-L1963)
looks like it could be moved to `TyKind` (then I guess `Ty` should be made to deref to `TyKind`).
This commit is contained in:
commit
0180b8fff0
@ -662,9 +662,10 @@ fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool {
|
|||||||
// `&dyn Trait`
|
// `&dyn Trait`
|
||||||
ty::Ref(_, ty, _) if ty.is_trait() => true,
|
ty::Ref(_, ty, _) if ty.is_trait() => true,
|
||||||
// `Box<dyn Trait>`
|
// `Box<dyn Trait>`
|
||||||
_ if ty.is_box() && ty.boxed_ty().is_trait() => {
|
_ if ty.boxed_ty().is_some_and(Ty::is_trait) => {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
// `dyn Trait`
|
// `dyn Trait`
|
||||||
_ if ty.is_trait() => true,
|
_ if ty.is_trait() => true,
|
||||||
// Anything else.
|
// Anything else.
|
||||||
|
@ -345,9 +345,9 @@ fn describe_field_from_ty(
|
|||||||
variant_index: Option<VariantIdx>,
|
variant_index: Option<VariantIdx>,
|
||||||
including_tuple_field: IncludingTupleField,
|
including_tuple_field: IncludingTupleField,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
if ty.is_box() {
|
if let Some(boxed_ty) = ty.boxed_ty() {
|
||||||
// If the type is a box, the field is described from the boxed type
|
// If the type is a box, the field is described from the boxed type
|
||||||
self.describe_field_from_ty(ty.boxed_ty(), field, variant_index, including_tuple_field)
|
self.describe_field_from_ty(boxed_ty, field, variant_index, including_tuple_field)
|
||||||
} else {
|
} else {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Adt(def, _) => {
|
ty::Adt(def, _) => {
|
||||||
|
@ -456,7 +456,7 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
|
|||||||
if def.is_box()
|
if def.is_box()
|
||||||
&& args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) =>
|
&& args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) =>
|
||||||
{
|
{
|
||||||
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
|
build_pointer_or_reference_di_node(cx, t, t.expect_boxed_ty(), unique_type_id)
|
||||||
}
|
}
|
||||||
ty::FnDef(..) | ty::FnPtr(..) => build_subroutine_type_di_node(cx, unique_type_id),
|
ty::FnDef(..) | ty::FnPtr(..) => build_subroutine_type_di_node(cx, unique_type_id),
|
||||||
ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
|
ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
|
||||||
|
@ -189,7 +189,7 @@ fn layout_compat(
|
|||||||
ty::Ref(_, ty, _) => *ty,
|
ty::Ref(_, ty, _) => *ty,
|
||||||
ty::RawPtr(ty, _) => *ty,
|
ty::RawPtr(ty, _) => *ty,
|
||||||
// We only accept `Box` with the default allocator.
|
// We only accept `Box` with the default allocator.
|
||||||
_ if ty.is_box_global(*self.tcx) => ty.boxed_ty(),
|
_ if ty.is_box_global(*self.tcx) => ty.expect_boxed_ty(),
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
@ -63,8 +63,7 @@ pub(super) fn lint_edition_dependent_dot_call(
|
|||||||
// Instead, the problem is that the array-into_iter hack will no longer
|
// Instead, the problem is that the array-into_iter hack will no longer
|
||||||
// apply in Rust 2021.
|
// apply in Rust 2021.
|
||||||
(ARRAY_INTO_ITER, "2021")
|
(ARRAY_INTO_ITER, "2021")
|
||||||
} else if self_ty.is_box()
|
} else if self_ty.boxed_ty().is_some_and(Ty::is_slice)
|
||||||
&& self_ty.boxed_ty().is_slice()
|
|
||||||
&& !span.at_least_rust_2024()
|
&& !span.at_least_rust_2024()
|
||||||
{
|
{
|
||||||
// In this case, it wasn't really a prelude addition that was the problem.
|
// In this case, it wasn't really a prelude addition that was the problem.
|
||||||
|
@ -1485,8 +1485,7 @@ fn consider_probe(
|
|||||||
|
|
||||||
// Some trait methods are excluded for boxed slices before 2024.
|
// Some trait methods are excluded for boxed slices before 2024.
|
||||||
// (`boxed_slice.into_iter()` wants a slice iterator for compatibility.)
|
// (`boxed_slice.into_iter()` wants a slice iterator for compatibility.)
|
||||||
if self_ty.is_box()
|
if self_ty.boxed_ty().is_some_and(Ty::is_slice)
|
||||||
&& self_ty.boxed_ty().is_slice()
|
|
||||||
&& !method_name.span.at_least_rust_2024()
|
&& !method_name.span.at_least_rust_2024()
|
||||||
{
|
{
|
||||||
let trait_def = self.tcx.trait_def(poly_trait_ref.def_id());
|
let trait_def = self.tcx.trait_def(poly_trait_ref.def_id());
|
||||||
|
@ -94,12 +94,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
|
|||||||
fn is_ref_to_array(ty: Ty<'_>) -> bool {
|
fn is_ref_to_array(ty: Ty<'_>) -> bool {
|
||||||
if let ty::Ref(_, pointee_ty, _) = *ty.kind() { pointee_ty.is_array() } else { false }
|
if let ty::Ref(_, pointee_ty, _) = *ty.kind() { pointee_ty.is_array() } else { false }
|
||||||
}
|
}
|
||||||
fn is_boxed_slice(ty: Ty<'_>) -> bool {
|
|
||||||
ty.is_box() && ty.boxed_ty().is_slice()
|
|
||||||
}
|
|
||||||
fn is_ref_to_boxed_slice(ty: Ty<'_>) -> bool {
|
fn is_ref_to_boxed_slice(ty: Ty<'_>) -> bool {
|
||||||
if let ty::Ref(_, pointee_ty, _) = *ty.kind() {
|
if let ty::Ref(_, pointee_ty, _) = *ty.kind() {
|
||||||
is_boxed_slice(pointee_ty)
|
pointee_ty.boxed_ty().is_some_and(Ty::is_slice)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -119,7 +116,7 @@ fn is_ref_to_boxed_slice(ty: Ty<'_>) -> bool {
|
|||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.take_while(|ty| !is_ref_to_boxed_slice(*ty))
|
.take_while(|ty| !is_ref_to_boxed_slice(*ty))
|
||||||
.position(|ty| is_boxed_slice(ty))
|
.position(|ty| ty.boxed_ty().is_some_and(Ty::is_slice))
|
||||||
{
|
{
|
||||||
(BOXED_SLICE_INTO_ITER, "Box<[T]>", "2024", idx == 0)
|
(BOXED_SLICE_INTO_ITER, "Box<[T]>", "2024", idx == 0)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1304,8 +1304,10 @@ fn check_type_for_ffi(
|
|||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Adt(def, args) => {
|
ty::Adt(def, args) => {
|
||||||
if def.is_box() && matches!(self.mode, CItemKind::Definition) {
|
if let Some(boxed) = ty.boxed_ty()
|
||||||
if ty.boxed_ty().is_sized(tcx, self.cx.param_env) {
|
&& matches!(self.mode, CItemKind::Definition)
|
||||||
|
{
|
||||||
|
if boxed.is_sized(tcx, self.cx.param_env) {
|
||||||
return FfiSafe;
|
return FfiSafe;
|
||||||
} else {
|
} else {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
|
@ -283,9 +283,8 @@ fn is_ty_must_use<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Adt(..) if ty.is_box() => {
|
ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => {
|
||||||
let boxed_ty = ty.boxed_ty();
|
is_ty_must_use(cx, boxed, expr, span)
|
||||||
is_ty_must_use(cx, boxed_ty, expr, span)
|
|
||||||
.map(|inner| MustUsePath::Boxed(Box::new(inner)))
|
.map(|inner| MustUsePath::Boxed(Box::new(inner)))
|
||||||
}
|
}
|
||||||
ty::Adt(def, args) if cx.tcx.is_lang_item(def.did(), LangItem::Pin) => {
|
ty::Adt(def, args) if cx.tcx.is_lang_item(def.did(), LangItem::Pin) => {
|
||||||
|
@ -1075,11 +1075,13 @@ fn ty_and_layout_pointee_info_at(
|
|||||||
// the raw pointer, so size and align are set to the boxed type, but `pointee.safe`
|
// the raw pointer, so size and align are set to the boxed type, but `pointee.safe`
|
||||||
// will still be `None`.
|
// will still be `None`.
|
||||||
if let Some(ref mut pointee) = result {
|
if let Some(ref mut pointee) = result {
|
||||||
if offset.bytes() == 0 && this.ty.is_box() {
|
if offset.bytes() == 0
|
||||||
|
&& let Some(boxed_ty) = this.ty.boxed_ty()
|
||||||
|
{
|
||||||
debug_assert!(pointee.safe.is_none());
|
debug_assert!(pointee.safe.is_none());
|
||||||
let optimize = tcx.sess.opts.optimize != OptLevel::No;
|
let optimize = tcx.sess.opts.optimize != OptLevel::No;
|
||||||
pointee.safe = Some(PointerKind::Box {
|
pointee.safe = Some(PointerKind::Box {
|
||||||
unpin: optimize && this.ty.boxed_ty().is_unpin(tcx, cx.param_env()),
|
unpin: optimize && boxed_ty.is_unpin(tcx, cx.param_env()),
|
||||||
global: this.ty.is_box_global(tcx),
|
global: this.ty.is_box_global(tcx),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1170,14 +1170,19 @@ pub fn is_box_global(self, tcx: TyCtxt<'tcx>) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Panics if called on any type other than `Box<T>`.
|
pub fn boxed_ty(self) -> Option<Ty<'tcx>> {
|
||||||
pub fn boxed_ty(self) -> Ty<'tcx> {
|
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
Adt(def, args) if def.is_box() => args.type_at(0),
|
Adt(def, args) if def.is_box() => Some(args.type_at(0)),
|
||||||
_ => bug!("`boxed_ty` is called on non-box type {:?}", self),
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Panics if called on any type other than `Box<T>`.
|
||||||
|
pub fn expect_boxed_ty(self) -> Ty<'tcx> {
|
||||||
|
self.boxed_ty()
|
||||||
|
.unwrap_or_else(|| bug!("`expect_boxed_ty` is called on non-box type {:?}", self))
|
||||||
|
}
|
||||||
|
|
||||||
/// A scalar type is one that denotes an atomic datum, with no sub-components.
|
/// A scalar type is one that denotes an atomic datum, with no sub-components.
|
||||||
/// (A RawPtr is scalar because it represents a non-managed pointer, so its
|
/// (A RawPtr is scalar because it represents a non-managed pointer, so its
|
||||||
/// contents are abstract to rustc.)
|
/// contents are abstract to rustc.)
|
||||||
@ -1323,7 +1328,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
|||||||
/// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
|
/// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
|
||||||
pub fn builtin_deref(self, explicit: bool) -> Option<Ty<'tcx>> {
|
pub fn builtin_deref(self, explicit: bool) -> Option<Ty<'tcx>> {
|
||||||
match *self.kind() {
|
match *self.kind() {
|
||||||
Adt(def, _) if def.is_box() => Some(self.boxed_ty()),
|
_ if let Some(boxed) = self.boxed_ty() => Some(boxed),
|
||||||
Ref(_, ty, _) => Some(ty),
|
Ref(_, ty, _) => Some(ty),
|
||||||
RawPtr(ty, _) if explicit => Some(ty),
|
RawPtr(ty, _) if explicit => Some(ty),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1628,7 +1628,7 @@ pub fn determine<P>(self_arg_ty: Ty<'tcx>, is_self_ty: P) -> ExplicitSelf<'tcx>
|
|||||||
_ if is_self_ty(self_arg_ty) => ByValue,
|
_ if is_self_ty(self_arg_ty) => ByValue,
|
||||||
ty::Ref(region, ty, mutbl) if is_self_ty(ty) => ByReference(region, mutbl),
|
ty::Ref(region, ty, mutbl) if is_self_ty(ty) => ByReference(region, mutbl),
|
||||||
ty::RawPtr(ty, mutbl) if is_self_ty(ty) => ByRawPointer(mutbl),
|
ty::RawPtr(ty, mutbl) if is_self_ty(ty) => ByRawPointer(mutbl),
|
||||||
ty::Adt(def, _) if def.is_box() && is_self_ty(self_arg_ty.boxed_ty()) => ByBox,
|
_ if self_arg_ty.boxed_ty().is_some_and(is_self_ty) => ByBox,
|
||||||
_ => Other,
|
_ => Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,11 +62,13 @@ fn visit_place(
|
|||||||
let base_ty = self.local_decls[place.local].ty;
|
let base_ty = self.local_decls[place.local].ty;
|
||||||
|
|
||||||
// Derefer ensures that derefs are always the first projection
|
// Derefer ensures that derefs are always the first projection
|
||||||
if place.projection.first() == Some(&PlaceElem::Deref) && base_ty.is_box() {
|
if let Some(PlaceElem::Deref) = place.projection.first()
|
||||||
|
&& let Some(boxed_ty) = base_ty.boxed_ty()
|
||||||
|
{
|
||||||
let source_info = self.local_decls[place.local].source_info;
|
let source_info = self.local_decls[place.local].source_info;
|
||||||
|
|
||||||
let (unique_ty, nonnull_ty, ptr_ty) =
|
let (unique_ty, nonnull_ty, ptr_ty) =
|
||||||
build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did);
|
build_ptr_tys(tcx, boxed_ty, self.unique_did, self.nonnull_did);
|
||||||
|
|
||||||
let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
|
let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
|
||||||
|
|
||||||
@ -120,13 +122,15 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
for (base, elem) in place.iter_projections() {
|
for (base, elem) in place.iter_projections() {
|
||||||
let base_ty = base.ty(&body.local_decls, tcx).ty;
|
let base_ty = base.ty(&body.local_decls, tcx).ty;
|
||||||
|
|
||||||
if elem == PlaceElem::Deref && base_ty.is_box() {
|
if let PlaceElem::Deref = elem
|
||||||
|
&& let Some(boxed_ty) = base_ty.boxed_ty()
|
||||||
|
{
|
||||||
// Clone the projections before us, since now we need to mutate them.
|
// Clone the projections before us, since now we need to mutate them.
|
||||||
let new_projections =
|
let new_projections =
|
||||||
new_projections.get_or_insert_with(|| base.projection.to_vec());
|
new_projections.get_or_insert_with(|| base.projection.to_vec());
|
||||||
|
|
||||||
let (unique_ty, nonnull_ty, ptr_ty) =
|
let (unique_ty, nonnull_ty, ptr_ty) =
|
||||||
build_ptr_tys(tcx, base_ty.boxed_ty(), unique_did, nonnull_did);
|
build_ptr_tys(tcx, boxed_ty, unique_did, nonnull_did);
|
||||||
|
|
||||||
new_projections.extend_from_slice(&build_projection(
|
new_projections.extend_from_slice(&build_projection(
|
||||||
unique_ty, nonnull_ty, ptr_ty,
|
unique_ty, nonnull_ty, ptr_ty,
|
||||||
|
@ -1041,8 +1041,11 @@ fn find_vtable_types_for_unsizing<'tcx>(
|
|||||||
match (source_ty.kind(), target_ty.kind()) {
|
match (source_ty.kind(), target_ty.kind()) {
|
||||||
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
|
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
|
||||||
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b),
|
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b),
|
||||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
(_, _)
|
||||||
ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty())
|
if let Some(source_boxed) = source_ty.boxed_ty()
|
||||||
|
&& let Some(target_boxed) = target_ty.boxed_ty() =>
|
||||||
|
{
|
||||||
|
ptr_vtable(source_boxed, target_boxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// T as dyn* Trait
|
// T as dyn* Trait
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
#![feature(array_windows)]
|
#![feature(array_windows)]
|
||||||
|
#![feature(if_let_guard)]
|
||||||
|
#![feature(let_chains)]
|
||||||
#![warn(unreachable_pub)]
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
|
@ -348,8 +348,7 @@ fn note_error_origin(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ty::error::ExpectedFound { found, .. }) = exp_found
|
if let Some(ty::error::ExpectedFound { found, .. }) = exp_found
|
||||||
&& ty.is_box()
|
&& ty.boxed_ty() == Some(found)
|
||||||
&& ty.boxed_ty() == found
|
|
||||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
|
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
|
@ -50,7 +50,7 @@ pub fn new(conf: &'static Conf) -> Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_non_trait_box(ty: Ty<'_>) -> bool {
|
fn is_non_trait_box(ty: Ty<'_>) -> bool {
|
||||||
ty.is_box() && !ty.boxed_ty().is_trait()
|
ty.boxed_ty().is_some_and(|boxed| !boxed.is_trait())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EscapeDelegate<'a, 'tcx> {
|
struct EscapeDelegate<'a, 'tcx> {
|
||||||
@ -191,8 +191,8 @@ fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
|||||||
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
|
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
|
||||||
fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
|
fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
|
||||||
// Large types need to be boxed to avoid stack overflows.
|
// Large types need to be boxed to avoid stack overflows.
|
||||||
if ty.is_box() {
|
if let Some(boxed_ty) = ty.boxed_ty() {
|
||||||
self.cx.layout_of(ty.boxed_ty()).map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
|
self.cx.layout_of(boxed_ty).map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -5187,8 +5187,8 @@ fn matches<'a>(self, cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> boo
|
|||||||
fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
|
fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
|
||||||
if ty == parent_ty {
|
if ty == parent_ty {
|
||||||
true
|
true
|
||||||
} else if ty.is_box() {
|
} else if let Some(boxed_ty) = ty.boxed_ty() {
|
||||||
ty.boxed_ty() == parent_ty
|
boxed_ty == parent_ty
|
||||||
} else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) {
|
} else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) {
|
||||||
if let ty::Adt(_, args) = ty.kind() {
|
if let ty::Adt(_, args) = ty.kind() {
|
||||||
args.types().next().map_or(false, |t| t == parent_ty)
|
args.types().next().map_or(false, |t| t == parent_ty)
|
||||||
|
@ -16,7 +16,7 @@ pub(super) fn derefs_to_slice<'tcx>(
|
|||||||
fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
|
fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Slice(_) => true,
|
ty::Slice(_) => true,
|
||||||
ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
|
ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => may_slice(cx, boxed),
|
||||||
ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::Vec),
|
ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::Vec),
|
||||||
ty::Array(_, size) => size.try_eval_target_usize(cx.tcx, cx.param_env).is_some(),
|
ty::Array(_, size) => size.try_eval_target_usize(cx.tcx, cx.param_env).is_some(),
|
||||||
ty::Ref(_, inner, _) => may_slice(cx, *inner),
|
ty::Ref(_, inner, _) => may_slice(cx, *inner),
|
||||||
@ -33,7 +33,7 @@ fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
|
|||||||
} else {
|
} else {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Slice(_) => Some(expr),
|
ty::Slice(_) => Some(expr),
|
||||||
ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr),
|
_ if ty.boxed_ty().is_some_and(|boxed| may_slice(cx, boxed)) => Some(expr),
|
||||||
ty::Ref(_, inner, _) => {
|
ty::Ref(_, inner, _) => {
|
||||||
if may_slice(cx, *inner) {
|
if may_slice(cx, *inner) {
|
||||||
Some(expr)
|
Some(expr)
|
||||||
|
@ -75,11 +75,9 @@ fn check_fn_item(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, def_id: Loc
|
|||||||
.instantiate_bound_regions_with_erased(cx.tcx.fn_sig(def_id).skip_binder())
|
.instantiate_bound_regions_with_erased(cx.tcx.fn_sig(def_id).skip_binder())
|
||||||
.output();
|
.output();
|
||||||
|
|
||||||
if !return_ty.is_box() {
|
let Some(boxed_ty) = return_ty.boxed_ty() else {
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
let boxed_ty = return_ty.boxed_ty();
|
|
||||||
|
|
||||||
// It's sometimes useful to return Box<T> if T is unsized, so don't lint those.
|
// It's sometimes useful to return Box<T> if T is unsized, so don't lint those.
|
||||||
// Also, don't lint if we know that T is very large, in which case returning
|
// Also, don't lint if we know that T is very large, in which case returning
|
||||||
|
@ -704,8 +704,8 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnS
|
|||||||
|
|
||||||
/// If the type is function like, get the signature for it.
|
/// If the type is function like, get the signature for it.
|
||||||
pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>> {
|
pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>> {
|
||||||
if ty.is_box() {
|
if let Some(boxed_ty) = ty.boxed_ty() {
|
||||||
return ty_sig(cx, ty.boxed_ty());
|
return ty_sig(cx, boxed_ty);
|
||||||
}
|
}
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Closure(id, subs) => {
|
ty::Closure(id, subs) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user