Skip to content

Commit 8b70583

Browse files
committed
Auto merge of #102324 - matthiaskrgr:rollup-6l70oz3, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #101875 (Allow more `!Copy` impls) - #101996 (Don't duplicate region names for late-bound regions in print of Binder) - #102181 (Add regression test) - #102273 (Allow `~const` bounds on non-const functions) - #102286 (Recover some items that expect braces and don't take semicolons) Failed merges: - #102314 (Add a label to struct/enum/union ident name) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1d1f142 + 6f5e8c2 commit 8b70583

File tree

132 files changed

+544
-309
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+544
-309
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14151415
if !self.is_tilde_const_allowed {
14161416
self.err_handler()
14171417
.struct_span_err(bound.span(), "`~const` is not allowed here")
1418-
.note("only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions")
1418+
.note("only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions")
14191419
.emit();
14201420
}
14211421
}
@@ -1523,9 +1523,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15231523
});
15241524
}
15251525

1526-
let tilde_const_allowed =
1527-
matches!(fk.header(), Some(FnHeader { constness: Const::Yes(_), .. }))
1528-
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
1526+
let tilde_const_allowed = matches!(fk.header(), Some(FnHeader { .. }))
1527+
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
15291528

15301529
self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk));
15311530
}

compiler/rustc_error_messages/locales/en-US/parser.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,6 @@ parser_remove_let = expected pattern, found `let`
158158
159159
parser_use_eq_instead = unexpected `==`
160160
.suggestion = try using `=` instead
161+
162+
parser_use_empty_block_not_semi = expected { "`{}`" }, found `;`
163+
.suggestion = try using { "`{}`" } instead

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

+54-27
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,9 @@ pub struct FmtPrinterData<'a, 'tcx> {
15621562
in_value: bool,
15631563
pub print_alloc_ids: bool,
15641564

1565+
// set of all named (non-anonymous) region names
15651566
used_region_names: FxHashSet<Symbol>,
1567+
15661568
region_index: usize,
15671569
binder_depth: usize,
15681570
printed_type_count: usize,
@@ -2118,23 +2120,31 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21182120
where
21192121
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
21202122
{
2121-
fn name_by_region_index(index: usize) -> Symbol {
2122-
match index {
2123-
0 => Symbol::intern("'r"),
2124-
1 => Symbol::intern("'s"),
2125-
i => Symbol::intern(&format!("'t{}", i - 2)),
2123+
fn name_by_region_index(
2124+
index: usize,
2125+
available_names: &mut Vec<Symbol>,
2126+
num_available: usize,
2127+
) -> Symbol {
2128+
if let Some(name) = available_names.pop() {
2129+
name
2130+
} else {
2131+
Symbol::intern(&format!("'z{}", index - num_available))
21262132
}
21272133
}
21282134

2135+
debug!("name_all_regions");
2136+
21292137
// Replace any anonymous late-bound regions with named
21302138
// variants, using new unique identifiers, so that we can
21312139
// clearly differentiate between named and unnamed regions in
21322140
// the output. We'll probably want to tweak this over time to
21332141
// decide just how much information to give.
21342142
if self.binder_depth == 0 {
2135-
self.prepare_late_bound_region_info(value);
2143+
self.prepare_region_info(value);
21362144
}
21372145

2146+
debug!("self.used_region_names: {:?}", &self.used_region_names);
2147+
21382148
let mut empty = true;
21392149
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
21402150
let w = if empty {
@@ -2151,13 +2161,24 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21512161

21522162
define_scoped_cx!(self);
21532163

2164+
let possible_names =
2165+
('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}"))).collect::<Vec<_>>();
2166+
2167+
let mut available_names = possible_names
2168+
.into_iter()
2169+
.filter(|name| !self.used_region_names.contains(&name))
2170+
.collect::<Vec<_>>();
2171+
debug!(?available_names);
2172+
let num_available = available_names.len();
2173+
21542174
let mut region_index = self.region_index;
2155-
let mut next_name = |this: &Self| loop {
2156-
let name = name_by_region_index(region_index);
2175+
let mut next_name = |this: &Self| {
2176+
let name = name_by_region_index(region_index, &mut available_names, num_available);
2177+
debug!(?name);
21572178
region_index += 1;
2158-
if !this.used_region_names.contains(&name) {
2159-
break name;
2160-
}
2179+
assert!(!this.used_region_names.contains(&name));
2180+
2181+
name
21612182
};
21622183

21632184
// If we want to print verbosely, then print *all* binders, even if they
@@ -2178,6 +2199,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21782199
ty::BrAnon(_) | ty::BrEnv => {
21792200
start_or_continue(&mut self, "for<", ", ");
21802201
let name = next_name(&self);
2202+
debug!(?name);
21812203
do_continue(&mut self, name);
21822204
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
21832205
}
@@ -2271,29 +2293,37 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22712293
Ok(inner)
22722294
}
22732295

2274-
fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
2296+
fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
22752297
where
22762298
T: TypeVisitable<'tcx>,
22772299
{
2278-
struct LateBoundRegionNameCollector<'a, 'tcx> {
2279-
used_region_names: &'a mut FxHashSet<Symbol>,
2300+
struct RegionNameCollector<'tcx> {
2301+
used_region_names: FxHashSet<Symbol>,
22802302
type_collector: SsoHashSet<Ty<'tcx>>,
22812303
}
22822304

2283-
impl<'tcx> ty::visit::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_, 'tcx> {
2305+
impl<'tcx> RegionNameCollector<'tcx> {
2306+
fn new() -> Self {
2307+
RegionNameCollector {
2308+
used_region_names: Default::default(),
2309+
type_collector: SsoHashSet::new(),
2310+
}
2311+
}
2312+
}
2313+
2314+
impl<'tcx> ty::visit::TypeVisitor<'tcx> for RegionNameCollector<'tcx> {
22842315
type BreakTy = ();
22852316

22862317
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
22872318
trace!("address: {:p}", r.0.0);
2288-
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
2289-
self.used_region_names.insert(name);
2290-
} else if let ty::RePlaceholder(ty::PlaceholderRegion {
2291-
name: ty::BrNamed(_, name),
2292-
..
2293-
}) = *r
2294-
{
2319+
2320+
// Collect all named lifetimes. These allow us to prevent duplication
2321+
// of already existing lifetime names when introducing names for
2322+
// anonymous late-bound regions.
2323+
if let Some(name) = r.get_name() {
22952324
self.used_region_names.insert(name);
22962325
}
2326+
22972327
r.super_visit_with(self)
22982328
}
22992329

@@ -2309,12 +2339,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
23092339
}
23102340
}
23112341

2312-
self.used_region_names.clear();
2313-
let mut collector = LateBoundRegionNameCollector {
2314-
used_region_names: &mut self.used_region_names,
2315-
type_collector: SsoHashSet::new(),
2316-
};
2342+
let mut collector = RegionNameCollector::new();
23172343
value.visit_with(&mut collector);
2344+
self.used_region_names = collector.used_region_names;
23182345
self.region_index = 0;
23192346
}
23202347
}

compiler/rustc_middle/src/ty/sty.rs

+28
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ impl BoundRegionKind {
8585
_ => false,
8686
}
8787
}
88+
89+
pub fn get_name(&self) -> Option<Symbol> {
90+
if self.is_named() {
91+
match *self {
92+
BoundRegionKind::BrNamed(_, name) => return Some(name),
93+
_ => unreachable!(),
94+
}
95+
}
96+
97+
None
98+
}
8899
}
89100

90101
pub trait Article {
@@ -1445,6 +1456,23 @@ impl<'tcx> Region<'tcx> {
14451456
*self.0.0
14461457
}
14471458

1459+
pub fn get_name(self) -> Option<Symbol> {
1460+
if self.has_name() {
1461+
let name = match *self {
1462+
ty::ReEarlyBound(ebr) => Some(ebr.name),
1463+
ty::ReLateBound(_, br) => br.kind.get_name(),
1464+
ty::ReFree(fr) => fr.bound_region.get_name(),
1465+
ty::ReStatic => Some(kw::StaticLifetime),
1466+
ty::RePlaceholder(placeholder) => placeholder.name.get_name(),
1467+
_ => None,
1468+
};
1469+
1470+
return name;
1471+
}
1472+
1473+
None
1474+
}
1475+
14481476
/// Is this region named by the user?
14491477
pub fn has_name(self) -> bool {
14501478
match *self {

compiler/rustc_parse/src/parser/diagnostics.rs

+8
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,14 @@ pub(crate) struct UseEqInstead {
745745
pub span: Span,
746746
}
747747

748+
#[derive(Diagnostic)]
749+
#[diag(parser::use_empty_block_not_semi)]
750+
pub(crate) struct UseEmptyBlockNotSemi {
751+
#[primary_span]
752+
#[suggestion_hidden(applicability = "machine-applicable", code = "{{}}")]
753+
pub span: Span,
754+
}
755+
748756
// SnapshotParser is used to create a snapshot of the parser
749757
// without causing duplicate errors being emitted when the `Parser`
750758
// is dropped.

compiler/rustc_parse/src/parser/item.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
1+
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error, UseEmptyBlockNotSemi};
22
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
33
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
44

@@ -664,6 +664,14 @@ impl<'a> Parser<'a> {
664664
mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>,
665665
) -> PResult<'a, Vec<T>> {
666666
let open_brace_span = self.token.span;
667+
668+
// Recover `impl Ty;` instead of `impl Ty {}`
669+
if self.token == TokenKind::Semi {
670+
self.sess.emit_err(UseEmptyBlockNotSemi { span: self.token.span });
671+
self.bump();
672+
return Ok(vec![]);
673+
}
674+
667675
self.expect(&token::OpenDelim(Delimiter::Brace))?;
668676
attrs.extend(self.parse_inner_attributes()?);
669677

@@ -1305,12 +1313,19 @@ impl<'a> Parser<'a> {
13051313
let mut generics = self.parse_generics()?;
13061314
generics.where_clause = self.parse_where_clause()?;
13071315

1308-
let (variants, _) = self
1309-
.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant())
1310-
.map_err(|e| {
1311-
self.recover_stmt();
1312-
e
1313-
})?;
1316+
// Possibly recover `enum Foo;` instead of `enum Foo {}`
1317+
let (variants, _) = if self.token == TokenKind::Semi {
1318+
self.sess.emit_err(UseEmptyBlockNotSemi { span: self.token.span });
1319+
self.bump();
1320+
(vec![], false)
1321+
} else {
1322+
self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err(
1323+
|e| {
1324+
self.recover_stmt();
1325+
e
1326+
},
1327+
)?
1328+
};
13141329

13151330
let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
13161331
Ok((id, ItemKind::Enum(enum_definition, generics)))

compiler/rustc_typeck/src/coherence/builtin.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,21 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
7070
let self_type = tcx.type_of(impl_did);
7171
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
7272

73-
let span = tcx.hir().span(impl_hir_id);
7473
let param_env = tcx.param_env(impl_did);
7574
assert!(!self_type.has_escaping_bound_vars());
7675

7776
debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
7877

78+
let span = match tcx.hir().expect_item(impl_did).kind {
79+
ItemKind::Impl(hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. }) => return,
80+
ItemKind::Impl(impl_) => impl_.self_ty.span,
81+
_ => bug!("expected Copy impl item"),
82+
};
83+
7984
let cause = traits::ObligationCause::misc(span, impl_hir_id);
8085
match can_type_implement_copy(tcx, param_env, self_type, cause) {
8186
Ok(()) => {}
8287
Err(CopyImplementationError::InfrigingFields(fields)) => {
83-
let item = tcx.hir().expect_item(impl_did);
84-
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref tr), .. }) = item.kind {
85-
tr.path.span
86-
} else {
87-
span
88-
};
89-
9088
let mut err = struct_span_err!(
9189
tcx.sess,
9290
span,
@@ -166,10 +164,6 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
166164
err.emit();
167165
}
168166
Err(CopyImplementationError::NotAnAdt) => {
169-
let item = tcx.hir().expect_item(impl_did);
170-
let span =
171-
if let ItemKind::Impl(ref impl_) = item.kind { impl_.self_ty.span } else { span };
172-
173167
tcx.sess.emit_err(CopyImplOnNonAdt { span });
174168
}
175169
Err(CopyImplementationError::HasDestructor) => {

src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
_2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
2525
// mir::Constant
2626
// + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9
27-
// + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
27+
// + literal: Const { ty: for<'a> fn(&'a T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
2828
}
2929

3030
bb1: {
@@ -37,7 +37,7 @@
3737
- _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
3838
- // mir::Constant
3939
- // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11
40-
- // + literal: Const { ty: for<'r> fn(&'r u64) -> u64 {<u64 as Clone>::clone}, val: Value(<ZST>) }
40+
- // + literal: Const { ty: for<'a> fn(&'a u64) -> u64 {<u64 as Clone>::clone}, val: Value(<ZST>) }
4141
+ _6 = _7; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
4242
+ _5 = (*_6); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
4343
+ goto -> bb2; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
@@ -53,7 +53,7 @@
5353
- _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
5454
- // mir::Constant
5555
- // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16
56-
- // + literal: Const { ty: for<'r> fn(&'r [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(<ZST>) }
56+
- // + literal: Const { ty: for<'a> fn(&'a [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(<ZST>) }
5757
+ _9 = _10; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
5858
+ _8 = (*_9); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
5959
+ goto -> bb3; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16

src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
_0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
3434
// mir::Constant
3535
// + span: $DIR/const-promotion-extern-static.rs:9:36: 9:42
36-
// + literal: Const { ty: for<'r> fn(&'r [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
36+
// + literal: Const { ty: for<'a> fn(&'a [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
3737
}
3838

3939
bb1: {

src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
_0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
3636
// mir::Constant
3737
// + span: $DIR/const-promotion-extern-static.rs:13:47: 13:53
38-
// + literal: Const { ty: for<'r> fn(&'r [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
38+
// + literal: Const { ty: for<'a> fn(&'a [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
3939
}
4040

4141
bb1: {

src/test/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
_2 = core::str::<impl str>::as_bytes(move _3) -> bb1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23
2121
// mir::Constant
2222
// + span: $DIR/deduplicate_blocks.rs:5:13: 5:21
23-
// + literal: Const { ty: for<'r> fn(&'r str) -> &'r [u8] {core::str::<impl str>::as_bytes}, val: Value(<ZST>) }
23+
// + literal: Const { ty: for<'a> fn(&'a str) -> &'a [u8] {core::str::<impl str>::as_bytes}, val: Value(<ZST>) }
2424
}
2525

2626
bb1: {

src/test/mir-opt/derefer_complex_case.main.Derefer.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
_7 = <std::slice::Iter<'_, i32> as Iterator>::next(move _8) -> bb3; // scope 1 at $DIR/derefer_complex_case.rs:+1:17: +1:26
5757
// mir::Constant
5858
// + span: $DIR/derefer_complex_case.rs:6:17: 6:26
59-
// + literal: Const { ty: for<'r> fn(&'r mut std::slice::Iter<'_, i32>) -> Option<<std::slice::Iter<'_, i32> as Iterator>::Item> {<std::slice::Iter<'_, i32> as Iterator>::next}, val: Value(<ZST>) }
59+
// + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, i32>) -> Option<<std::slice::Iter<'_, i32> as Iterator>::Item> {<std::slice::Iter<'_, i32> as Iterator>::next}, val: Value(<ZST>) }
6060
}
6161

6262
bb3: {

0 commit comments

Comments
 (0)