Skip to content

Commit 306ca37

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 67b4966 commit 306ca37

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
@@ -1018,16 +1018,20 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10181018

10191019
let mut traits = FxIndexMap::default();
10201020
let mut fn_traits = FxIndexMap::default();
1021+
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
1022+
10211023
let mut has_sized_bound = false;
10221024
let mut has_negative_sized_bound = false;
1023-
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
1025+
let mut has_metasized_bound = false;
1026+
let mut has_pointeesized_bound = false;
10241027

10251028
for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) {
10261029
let bound_predicate = predicate.kind();
10271030

10281031
match bound_predicate.skip_binder() {
10291032
ty::ClauseKind::Trait(pred) => {
1030-
// Don't print `+ Sized`, but rather `+ ?Sized` if absent.
1033+
// With `feature(sized_hierarchy)`, don't print `?Sized` as an alias for
1034+
// `MetaSized`, and skip sizedness bounds to be added at the end.
10311035
if tcx.is_lang_item(pred.def_id(), LangItem::Sized) {
10321036
match pred.polarity {
10331037
ty::PredicatePolarity::Positive => {
@@ -1036,6 +1040,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10361040
}
10371041
ty::PredicatePolarity::Negative => has_negative_sized_bound = true,
10381042
}
1043+
} else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) {
1044+
has_metasized_bound = true;
1045+
continue;
1046+
} else if tcx.is_lang_item(pred.def_id(), LangItem::PointeeSized) {
1047+
// Unexpected - `PointeeSized` is the absence of bounds.
1048+
has_pointeesized_bound = true;
1049+
continue;
10391050
}
10401051

10411052
self.insert_trait_and_projection(
@@ -1204,8 +1215,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
12041215
})?;
12051216
}
12061217

1218+
let using_sized_hierarchy = self.tcx().features().sized_hierarchy();
12071219
let add_sized = has_sized_bound && (first || has_negative_sized_bound);
1208-
let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound;
1220+
let add_maybe_sized = has_metasized_bound && !has_negative_sized_bound && !using_sized_hierarchy;
1221+
// Set `has_pointeesized_bound` if there were no `Sized` or `MetaSized` bounds.
1222+
has_pointeesized_bound = has_pointeesized_bound || (!has_sized_bound && !has_metasized_bound && !has_negative_sized_bound);
12091223
if add_sized || add_maybe_sized {
12101224
if !first {
12111225
write!(self, " + ")?;
@@ -1214,6 +1228,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
12141228
write!(self, "?")?;
12151229
}
12161230
write!(self, "Sized")?;
1231+
} else if has_metasized_bound && using_sized_hierarchy {
1232+
if !first {
1233+
write!(self, " + ")?;
1234+
}
1235+
write!(self, "MetaSized")?;
1236+
} else if has_pointeesized_bound && using_sized_hierarchy {
1237+
if !first {
1238+
write!(self, " + ")?;
1239+
}
1240+
write!(self, "PointeeSized")?;
12171241
}
12181242

12191243
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)