Skip to content

Commit a32ceac

Browse files
authored
Unrolled build for #146340
Rollup merge of #146340 - fmease:frontmatter-containment, r=fee1-dead,Urgau Strip frontmatter in fewer places * Stop stripping frontmatter in `proc_macro::Literal::from_str` (RUST-146132) * Stop stripping frontmatter in expr-ctxt (but not item-ctxt!) `include`s (RUST-145945) * Stop stripping shebang (!) in `proc_macro::Literal::from_str` * Not a breaking change because it did compare spans already to ensure there wasn't extra whitespace or comments (`Literal::from_str("#!\n0")` already yields `Err(_)` thankfully!) * Stop stripping frontmatter+shebang inside some rustdoc code where it doesn't make any observable difference (see self review comments) * (Stop stripping frontmatter+shebang inside internal test code) Fixes #145945. Fixes #146132. r? fee1-dead
2 parents 565a9ca + 7a66925 commit a32ceac

File tree

21 files changed

+226
-128
lines changed

21 files changed

+226
-128
lines changed

compiler/rustc_builtin_macros/src/source_util.rs

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! The implementation of built-in macros which relate to the file system.
2+
13
use std::path::{Path, PathBuf};
24
use std::rc::Rc;
35
use std::sync::Arc;
@@ -11,9 +13,11 @@ use rustc_expand::base::{
1113
};
1214
use rustc_expand::module::DirOwnership;
1315
use rustc_lint_defs::BuiltinLintDiag;
14-
use rustc_parse::parser::{ForceCollect, Parser};
16+
use rustc_parse::lexer::StripTokens;
17+
use rustc_parse::parser::ForceCollect;
1518
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error};
1619
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
20+
use rustc_session::parse::ParseSess;
1721
use rustc_span::source_map::SourceMap;
1822
use rustc_span::{ByteSymbol, Pos, Span, Symbol};
1923
use smallvec::SmallVec;
@@ -23,11 +27,7 @@ use crate::util::{
2327
check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
2428
};
2529

26-
// These macros all relate to the file system; they either return
27-
// the column/row/filename of the expression, or they include
28-
// a given file into the current one.
29-
30-
/// line!(): expands to the current line number
30+
/// Expand `line!()` to the current line number.
3131
pub(crate) fn expand_line(
3232
cx: &mut ExtCtxt<'_>,
3333
sp: Span,
@@ -42,7 +42,7 @@ pub(crate) fn expand_line(
4242
ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.line as u32)))
4343
}
4444

45-
/* column!(): expands to the current column number */
45+
/// Expand `column!()` to the current column number.
4646
pub(crate) fn expand_column(
4747
cx: &mut ExtCtxt<'_>,
4848
sp: Span,
@@ -57,9 +57,7 @@ pub(crate) fn expand_column(
5757
ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1)))
5858
}
5959

60-
/// file!(): expands to the current filename */
61-
/// The source_file (`loc.file`) contains a bunch more information we could spit
62-
/// out if we wanted.
60+
/// Expand `file!()` to the current filename.
6361
pub(crate) fn expand_file(
6462
cx: &mut ExtCtxt<'_>,
6563
sp: Span,
@@ -81,6 +79,7 @@ pub(crate) fn expand_file(
8179
)))
8280
}
8381

82+
/// Expand `stringify!($input)`.
8483
pub(crate) fn expand_stringify(
8584
cx: &mut ExtCtxt<'_>,
8685
sp: Span,
@@ -91,6 +90,7 @@ pub(crate) fn expand_stringify(
9190
ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&s))))
9291
}
9392

93+
/// Expand `module_path!()` to (a textual representation of) the current module path.
9494
pub(crate) fn expand_mod(
9595
cx: &mut ExtCtxt<'_>,
9696
sp: Span,
@@ -104,9 +104,9 @@ pub(crate) fn expand_mod(
104104
ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&string))))
105105
}
106106

107-
/// include! : parse the given file as an expr
108-
/// This is generally a bad idea because it's going to behave
109-
/// unhygienically.
107+
/// Expand `include!($input)`.
108+
///
109+
/// This works in item and expression position. Notably, it doesn't work in pattern position.
110110
pub(crate) fn expand_include<'cx>(
111111
cx: &'cx mut ExtCtxt<'_>,
112112
sp: Span,
@@ -116,64 +116,76 @@ pub(crate) fn expand_include<'cx>(
116116
let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include!") else {
117117
return ExpandResult::Retry(());
118118
};
119-
let file = match mac {
120-
Ok(file) => file,
119+
let path = match mac {
120+
Ok(path) => path,
121121
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
122122
};
123123
// The file will be added to the code map by the parser
124-
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
125-
Ok(f) => f,
124+
let path = match resolve_path(&cx.sess, path.as_str(), sp) {
125+
Ok(path) => path,
126126
Err(err) => {
127127
let guar = err.emit();
128128
return ExpandResult::Ready(DummyResult::any(sp, guar));
129129
}
130130
};
131-
let p = unwrap_or_emit_fatal(new_parser_from_file(cx.psess(), &file, Some(sp)));
132131

133132
// If in the included file we have e.g., `mod bar;`,
134-
// then the path of `bar.rs` should be relative to the directory of `file`.
133+
// then the path of `bar.rs` should be relative to the directory of `path`.
135134
// See https://github.com/rust-lang/rust/pull/69838/files#r395217057 for a discussion.
136135
// `MacroExpander::fully_expand_fragment` later restores, so "stack discipline" is maintained.
137-
let dir_path = file.parent().unwrap_or(&file).to_owned();
136+
let dir_path = path.parent().unwrap_or(&path).to_owned();
138137
cx.current_expansion.module = Rc::new(cx.current_expansion.module.with_dir_path(dir_path));
139138
cx.current_expansion.dir_ownership = DirOwnership::Owned { relative: None };
140139

141140
struct ExpandInclude<'a> {
142-
p: Parser<'a>,
141+
psess: &'a ParseSess,
142+
path: PathBuf,
143143
node_id: ast::NodeId,
144+
span: Span,
144145
}
145146
impl<'a> MacResult for ExpandInclude<'a> {
146-
fn make_expr(mut self: Box<ExpandInclude<'a>>) -> Option<Box<ast::Expr>> {
147-
let expr = parse_expr(&mut self.p).ok()?;
148-
if self.p.token != token::Eof {
149-
self.p.psess.buffer_lint(
147+
fn make_expr(self: Box<ExpandInclude<'a>>) -> Option<Box<ast::Expr>> {
148+
let mut p = unwrap_or_emit_fatal(new_parser_from_file(
149+
self.psess,
150+
&self.path,
151+
// Don't strip frontmatter for backward compatibility, `---` may be the start of a
152+
// manifold negation. FIXME: Ideally, we wouldn't strip shebangs here either.
153+
StripTokens::Shebang,
154+
Some(self.span),
155+
));
156+
let expr = parse_expr(&mut p).ok()?;
157+
if p.token != token::Eof {
158+
p.psess.buffer_lint(
150159
INCOMPLETE_INCLUDE,
151-
self.p.token.span,
160+
p.token.span,
152161
self.node_id,
153162
BuiltinLintDiag::IncompleteInclude,
154163
);
155164
}
156165
Some(expr)
157166
}
158167

159-
fn make_items(mut self: Box<ExpandInclude<'a>>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
168+
fn make_items(self: Box<ExpandInclude<'a>>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
169+
let mut p = unwrap_or_emit_fatal(new_parser_from_file(
170+
self.psess,
171+
&self.path,
172+
StripTokens::ShebangAndFrontmatter,
173+
Some(self.span),
174+
));
160175
let mut ret = SmallVec::new();
161176
loop {
162-
match self.p.parse_item(ForceCollect::No) {
177+
match p.parse_item(ForceCollect::No) {
163178
Err(err) => {
164179
err.emit();
165180
break;
166181
}
167182
Ok(Some(item)) => ret.push(item),
168183
Ok(None) => {
169-
if self.p.token != token::Eof {
170-
self.p
171-
.dcx()
172-
.create_err(errors::ExpectedItem {
173-
span: self.p.token.span,
174-
token: &pprust::token_to_string(&self.p.token),
175-
})
176-
.emit();
184+
if p.token != token::Eof {
185+
p.dcx().emit_err(errors::ExpectedItem {
186+
span: p.token.span,
187+
token: &pprust::token_to_string(&p.token),
188+
});
177189
}
178190

179191
break;
@@ -184,10 +196,17 @@ pub(crate) fn expand_include<'cx>(
184196
}
185197
}
186198

187-
ExpandResult::Ready(Box::new(ExpandInclude { p, node_id: cx.current_expansion.lint_node_id }))
199+
ExpandResult::Ready(Box::new(ExpandInclude {
200+
psess: cx.psess(),
201+
path,
202+
node_id: cx.current_expansion.lint_node_id,
203+
span: sp,
204+
}))
188205
}
189206

190-
/// `include_str!`: read the given file, insert it as a literal string expr
207+
/// Expand `include_str!($input)` to the content of the UTF-8-encoded file given by path `$input` as a string literal.
208+
///
209+
/// This works in expression, pattern and statement position.
191210
pub(crate) fn expand_include_str(
192211
cx: &mut ExtCtxt<'_>,
193212
sp: Span,
@@ -206,6 +225,7 @@ pub(crate) fn expand_include_str(
206225
Ok((bytes, bsp)) => match std::str::from_utf8(&bytes) {
207226
Ok(src) => {
208227
let interned_src = Symbol::intern(src);
228+
// MacEager converts the expr into a pat if need be.
209229
MacEager::expr(cx.expr_str(cx.with_def_site_ctxt(bsp), interned_src))
210230
}
211231
Err(utf8err) => {
@@ -218,6 +238,9 @@ pub(crate) fn expand_include_str(
218238
})
219239
}
220240

241+
/// Expand `include_bytes!($input)` to the content of the file given by path `$input`.
242+
///
243+
/// This works in expression, pattern and statement position.
221244
pub(crate) fn expand_include_bytes(
222245
cx: &mut ExtCtxt<'_>,
223246
sp: Span,
@@ -237,6 +260,7 @@ pub(crate) fn expand_include_bytes(
237260
// Don't care about getting the span for the raw bytes,
238261
// because the console can't really show them anyway.
239262
let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(ByteSymbol::intern(&bytes)));
263+
// MacEager converts the expr into a pat if need be.
240264
MacEager::expr(expr)
241265
}
242266
Err(dummy) => dummy,

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use rustc_lint::unerased_lint_store;
5151
use rustc_metadata::creader::MetadataLoader;
5252
use rustc_metadata::locator;
5353
use rustc_middle::ty::TyCtxt;
54+
use rustc_parse::lexer::StripTokens;
5455
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
5556
use rustc_session::config::{
5657
CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType, Sysroot,
@@ -1288,10 +1289,15 @@ fn warn_on_confusing_output_filename_flag(
12881289

12891290
fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
12901291
let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
1291-
Input::File(file) => new_parser_from_file(&sess.psess, file, None),
1292-
Input::Str { name, input } => {
1293-
new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
1292+
Input::File(file) => {
1293+
new_parser_from_file(&sess.psess, file, StripTokens::ShebangAndFrontmatter, None)
12941294
}
1295+
Input::Str { name, input } => new_parser_from_source_str(
1296+
&sess.psess,
1297+
name.clone(),
1298+
input.clone(),
1299+
StripTokens::ShebangAndFrontmatter,
1300+
),
12951301
});
12961302
parser.parse_inner_attributes()
12971303
}

compiler/rustc_expand/src/module.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::path::{self, Path, PathBuf};
44
use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans};
55
use rustc_attr_parsing::validate_attr;
66
use rustc_errors::{Diag, ErrorGuaranteed};
7+
use rustc_parse::lexer::StripTokens;
78
use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal};
89
use rustc_session::Session;
910
use rustc_session::parse::ParseSess;
@@ -67,8 +68,12 @@ pub(crate) fn parse_external_mod(
6768
}
6869

6970
// Actually parse the external file as a module.
70-
let mut parser =
71-
unwrap_or_emit_fatal(new_parser_from_file(&sess.psess, &mp.file_path, Some(span)));
71+
let mut parser = unwrap_or_emit_fatal(new_parser_from_file(
72+
&sess.psess,
73+
&mp.file_path,
74+
StripTokens::ShebangAndFrontmatter,
75+
Some(span),
76+
));
7277
let (inner_attrs, items, inner_span) =
7378
parser.parse_mod(exp!(Eof)).map_err(|err| ModError::ParserError(err))?;
7479
attrs.extend(inner_attrs);

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
88
use rustc_ast_pretty::pprust;
99
use rustc_data_structures::fx::FxHashMap;
1010
use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
11-
use rustc_parse::lexer::nfc_normalize;
11+
use rustc_parse::lexer::{StripTokens, nfc_normalize};
1212
use rustc_parse::parser::Parser;
1313
use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
1414
use rustc_proc_macro::bridge::{
@@ -485,8 +485,13 @@ impl server::FreeFunctions for Rustc<'_, '_> {
485485

486486
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, ()> {
487487
let name = FileName::proc_macro_source_code(s);
488-
let mut parser =
489-
unwrap_or_emit_fatal(new_parser_from_source_str(self.psess(), name, s.to_owned()));
488+
489+
let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str(
490+
self.psess(),
491+
name,
492+
s.to_owned(),
493+
StripTokens::Nothing,
494+
));
490495

491496
let first_span = parser.token.span.data();
492497
let minus_present = parser.eat(exp!(Minus));

compiler/rustc_interface/src/interface.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use rustc_lint::LintStore;
1313
use rustc_middle::ty;
1414
use rustc_middle::ty::CurrentGcx;
1515
use rustc_middle::util::Providers;
16-
use rustc_parse::new_parser_from_simple_source_str;
16+
use rustc_parse::lexer::StripTokens;
17+
use rustc_parse::new_parser_from_source_str;
1718
use rustc_parse::parser::attr::AllowLeadingUnsafe;
1819
use rustc_query_impl::QueryCtxt;
1920
use rustc_query_system::query::print_query_stack;
@@ -68,7 +69,8 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {
6869
};
6970
}
7071

71-
match new_parser_from_simple_source_str(&psess, filename, s.to_string()) {
72+
match new_parser_from_source_str(&psess, filename, s.to_string(), StripTokens::Nothing)
73+
{
7274
Ok(mut parser) => match parser.parse_meta_item(AllowLeadingUnsafe::No) {
7375
Ok(meta_item) if parser.token == token::Eof => {
7476
if meta_item.path.segments.len() != 1 {
@@ -166,13 +168,15 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch
166168
error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
167169
};
168170

169-
let mut parser = match new_parser_from_simple_source_str(&psess, filename, s.to_string()) {
170-
Ok(parser) => parser,
171-
Err(errs) => {
172-
errs.into_iter().for_each(|err| err.cancel());
173-
expected_error();
174-
}
175-
};
171+
let mut parser =
172+
match new_parser_from_source_str(&psess, filename, s.to_string(), StripTokens::Nothing)
173+
{
174+
Ok(parser) => parser,
175+
Err(errs) => {
176+
errs.into_iter().for_each(|err| err.cancel());
177+
expected_error();
178+
}
179+
};
176180

177181
let meta_item = match parser.parse_meta_item(AllowLeadingUnsafe::No) {
178182
Ok(meta_item) if parser.token == token::Eof => meta_item,

compiler/rustc_interface/src/passes.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use rustc_middle::arena::Arena;
2828
use rustc_middle::dep_graph::DepsType;
2929
use rustc_middle::ty::{self, CurrentGcx, GlobalCtxt, RegisteredTools, TyCtxt};
3030
use rustc_middle::util::Providers;
31+
use rustc_parse::lexer::StripTokens;
3132
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
3233
use rustc_passes::{abi_test, input_stats, layout_test};
3334
use rustc_resolve::{Resolver, ResolverOutputs};
@@ -52,10 +53,18 @@ pub fn parse<'a>(sess: &'a Session) -> ast::Crate {
5253
let mut krate = sess
5354
.time("parse_crate", || {
5455
let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
55-
Input::File(file) => new_parser_from_file(&sess.psess, file, None),
56-
Input::Str { input, name } => {
57-
new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
58-
}
56+
Input::File(file) => new_parser_from_file(
57+
&sess.psess,
58+
file,
59+
StripTokens::ShebangAndFrontmatter,
60+
None,
61+
),
62+
Input::Str { input, name } => new_parser_from_source_str(
63+
&sess.psess,
64+
name.clone(),
65+
input.clone(),
66+
StripTokens::ShebangAndFrontmatter,
67+
),
5968
});
6069
parser.parse_crate_mod()
6170
})

compiler/rustc_parse/src/lexer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub(crate) struct UnmatchedDelim {
4545
}
4646

4747
/// Which tokens should be stripped before lexing the tokens.
48-
pub(crate) enum StripTokens {
48+
pub enum StripTokens {
4949
/// Strip both shebang and frontmatter.
5050
ShebangAndFrontmatter,
5151
/// Strip the shebang but not frontmatter.

0 commit comments

Comments
 (0)