Skip to content

Commit 50f74e5

Browse files
committed
Strip frontmatter in fewer places
1 parent 2d0cc75 commit 50f74e5

File tree

15 files changed

+121
-66
lines changed

15 files changed

+121
-66
lines changed

compiler/rustc_builtin_macros/src/source_util.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_expand::base::{
1313
};
1414
use rustc_expand::module::DirOwnership;
1515
use rustc_lint_defs::BuiltinLintDiag;
16+
use rustc_parse::lexer::StripTokens;
1617
use rustc_parse::parser::{ForceCollect, Parser};
1718
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error};
1819
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
@@ -126,7 +127,16 @@ pub(crate) fn expand_include<'cx>(
126127
return ExpandResult::Ready(DummyResult::any(sp, guar));
127128
}
128129
};
129-
let p = unwrap_or_emit_fatal(new_parser_from_file(cx.psess(), &file, Some(sp)));
130+
// FIXME(frontmatter): Consider stripping frontmatter in a future edition. We can't strip them
131+
// in the current edition since that would be breaking.
132+
// See also <https://github.com/rust-lang/rust/issues/145945>.
133+
// Alternatively, stop stripping shebangs here, too, if T-lang and crater approve.
134+
let p = unwrap_or_emit_fatal(new_parser_from_file(
135+
cx.psess(),
136+
&file,
137+
StripTokens::Shebang,
138+
Some(sp),
139+
));
130140

131141
// If in the included file we have e.g., `mod bar;`,
132142
// then the path of `bar.rs` should be relative to the directory of `file`.

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
@@ -27,6 +27,7 @@ use rustc_middle::arena::Arena;
2727
use rustc_middle::dep_graph::DepsType;
2828
use rustc_middle::ty::{self, CurrentGcx, GlobalCtxt, RegisteredTools, TyCtxt};
2929
use rustc_middle::util::Providers;
30+
use rustc_parse::lexer::StripTokens;
3031
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
3132
use rustc_passes::{abi_test, input_stats, layout_test};
3233
use rustc_resolve::{Resolver, ResolverOutputs};
@@ -51,10 +52,18 @@ pub fn parse<'a>(sess: &'a Session) -> ast::Crate {
5152
let mut krate = sess
5253
.time("parse_crate", || {
5354
let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
54-
Input::File(file) => new_parser_from_file(&sess.psess, file, None),
55-
Input::Str { input, name } => {
56-
new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
57-
}
55+
Input::File(file) => new_parser_from_file(
56+
&sess.psess,
57+
file,
58+
StripTokens::ShebangAndFrontmatter,
59+
None,
60+
),
61+
Input::Str { input, name } => new_parser_from_source_str(
62+
&sess.psess,
63+
name.clone(),
64+
input.clone(),
65+
StripTokens::ShebangAndFrontmatter,
66+
),
5867
});
5968
parser.parse_crate_mod()
6069
})

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.

compiler/rustc_parse/src/lib.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,29 +54,18 @@ pub fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
5454
}
5555
}
5656

57-
/// Creates a new parser from a source string. On failure, the errors must be consumed via
58-
/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are
59-
/// dropped.
60-
pub fn new_parser_from_source_str(
61-
psess: &ParseSess,
62-
name: FileName,
63-
source: String,
64-
) -> Result<Parser<'_>, Vec<Diag<'_>>> {
65-
let source_file = psess.source_map().new_source_file(name, source);
66-
new_parser_from_source_file(psess, source_file, StripTokens::ShebangAndFrontmatter)
67-
}
68-
69-
/// Creates a new parser from a simple (no shebang, no frontmatter) source string.
57+
/// Creates a new parser from a source string.
7058
///
7159
/// On failure, the errors must be consumed via `unwrap_or_emit_fatal`, `emit`, `cancel`,
7260
/// etc., otherwise a panic will occur when they are dropped.
73-
pub fn new_parser_from_simple_source_str(
61+
pub fn new_parser_from_source_str(
7462
psess: &ParseSess,
7563
name: FileName,
7664
source: String,
65+
strip_tokens: StripTokens,
7766
) -> Result<Parser<'_>, Vec<Diag<'_>>> {
7867
let source_file = psess.source_map().new_source_file(name, source);
79-
new_parser_from_source_file(psess, source_file, StripTokens::Nothing)
68+
new_parser_from_source_file(psess, source_file, strip_tokens)
8069
}
8170

8271
/// Creates a new parser from a filename. On failure, the errors must be consumed via
@@ -87,6 +76,7 @@ pub fn new_parser_from_simple_source_str(
8776
pub fn new_parser_from_file<'a>(
8877
psess: &'a ParseSess,
8978
path: &Path,
79+
strip_tokens: StripTokens,
9080
sp: Option<Span>,
9181
) -> Result<Parser<'a>, Vec<Diag<'a>>> {
9282
let sm = psess.source_map();
@@ -110,7 +100,7 @@ pub fn new_parser_from_file<'a>(
110100
}
111101
err.emit();
112102
});
113-
new_parser_from_source_file(psess, source_file, StripTokens::ShebangAndFrontmatter)
103+
new_parser_from_source_file(psess, source_file, strip_tokens)
114104
}
115105

116106
pub fn utf8_error<E: EmissionGuarantee>(
@@ -172,20 +162,26 @@ fn new_parser_from_source_file(
172162
Ok(parser)
173163
}
174164

165+
/// Given a source string, produces a sequence of token trees.
166+
///
167+
/// NOTE: This only strips shebangs, not frontmatter!
175168
pub fn source_str_to_stream(
176169
psess: &ParseSess,
177170
name: FileName,
178171
source: String,
179172
override_span: Option<Span>,
180173
) -> Result<TokenStream, Vec<Diag<'_>>> {
181174
let source_file = psess.source_map().new_source_file(name, source);
182-
// used mainly for `proc_macro` and the likes, not for our parsing purposes, so don't parse
183-
// frontmatters as frontmatters, but for compatibility reason still strip the shebang
175+
// FIXME(frontmatter): Consider stripping frontmatter in a future edition. We can't strip them
176+
// in the current edition since that would be breaking.
177+
// See also <https://github.com/rust-lang/rust/issues/145520>.
178+
// Alternatively, stop stripping shebangs here, too, if T-lang and crater approve.
184179
source_file_to_stream(psess, source_file, override_span, StripTokens::Shebang)
185180
}
186181

187-
/// Given a source file, produces a sequence of token trees. Returns any buffered errors from
188-
/// parsing the token stream.
182+
/// Given a source file, produces a sequence of token trees.
183+
///
184+
/// Returns any buffered errors from parsing the token stream.
189185
fn source_file_to_stream<'psess>(
190186
psess: &'psess ParseSess,
191187
source_file: Arc<SourceFile>,

compiler/rustc_parse/src/parser/tests.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_span::{
2222
};
2323
use termcolor::WriteColor;
2424

25+
use crate::lexer::StripTokens;
2526
use crate::parser::{ForceCollect, Parser};
2627
use crate::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
2728

@@ -35,6 +36,7 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
3536
psess,
3637
PathBuf::from("bogofile").into(),
3738
source_str,
39+
StripTokens::Nothing,
3840
))
3941
}
4042

@@ -2240,7 +2242,7 @@ fn parse_item_from_source_str(
22402242
source: String,
22412243
psess: &ParseSess,
22422244
) -> PResult<'_, Option<Box<ast::Item>>> {
2243-
unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source))
2245+
unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source, StripTokens::Nothing))
22442246
.parse_item(ForceCollect::No)
22452247
}
22462248

@@ -2520,7 +2522,8 @@ fn ttdelim_span() {
25202522
source: String,
25212523
psess: &ParseSess,
25222524
) -> PResult<'_, Box<ast::Expr>> {
2523-
unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)).parse_expr()
2525+
unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source, StripTokens::Nothing))
2526+
.parse_expr()
25242527
}
25252528

25262529
create_default_session_globals_then(|| {

src/librustdoc/clean/render_macro_matchers.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
33
use rustc_ast_pretty::pprust::PrintState;
44
use rustc_ast_pretty::pprust::state::State as Printer;
55
use rustc_middle::ty::TyCtxt;
6+
use rustc_parse::lexer::StripTokens;
67
use rustc_session::parse::ParseSess;
78
use rustc_span::symbol::{Ident, Symbol, kw};
89
use rustc_span::{FileName, Span};
@@ -64,14 +65,18 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
6465
// Create a Parser.
6566
let psess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec());
6667
let file_name = FileName::macro_expansion_source_code(&snippet);
67-
let mut parser =
68-
match rustc_parse::new_parser_from_source_str(&psess, file_name, snippet.clone()) {
69-
Ok(parser) => parser,
70-
Err(errs) => {
71-
errs.into_iter().for_each(|err| err.cancel());
72-
return None;
73-
}
74-
};
68+
let mut parser = match rustc_parse::new_parser_from_source_str(
69+
&psess,
70+
file_name,
71+
snippet.clone(),
72+
StripTokens::Nothing,
73+
) {
74+
Ok(parser) => parser,
75+
Err(errs) => {
76+
errs.into_iter().for_each(|err| err.cancel());
77+
return None;
78+
}
79+
};
7580

7681
// Reparse a single token tree.
7782
if parser.token == token::Eof {

0 commit comments

Comments
 (0)