Skip to content

Commit ff5cc43

Browse files
authored
Unrolled build for rust-lang#137863
Rollup merge of rust-lang#137863 - compiler-errors:unsafe-binder-render, r=oli-obk Fix pretty printing of unsafe binders We used to render `unsafe<> i32` as `i32`, and `unsafe<'a> &'a i32` as `for<'a> &'a i32`. r? oli-obk Review with whitespace b/c adding a new argument changes some the wrapping of some function calls.
2 parents 2010bba + a05a8c8 commit ff5cc43

File tree

5 files changed

+121
-42
lines changed

5 files changed

+121
-42
lines changed

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

+71-37
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ pub macro with_no_queries($e:expr) {{
133133
))
134134
}}
135135

136+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
137+
pub enum WrapBinderMode {
138+
ForAll,
139+
Unsafe,
140+
}
141+
impl WrapBinderMode {
142+
pub fn start_str(self) -> &'static str {
143+
match self {
144+
WrapBinderMode::ForAll => "for<",
145+
WrapBinderMode::Unsafe => "unsafe<",
146+
}
147+
}
148+
}
149+
136150
/// The "region highlights" are used to control region printing during
137151
/// specific error messages. When a "region highlight" is enabled, it
138152
/// gives an alternate way to print specific regions. For now, we
@@ -219,7 +233,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
219233
self.print_def_path(def_id, args)
220234
}
221235

222-
fn in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
236+
fn print_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
223237
where
224238
T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
225239
{
@@ -229,6 +243,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
229243
fn wrap_binder<T, F: FnOnce(&T, &mut Self) -> Result<(), fmt::Error>>(
230244
&mut self,
231245
value: &ty::Binder<'tcx, T>,
246+
_mode: WrapBinderMode,
232247
f: F,
233248
) -> Result<(), PrintError>
234249
where
@@ -703,8 +718,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
703718
}
704719
ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))),
705720
ty::UnsafeBinder(ref bound_ty) => {
706-
// FIXME(unsafe_binders): Make this print `unsafe<>` rather than `for<>`.
707-
self.wrap_binder(bound_ty, |ty, cx| cx.pretty_print_type(*ty))?;
721+
self.wrap_binder(bound_ty, WrapBinderMode::Unsafe, |ty, cx| {
722+
cx.pretty_print_type(*ty)
723+
})?;
708724
}
709725
ty::Infer(infer_ty) => {
710726
if self.should_print_verbose() {
@@ -1067,29 +1083,33 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10671083
};
10681084

10691085
if let Some(return_ty) = entry.return_ty {
1070-
self.wrap_binder(&bound_args_and_self_ty, |(args, _), cx| {
1071-
define_scoped_cx!(cx);
1072-
p!(write("{}", tcx.item_name(trait_def_id)));
1073-
p!("(");
1074-
1075-
for (idx, ty) in args.iter().enumerate() {
1076-
if idx > 0 {
1077-
p!(", ");
1086+
self.wrap_binder(
1087+
&bound_args_and_self_ty,
1088+
WrapBinderMode::ForAll,
1089+
|(args, _), cx| {
1090+
define_scoped_cx!(cx);
1091+
p!(write("{}", tcx.item_name(trait_def_id)));
1092+
p!("(");
1093+
1094+
for (idx, ty) in args.iter().enumerate() {
1095+
if idx > 0 {
1096+
p!(", ");
1097+
}
1098+
p!(print(ty));
10781099
}
1079-
p!(print(ty));
1080-
}
10811100

1082-
p!(")");
1083-
if let Some(ty) = return_ty.skip_binder().as_type() {
1084-
if !ty.is_unit() {
1085-
p!(" -> ", print(return_ty));
1101+
p!(")");
1102+
if let Some(ty) = return_ty.skip_binder().as_type() {
1103+
if !ty.is_unit() {
1104+
p!(" -> ", print(return_ty));
1105+
}
10861106
}
1087-
}
1088-
p!(write("{}", if paren_needed { ")" } else { "" }));
1107+
p!(write("{}", if paren_needed { ")" } else { "" }));
10891108

1090-
first = false;
1091-
Ok(())
1092-
})?;
1109+
first = false;
1110+
Ok(())
1111+
},
1112+
)?;
10931113
} else {
10941114
// Otherwise, render this like a regular trait.
10951115
traits.insert(
@@ -1110,7 +1130,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11101130
for (trait_pred, assoc_items) in traits {
11111131
write!(self, "{}", if first { "" } else { " + " })?;
11121132

1113-
self.wrap_binder(&trait_pred, |trait_pred, cx| {
1133+
self.wrap_binder(&trait_pred, WrapBinderMode::ForAll, |trait_pred, cx| {
11141134
define_scoped_cx!(cx);
11151135

11161136
if trait_pred.polarity == ty::PredicatePolarity::Negative {
@@ -1302,7 +1322,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
13021322
let mut first = true;
13031323

13041324
if let Some(bound_principal) = predicates.principal() {
1305-
self.wrap_binder(&bound_principal, |principal, cx| {
1325+
self.wrap_binder(&bound_principal, WrapBinderMode::ForAll, |principal, cx| {
13061326
define_scoped_cx!(cx);
13071327
p!(print_def_path(principal.def_id, &[]));
13081328

@@ -1927,7 +1947,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
19271947
let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
19281948

19291949
write!(self, "impl ")?;
1930-
self.wrap_binder(&sig, |sig, cx| {
1950+
self.wrap_binder(&sig, WrapBinderMode::ForAll, |sig, cx| {
19311951
define_scoped_cx!(cx);
19321952

19331953
p!(write("{kind}("));
@@ -2367,22 +2387,23 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
23672387
Ok(())
23682388
}
23692389

2370-
fn in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
2390+
fn print_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
23712391
where
23722392
T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
23732393
{
2374-
self.pretty_in_binder(value)
2394+
self.pretty_print_in_binder(value)
23752395
}
23762396

23772397
fn wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), PrintError>>(
23782398
&mut self,
23792399
value: &ty::Binder<'tcx, T>,
2400+
mode: WrapBinderMode,
23802401
f: C,
23812402
) -> Result<(), PrintError>
23822403
where
23832404
T: TypeFoldable<TyCtxt<'tcx>>,
23842405
{
2385-
self.pretty_wrap_binder(value, f)
2406+
self.pretty_wrap_binder(value, mode, f)
23862407
}
23872408

23882409
fn typed_value(
@@ -2632,6 +2653,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
26322653
pub fn name_all_regions<T>(
26332654
&mut self,
26342655
value: &ty::Binder<'tcx, T>,
2656+
mode: WrapBinderMode,
26352657
) -> Result<(T, UnordMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
26362658
where
26372659
T: TypeFoldable<TyCtxt<'tcx>>,
@@ -2705,9 +2727,13 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27052727
// anyways.
27062728
let (new_value, map) = if self.should_print_verbose() {
27072729
for var in value.bound_vars().iter() {
2708-
start_or_continue(self, "for<", ", ");
2730+
start_or_continue(self, mode.start_str(), ", ");
27092731
write!(self, "{var:?}")?;
27102732
}
2733+
// Unconditionally render `unsafe<>`.
2734+
if value.bound_vars().is_empty() && mode == WrapBinderMode::Unsafe {
2735+
start_or_continue(self, mode.start_str(), "");
2736+
}
27112737
start_or_continue(self, "", "> ");
27122738
(value.clone().skip_binder(), UnordMap::default())
27132739
} else {
@@ -2772,8 +2798,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27722798
}
27732799
};
27742800

2775-
if !trim_path {
2776-
start_or_continue(self, "for<", ", ");
2801+
// Unconditionally render `unsafe<>`.
2802+
if !trim_path || mode == WrapBinderMode::Unsafe {
2803+
start_or_continue(self, mode.start_str(), ", ");
27772804
do_continue(self, name);
27782805
}
27792806
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion { var: br.var, kind })
@@ -2786,9 +2813,12 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27862813
};
27872814
let new_value = value.clone().skip_binder().fold_with(&mut folder);
27882815
let region_map = folder.region_map;
2789-
if !trim_path {
2790-
start_or_continue(self, "", "> ");
2816+
2817+
if mode == WrapBinderMode::Unsafe && region_map.is_empty() {
2818+
start_or_continue(self, mode.start_str(), "");
27912819
}
2820+
start_or_continue(self, "", "> ");
2821+
27922822
(new_value, region_map)
27932823
};
27942824

@@ -2797,12 +2827,15 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27972827
Ok((new_value, map))
27982828
}
27992829

2800-
pub fn pretty_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), fmt::Error>
2830+
pub fn pretty_print_in_binder<T>(
2831+
&mut self,
2832+
value: &ty::Binder<'tcx, T>,
2833+
) -> Result<(), fmt::Error>
28012834
where
28022835
T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
28032836
{
28042837
let old_region_index = self.region_index;
2805-
let (new_value, _) = self.name_all_regions(value)?;
2838+
let (new_value, _) = self.name_all_regions(value, WrapBinderMode::ForAll)?;
28062839
new_value.print(self)?;
28072840
self.region_index = old_region_index;
28082841
self.binder_depth -= 1;
@@ -2812,13 +2845,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
28122845
pub fn pretty_wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), fmt::Error>>(
28132846
&mut self,
28142847
value: &ty::Binder<'tcx, T>,
2848+
mode: WrapBinderMode,
28152849
f: C,
28162850
) -> Result<(), fmt::Error>
28172851
where
28182852
T: TypeFoldable<TyCtxt<'tcx>>,
28192853
{
28202854
let old_region_index = self.region_index;
2821-
let (new_value, _) = self.name_all_regions(value)?;
2855+
let (new_value, _) = self.name_all_regions(value, mode)?;
28222856
f(&new_value, self)?;
28232857
self.region_index = old_region_index;
28242858
self.binder_depth -= 1;
@@ -2877,7 +2911,7 @@ where
28772911
T: Print<'tcx, P> + TypeFoldable<TyCtxt<'tcx>>,
28782912
{
28792913
fn print(&self, cx: &mut P) -> Result<(), PrintError> {
2880-
cx.in_binder(self)
2914+
cx.print_in_binder(self)
28812915
}
28822916
}
28832917

compiler/rustc_symbol_mangling/src/v0.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ impl<'tcx> SymbolMangler<'tcx> {
169169
Ok(())
170170
}
171171

172-
fn in_binder<T>(
172+
fn wrap_binder<T>(
173173
&mut self,
174174
value: &ty::Binder<'tcx, T>,
175175
print_value: impl FnOnce(&mut Self, &T) -> Result<(), PrintError>,
@@ -471,7 +471,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
471471
ty::FnPtr(sig_tys, hdr) => {
472472
let sig = sig_tys.with(hdr);
473473
self.push("F");
474-
self.in_binder(&sig, |cx, sig| {
474+
self.wrap_binder(&sig, |cx, sig| {
475475
if sig.safety.is_unsafe() {
476476
cx.push("U");
477477
}
@@ -554,7 +554,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
554554
// [<Trait> [{<Projection>}]] [{<Auto>}]
555555
// Since any predicates after the first one shouldn't change the binders,
556556
// just put them all in the binders of the first.
557-
self.in_binder(&predicates[0], |cx, _| {
557+
self.wrap_binder(&predicates[0], |cx, _| {
558558
for predicate in predicates.iter() {
559559
// It would be nice to be able to validate bound vars here, but
560560
// projections can actually include bound vars from super traits

compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ use rustc_middle::bug;
6565
use rustc_middle::dep_graph::DepContext;
6666
use rustc_middle::traits::PatternOriginExpr;
6767
use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt};
68-
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, with_forced_trimmed_paths};
68+
use rustc_middle::ty::print::{
69+
PrintError, PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths,
70+
};
6971
use rustc_middle::ty::{
7072
self, List, ParamEnv, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
7173
TypeVisitableExt,
@@ -835,7 +837,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
835837
let get_lifetimes = |sig| {
836838
use rustc_hir::def::Namespace;
837839
let (sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS)
838-
.name_all_regions(sig)
840+
.name_all_regions(sig, WrapBinderMode::ForAll)
839841
.unwrap();
840842
let lts: Vec<String> =
841843
reg.into_items().map(|(_, kind)| kind.to_string()).into_sorted_stable_ord();
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(unsafe_binders)]
2+
//~^ WARN the feature `unsafe_binders` is incomplete
3+
4+
fn main() {
5+
let x: unsafe<> i32 = 0;
6+
//~^ ERROR mismatched types
7+
let x: unsafe<'a> &'a i32 = &0;
8+
//~^ ERROR mismatched types
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/type-mismatch.rs:1:12
3+
|
4+
LL | #![feature(unsafe_binders)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0308]: mismatched types
11+
--> $DIR/type-mismatch.rs:5:27
12+
|
13+
LL | let x: unsafe<> i32 = 0;
14+
| ------------ ^ expected `unsafe<> i32`, found integer
15+
| |
16+
| expected due to this
17+
|
18+
= note: expected unsafe binder `unsafe<> i32`
19+
found type `{integer}`
20+
21+
error[E0308]: mismatched types
22+
--> $DIR/type-mismatch.rs:7:33
23+
|
24+
LL | let x: unsafe<'a> &'a i32 = &0;
25+
| ------------------ ^^ expected `unsafe<'a> &i32`, found `&{integer}`
26+
| |
27+
| expected due to this
28+
|
29+
= note: expected unsafe binder `unsafe<'a> &'a i32`
30+
found reference `&{integer}`
31+
32+
error: aborting due to 2 previous errors; 1 warning emitted
33+
34+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)