Skip to content

Commit 44e9516

Browse files
committed
Auto merge of #97654 - Dylan-DPC:rollup-w6zrzxf, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #97420 (Be a little nicer with casts when formatting `fn` pointers) - #97450 ([RFC 2011] Basic compiler infrastructure) - #97599 (Fix JSON reexport ICE) - #97617 (Rustdoc anonymous reexports) - #97636 (Revert #96682.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 20976ba + 1d71237 commit 44e9516

31 files changed

+336
-208
lines changed

compiler/rustc_ast/src/token.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,11 @@ pub enum Delimiter {
5050
Brace,
5151
/// `[ ... ]`
5252
Bracket,
53-
/// `/*«*/ ... /*»*/`
53+
/// `Ø ... Ø`
5454
/// An invisible delimiter, that may, for example, appear around tokens coming from a
5555
/// "macro variable" `$var`. It is important to preserve operator priorities in cases like
5656
/// `$var * 3` where `$var` is `1 + 2`.
57-
/// Invisible delimiters are not directly writable in normal Rust code except as comments.
58-
/// Therefore, they might not survive a roundtrip of a token stream through a string.
57+
/// Invisible delimiters might not survive roundtrip of a token stream through a string.
5958
Invisible,
6059
}
6160

compiler/rustc_ast_pretty/src/pprust/state.rs

+5-18
Original file line numberDiff line numberDiff line change
@@ -590,28 +590,14 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
590590
self.nbsp();
591591
}
592592
self.word("{");
593-
let empty = tts.is_empty();
594-
if !empty {
593+
if !tts.is_empty() {
595594
self.space();
596595
}
597596
self.ibox(0);
598597
self.print_tts(tts, convert_dollar_crate);
599598
self.end();
600-
self.bclose(span, empty);
601-
}
602-
Some(Delimiter::Invisible) => {
603-
self.word("/*«*/");
604599
let empty = tts.is_empty();
605-
if !empty {
606-
self.space();
607-
}
608-
self.ibox(0);
609-
self.print_tts(tts, convert_dollar_crate);
610-
self.end();
611-
if !empty {
612-
self.space();
613-
}
614-
self.word("/*»*/");
600+
self.bclose(span, empty);
615601
}
616602
Some(delim) => {
617603
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
@@ -786,8 +772,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
786772
token::CloseDelim(Delimiter::Bracket) => "]".into(),
787773
token::OpenDelim(Delimiter::Brace) => "{".into(),
788774
token::CloseDelim(Delimiter::Brace) => "}".into(),
789-
token::OpenDelim(Delimiter::Invisible) => "/*«*/".into(),
790-
token::CloseDelim(Delimiter::Invisible) => "/*»*/".into(),
775+
token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible) => {
776+
"".into()
777+
}
791778
token::Pound => "#".into(),
792779
token::Dollar => "$".into(),
793780
token::Question => "?".into(),

compiler/rustc_builtin_macros/src/assert.rs

+48-22
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
mod context;
2+
13
use crate::edition_panic::use_panic_2021;
24
use rustc_ast::ptr::P;
35
use rustc_ast::token;
46
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
5-
use rustc_ast::{self as ast, *};
7+
use rustc_ast::{Expr, ExprKind, MacArgs, MacCall, MacDelimiter, Path, PathSegment, UnOp};
68
use rustc_ast_pretty::pprust;
79
use rustc_errors::{Applicability, PResult};
8-
use rustc_expand::base::*;
10+
use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
911
use rustc_parse::parser::Parser;
1012
use rustc_span::symbol::{sym, Ident, Symbol};
1113
use rustc_span::{Span, DUMMY_SP};
@@ -25,13 +27,13 @@ pub fn expand_assert<'cx>(
2527

2628
// `core::panic` and `std::panic` are different macros, so we use call-site
2729
// context to pick up whichever is currently in scope.
28-
let sp = cx.with_call_site_ctxt(span);
30+
let call_site_span = cx.with_call_site_ctxt(span);
2931

30-
let panic_call = if let Some(tokens) = custom_message {
31-
let path = if use_panic_2021(span) {
32+
let panic_path = || {
33+
if use_panic_2021(span) {
3234
// On edition 2021, we always call `$crate::panic::panic_2021!()`.
3335
Path {
34-
span: sp,
36+
span: call_site_span,
3537
segments: cx
3638
.std_path(&[sym::panic, sym::panic_2021])
3739
.into_iter()
@@ -42,27 +44,40 @@ pub fn expand_assert<'cx>(
4244
} else {
4345
// Before edition 2021, we call `panic!()` unqualified,
4446
// such that it calls either `std::panic!()` or `core::panic!()`.
45-
Path::from_ident(Ident::new(sym::panic, sp))
46-
};
47-
// Pass the custom message to panic!().
48-
cx.expr(
49-
sp,
47+
Path::from_ident(Ident::new(sym::panic, call_site_span))
48+
}
49+
};
50+
51+
// Simply uses the user provided message instead of generating custom outputs
52+
let expr = if let Some(tokens) = custom_message {
53+
let then = cx.expr(
54+
call_site_span,
5055
ExprKind::MacCall(MacCall {
51-
path,
56+
path: panic_path(),
5257
args: P(MacArgs::Delimited(
53-
DelimSpan::from_single(sp),
58+
DelimSpan::from_single(call_site_span),
5459
MacDelimiter::Parenthesis,
5560
tokens,
5661
)),
5762
prior_type_ascription: None,
5863
}),
59-
)
60-
} else {
64+
);
65+
expr_if_not(cx, call_site_span, cond_expr, then, None)
66+
}
67+
// If `generic_assert` is enabled, generates rich captured outputs
68+
//
69+
// FIXME(c410-f3r) See https://github.com/rust-lang/rust/issues/96949
70+
else if let Some(features) = cx.ecfg.features && features.generic_assert {
71+
context::Context::new(cx, call_site_span).build(cond_expr, panic_path())
72+
}
73+
// If `generic_assert` is not enabled, only outputs a literal "assertion failed: ..."
74+
// string
75+
else {
6176
// Pass our own message directly to $crate::panicking::panic(),
6277
// because it might contain `{` and `}` that should always be
6378
// passed literally.
64-
cx.expr_call_global(
65-
sp,
79+
let then = cx.expr_call_global(
80+
call_site_span,
6681
cx.std_path(&[sym::panicking, sym::panic]),
6782
vec![cx.expr_str(
6883
DUMMY_SP,
@@ -71,18 +86,29 @@ pub fn expand_assert<'cx>(
7186
pprust::expr_to_string(&cond_expr).escape_debug()
7287
)),
7388
)],
74-
)
89+
);
90+
expr_if_not(cx, call_site_span, cond_expr, then, None)
7591
};
76-
let if_expr =
77-
cx.expr_if(sp, cx.expr(sp, ExprKind::Unary(UnOp::Not, cond_expr)), panic_call, None);
78-
MacEager::expr(if_expr)
92+
93+
MacEager::expr(expr)
7994
}
8095

8196
struct Assert {
82-
cond_expr: P<ast::Expr>,
97+
cond_expr: P<Expr>,
8398
custom_message: Option<TokenStream>,
8499
}
85100

101+
// if !{ ... } { ... } else { ... }
102+
fn expr_if_not(
103+
cx: &ExtCtxt<'_>,
104+
span: Span,
105+
cond: P<Expr>,
106+
then: P<Expr>,
107+
els: Option<P<Expr>>,
108+
) -> P<Expr> {
109+
cx.expr_if(span, cx.expr(span, ExprKind::Unary(UnOp::Not, cond)), then, els)
110+
}
111+
86112
fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<'a, Assert> {
87113
let mut parser = cx.new_parser_from_tts(stream);
88114

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use rustc_ast::{ptr::P, Expr, Path};
2+
use rustc_expand::base::ExtCtxt;
3+
use rustc_span::Span;
4+
5+
pub(super) struct Context<'cx, 'a> {
6+
cx: &'cx ExtCtxt<'a>,
7+
span: Span,
8+
}
9+
10+
impl<'cx, 'a> Context<'cx, 'a> {
11+
pub(super) fn new(cx: &'cx ExtCtxt<'a>, span: Span) -> Self {
12+
Self { cx, span }
13+
}
14+
15+
/// Builds the whole `assert!` expression.
16+
///
17+
/// {
18+
/// use ::core::asserting::{ ... };
19+
///
20+
/// let mut __capture0 = Capture::new();
21+
/// ...
22+
/// ...
23+
/// ...
24+
///
25+
/// if !{
26+
/// ...
27+
/// ...
28+
/// ...
29+
/// } {
30+
/// panic!(
31+
/// "Assertion failed: ... \n With expansion: ...",
32+
/// __capture0,
33+
/// ...
34+
/// ...
35+
/// ...
36+
/// );
37+
/// }
38+
/// }
39+
pub(super) fn build(self, _cond_expr: P<Expr>, _panic_path: Path) -> P<Expr> {
40+
let Self { cx, span, .. } = self;
41+
let stmts = Vec::new();
42+
cx.expr_block(cx.block(span, stmts))
43+
}
44+
}

compiler/rustc_builtin_macros/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
//! This crate contains implementations of built-in macros and other code generating facilities
22
//! injecting code into the crate before it is lowered to HIR.
33
4+
#![allow(rustc::potential_query_instability)]
45
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
56
#![feature(array_windows)]
67
#![feature(box_patterns)]
78
#![feature(decl_macro)]
89
#![feature(is_sorted)]
9-
#![feature(nll)]
10+
#![feature(let_chains)]
1011
#![feature(let_else)]
12+
#![feature(nll)]
1113
#![feature(proc_macro_internals)]
1214
#![feature(proc_macro_quote)]
1315
#![recursion_limit = "256"]
14-
#![allow(rustc::potential_query_instability)]
1516

1617
extern crate proc_macro;
1718

compiler/rustc_expand/src/build.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl<'a> ExtCtxt<'a> {
160160
attrs: AttrVec::new(),
161161
tokens: None,
162162
});
163-
ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp }
163+
self.stmt_local(local, sp)
164164
}
165165

166166
// Generates `let _: Type;`, which is usually used for type assertions.
@@ -174,6 +174,10 @@ impl<'a> ExtCtxt<'a> {
174174
attrs: AttrVec::new(),
175175
tokens: None,
176176
});
177+
self.stmt_local(local, span)
178+
}
179+
180+
pub fn stmt_local(&self, local: P<ast::Local>, span: Span) -> ast::Stmt {
177181
ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span }
178182
}
179183

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ declare_features! (
150150
(active, allow_internal_unstable, "1.0.0", None, None),
151151
/// Allows identifying the `compiler_builtins` crate.
152152
(active, compiler_builtins, "1.13.0", None, None),
153+
/// Outputs useful `assert!` messages
154+
(active, generic_assert, "1.63.0", None, None),
153155
/// Allows using the `rust-intrinsic`'s "ABI".
154156
(active, intrinsics, "1.0.0", None, None),
155157
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ symbols! {
733733
generator_state,
734734
generators,
735735
generic_arg_infer,
736+
generic_assert,
736737
generic_associated_types,
737738
generic_associated_types_extended,
738739
generic_const_exprs,

library/core/src/fmt/mod.rs

+30-24
Original file line numberDiff line numberDiff line change
@@ -2233,35 +2233,41 @@ impl Display for char {
22332233
#[stable(feature = "rust1", since = "1.0.0")]
22342234
impl<T: ?Sized> Pointer for *const T {
22352235
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
2236-
/// Since the formatting will be identical for all pointer types, use a non-monomorphized
2237-
/// implementation for the actual formatting to reduce the amount of codegen work needed
2238-
fn inner(ptr: *const (), f: &mut Formatter<'_>) -> Result {
2239-
let old_width = f.width;
2240-
let old_flags = f.flags;
2241-
2242-
// The alternate flag is already treated by LowerHex as being special-
2243-
// it denotes whether to prefix with 0x. We use it to work out whether
2244-
// or not to zero extend, and then unconditionally set it to get the
2245-
// prefix.
2246-
if f.alternate() {
2247-
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
2248-
2249-
if f.width.is_none() {
2250-
f.width = Some((usize::BITS / 4) as usize + 2);
2251-
}
2252-
}
2253-
f.flags |= 1 << (FlagV1::Alternate as u32);
2236+
// Cast is needed here because `.addr()` requires `T: Sized`.
2237+
pointer_fmt_inner((*self as *const ()).addr(), f)
2238+
}
2239+
}
22542240

2255-
let ret = LowerHex::fmt(&(ptr.addr()), f);
2241+
/// Since the formatting will be identical for all pointer types, use a non-monomorphized
2242+
/// implementation for the actual formatting to reduce the amount of codegen work needed.
2243+
///
2244+
/// This uses `ptr_addr: usize` and not `ptr: *const ()` to be able to use this for
2245+
/// `fn(...) -> ...` without using [problematic] "Oxford Casts".
2246+
///
2247+
/// [problematic]: https://github.com/rust-lang/rust/issues/95489
2248+
pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Result {
2249+
let old_width = f.width;
2250+
let old_flags = f.flags;
22562251

2257-
f.width = old_width;
2258-
f.flags = old_flags;
2252+
// The alternate flag is already treated by LowerHex as being special-
2253+
// it denotes whether to prefix with 0x. We use it to work out whether
2254+
// or not to zero extend, and then unconditionally set it to get the
2255+
// prefix.
2256+
if f.alternate() {
2257+
f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32);
22592258

2260-
ret
2259+
if f.width.is_none() {
2260+
f.width = Some((usize::BITS / 4) as usize + 2);
22612261
}
2262-
2263-
inner(*self as *const (), f)
22642262
}
2263+
f.flags |= 1 << (FlagV1::Alternate as u32);
2264+
2265+
let ret = LowerHex::fmt(&ptr_addr, f);
2266+
2267+
f.width = old_width;
2268+
f.flags = old_flags;
2269+
2270+
ret
22652271
}
22662272

22672273
#[stable(feature = "rust1", since = "1.0.0")]

library/core/src/ptr/mod.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -1878,24 +1878,14 @@ macro_rules! fnptr_impls_safety_abi {
18781878
#[stable(feature = "fnptr_impls", since = "1.4.0")]
18791879
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
18801880
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1881-
// HACK: The intermediate cast as usize is required for AVR
1882-
// so that the address space of the source function pointer
1883-
// is preserved in the final function pointer.
1884-
//
1885-
// https://github.com/avr-rust/rust/issues/143
1886-
fmt::Pointer::fmt(&(*self as usize as *const ()), f)
1881+
fmt::pointer_fmt_inner(*self as usize, f)
18871882
}
18881883
}
18891884

18901885
#[stable(feature = "fnptr_impls", since = "1.4.0")]
18911886
impl<Ret, $($Arg),*> fmt::Debug for $FnTy {
18921887
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1893-
// HACK: The intermediate cast as usize is required for AVR
1894-
// so that the address space of the source function pointer
1895-
// is preserved in the final function pointer.
1896-
//
1897-
// https://github.com/avr-rust/rust/issues/143
1898-
fmt::Pointer::fmt(&(*self as usize as *const ()), f)
1888+
fmt::pointer_fmt_inner(*self as usize, f)
18991889
}
19001890
}
19011891
}

library/proc_macro/src/lib.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,11 @@ pub enum Delimiter {
703703
/// `[ ... ]`
704704
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
705705
Bracket,
706-
/// `/*«*/ ... /*»*/`
706+
/// `Ø ... Ø`
707707
/// An invisible delimiter, that may, for example, appear around tokens coming from a
708708
/// "macro variable" `$var`. It is important to preserve operator priorities in cases like
709709
/// `$var * 3` where `$var` is `1 + 2`.
710-
/// Invisible delimiters are not directly writable in normal Rust code except as comments.
711-
/// Therefore, they might not survive a roundtrip of a token stream through a string.
710+
/// Invisible delimiters might not survive roundtrip of a token stream through a string.
712711
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
713712
None,
714713
}

0 commit comments

Comments
 (0)