Skip to content

Commit 0842ab3

Browse files
committed
middle: print {Meta,Pointee}Sized in opaques
When `sized_hierarchy` is enabled, rustc should print `MetaSized` or `PointeeSized` instead of `?Sized` in opaques.
1 parent dc1150a commit 0842ab3

File tree

5 files changed

+147
-3
lines changed

5 files changed

+147
-3
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,16 +1002,20 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10021002

10031003
let mut traits = FxIndexMap::default();
10041004
let mut fn_traits = FxIndexMap::default();
1005+
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
1006+
10051007
let mut has_sized_bound = false;
10061008
let mut has_negative_sized_bound = false;
1007-
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
1009+
let mut has_metasized_bound = false;
1010+
let mut has_pointeesized_bound = false;
10081011

10091012
for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) {
10101013
let bound_predicate = predicate.kind();
10111014

10121015
match bound_predicate.skip_binder() {
10131016
ty::ClauseKind::Trait(pred) => {
1014-
// Don't print `+ Sized`, but rather `+ ?Sized` if absent.
1017+
// With `feature(sized_hierarchy)`, don't print `?Sized` as an alias for
1018+
// `MetaSized`, and skip sizedness bounds to be added at the end.
10151019
if tcx.is_lang_item(pred.def_id(), LangItem::Sized) {
10161020
match pred.polarity {
10171021
ty::PredicatePolarity::Positive => {
@@ -1020,6 +1024,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10201024
}
10211025
ty::PredicatePolarity::Negative => has_negative_sized_bound = true,
10221026
}
1027+
} else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) {
1028+
has_metasized_bound = true;
1029+
continue;
1030+
} else if tcx.is_lang_item(pred.def_id(), LangItem::PointeeSized) {
1031+
// Unexpected - `PointeeSized` is the absence of bounds.
1032+
has_pointeesized_bound = true;
1033+
continue;
10231034
}
10241035

10251036
self.insert_trait_and_projection(
@@ -1184,8 +1195,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11841195
})?;
11851196
}
11861197

1198+
let using_sized_hierarchy = self.tcx().features().sized_hierarchy();
11871199
let add_sized = has_sized_bound && (first || has_negative_sized_bound);
1188-
let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound;
1200+
let add_maybe_sized = has_metasized_bound && !has_negative_sized_bound && !using_sized_hierarchy;
1201+
// Set `has_pointeesized_bound` if there were no `Sized` or `MetaSized` bounds.
1202+
has_pointeesized_bound = has_pointeesized_bound || (!has_sized_bound && !has_metasized_bound && !has_negative_sized_bound);
11891203
if add_sized || add_maybe_sized {
11901204
if !first {
11911205
write!(self, " + ")?;
@@ -1194,6 +1208,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11941208
write!(self, "?")?;
11951209
}
11961210
write!(self, "Sized")?;
1211+
} else if has_metasized_bound && using_sized_hierarchy {
1212+
if !first {
1213+
write!(self, " + ")?;
1214+
}
1215+
write!(self, "MetaSized")?;
1216+
} else if has_pointeesized_bound && using_sized_hierarchy {
1217+
if !first {
1218+
write!(self, " + ")?;
1219+
}
1220+
write!(self, "PointeeSized")?;
11971221
}
11981222

11991223
if !with_forced_trimmed_paths() {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ compile-flags: --crate-type=lib
2+
3+
pub trait Tr {}
4+
impl Tr for u32 {}
5+
6+
pub fn foo() -> Box<impl Tr + ?Sized> {
7+
if true {
8+
let x = foo();
9+
let y: Box<dyn Tr> = x;
10+
//~^ ERROR: the size for values of type `impl Tr + ?Sized` cannot be known
11+
}
12+
Box::new(1u32)
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the size for values of type `impl Tr + ?Sized` cannot be known at compilation time
2+
--> $DIR/pretty-print-opaque-no-feat.rs:9:30
3+
|
4+
LL | let y: Box<dyn Tr> = x;
5+
| ^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `impl Tr + ?Sized`
8+
= note: required for the cast from `Box<impl Tr + ?Sized>` to `Box<dyn Tr>`
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//@ compile-flags: --crate-type=lib
2+
#![feature(sized_hierarchy)]
3+
4+
use std::marker::{MetaSized, PointeeSized};
5+
6+
pub trait Tr: PointeeSized {}
7+
impl Tr for u32 {}
8+
9+
pub fn sized() -> Box<impl Tr + Sized> {
10+
if true {
11+
let x = sized();
12+
let y: Box<dyn Tr> = x;
13+
}
14+
Box::new(1u32)
15+
}
16+
17+
pub fn neg_sized() -> Box<impl Tr + ?Sized> {
18+
if true {
19+
let x = neg_sized();
20+
let y: Box<dyn Tr> = x;
21+
//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known
22+
}
23+
Box::new(1u32)
24+
}
25+
26+
pub fn metasized() -> Box<impl Tr + MetaSized> {
27+
if true {
28+
let x = metasized();
29+
let y: Box<dyn Tr> = x;
30+
//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known
31+
}
32+
Box::new(1u32)
33+
}
34+
35+
pub fn pointeesized() -> Box<impl Tr + PointeeSized> {
36+
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
37+
if true {
38+
let x = pointeesized();
39+
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
40+
let y: Box<dyn Tr> = x;
41+
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
42+
}
43+
Box::new(1u32)
44+
}
45+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known
2+
--> $DIR/pretty-print-opaque.rs:35:26
3+
|
4+
LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
6+
|
7+
= help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
8+
note: required by a bound in `Box`
9+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
10+
11+
error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time
12+
--> $DIR/pretty-print-opaque.rs:20:30
13+
|
14+
LL | let y: Box<dyn Tr> = x;
15+
| ^ doesn't have a size known at compile-time
16+
|
17+
= help: the trait `Sized` is not implemented for `impl Tr + MetaSized`
18+
= note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>`
19+
20+
error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time
21+
--> $DIR/pretty-print-opaque.rs:29:30
22+
|
23+
LL | let y: Box<dyn Tr> = x;
24+
| ^ doesn't have a size known at compile-time
25+
|
26+
= help: the trait `Sized` is not implemented for `impl Tr + MetaSized`
27+
= note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>`
28+
29+
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known
30+
--> $DIR/pretty-print-opaque.rs:38:17
31+
|
32+
LL | let x = pointeesized();
33+
| ^^^^^^^^^^^^^^ doesn't have a known size
34+
|
35+
= help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
36+
note: required by a bound in `Box`
37+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
38+
39+
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time
40+
--> $DIR/pretty-print-opaque.rs:40:30
41+
|
42+
LL | let y: Box<dyn Tr> = x;
43+
| ^ doesn't have a size known at compile-time
44+
|
45+
= help: the trait `Sized` is not implemented for `impl Tr + PointeeSized`
46+
= note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>`
47+
48+
error: aborting due to 5 previous errors
49+
50+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)