diff options
| author | David Wood <david.wood2@arm.com> | 2025-02-27 22:27:57 +0000 |
|---|---|---|
| committer | David Wood <david.wood2@arm.com> | 2025-06-16 23:04:34 +0000 |
| commit | 118d4e62c380a4dfb7a0c53a0001a19d0cee6567 (patch) | |
| tree | e1effc80ca9dafaa8e67dcb66d210a68ece5007f | |
| parent | 9044b78c0dca4751934c249a9d30b1a2d285fb54 (diff) | |
| download | rust-118d4e62c380a4dfb7a0c53a0001a19d0cee6567.tar.gz rust-118d4e62c380a4dfb7a0c53a0001a19d0cee6567.zip | |
middle: print `{Meta,Pointee}Sized` in opaques
When `sized_hierarchy` is enabled, rustc should print `MetaSized` or `PointeeSized` instead of `?Sized` in opaques.
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 36 | ||||
| -rw-r--r-- | tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs | 13 | ||||
| -rw-r--r-- | tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr | 12 | ||||
| -rw-r--r-- | tests/ui/sized-hierarchy/pretty-print-opaque.rs | 44 | ||||
| -rw-r--r-- | tests/ui/sized-hierarchy/pretty-print-opaque.stderr | 50 |
5 files changed, 150 insertions, 5 deletions
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 673a89a8134..c10277c75a7 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1069,24 +1069,35 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); + let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_sized_bound = false; let mut has_negative_sized_bound = false; - let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_meta_sized_bound = false; for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => { - // Don't print `+ Sized`, but rather `+ ?Sized` if absent. - if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { - match pred.polarity { + // With `feature(sized_hierarchy)`, don't print `?Sized` as an alias for + // `MetaSized`, and skip sizedness bounds to be added at the end. + match tcx.as_lang_item(pred.def_id()) { + Some(LangItem::Sized) => match pred.polarity { ty::PredicatePolarity::Positive => { has_sized_bound = true; continue; } ty::PredicatePolarity::Negative => has_negative_sized_bound = true, + }, + Some(LangItem::MetaSized) => { + has_meta_sized_bound = true; + continue; + } + Some(LangItem::PointeeSized) => { + bug!("`PointeeSized` is removed during lowering"); } + _ => (), } self.insert_trait_and_projection( @@ -1255,8 +1266,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { })?; } + let using_sized_hierarchy = self.tcx().features().sized_hierarchy(); let add_sized = has_sized_bound && (first || has_negative_sized_bound); - let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound; + let add_maybe_sized = + has_meta_sized_bound && !has_negative_sized_bound && !using_sized_hierarchy; + // Set `has_pointee_sized_bound` if there were no `Sized` or `MetaSized` bounds. + let has_pointee_sized_bound = + !has_sized_bound && !has_meta_sized_bound && !has_negative_sized_bound; if add_sized || add_maybe_sized { if !first { write!(self, " + ")?; @@ -1265,6 +1281,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { write!(self, "?")?; } write!(self, "Sized")?; + } else if has_meta_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "MetaSized")?; + } else if has_pointee_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "PointeeSized")?; } if !with_forced_trimmed_paths() { diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs new file mode 100644 index 00000000000..955108a2074 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --crate-type=lib + +pub trait Tr {} +impl Tr for u32 {} + +pub fn foo() -> Box<impl Tr + ?Sized> { + if true { + let x = foo(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + ?Sized` cannot be known + } + Box::new(1u32) +} diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr new file mode 100644 index 00000000000..bbe19870937 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `impl Tr + ?Sized` cannot be known at compilation time + --> $DIR/pretty-print-opaque-no-feat.rs:9:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + ?Sized` + = note: required for the cast from `Box<impl Tr + ?Sized>` to `Box<dyn Tr>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.rs b/tests/ui/sized-hierarchy/pretty-print-opaque.rs new file mode 100644 index 00000000000..7fad93efbd2 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -0,0 +1,44 @@ +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait Tr: PointeeSized {} +impl Tr for u32 {} + +pub fn sized() -> Box<impl Tr + Sized> { + if true { + let x = sized(); + let y: Box<dyn Tr> = x; + } + Box::new(1u32) +} + +pub fn neg_sized() -> Box<impl Tr + ?Sized> { + if true { + let x = neg_sized(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn metasized() -> Box<impl Tr + MetaSized> { + if true { + let x = metasized(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn pointeesized() -> Box<impl Tr + PointeeSized> { +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + if true { + let x = pointeesized(); +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + } + Box::new(1u32) +} diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr new file mode 100644 index 00000000000..523f6e7dd83 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -0,0 +1,50 @@ +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:35:26 + | +LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:20:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` + = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:29:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` + = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:38:17 + | +LL | let x = pointeesized(); + | ^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:40:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + PointeeSized` + = note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. |
