diff --git a/tests/ui-fulldeps/auxiliary/parser.rs b/tests/ui-fulldeps/auxiliary/parser.rs new file mode 100644 index 0000000000000..4ea0d814b1faa --- /dev/null +++ b/tests/ui-fulldeps/auxiliary/parser.rs @@ -0,0 +1,51 @@ +#![feature(rustc_private)] + +extern crate rustc_ast; +extern crate rustc_driver; +extern crate rustc_errors; +extern crate rustc_parse; +extern crate rustc_session; +extern crate rustc_span; + +use rustc_ast::ast::{DUMMY_NODE_ID, Expr}; +use rustc_ast::mut_visit::MutVisitor; +use rustc_ast::node_id::NodeId; +use rustc_ast::ptr::P; +use rustc_ast::token; +use rustc_errors::Diag; +use rustc_parse::parser::Recovery; +use rustc_session::parse::ParseSess; +use rustc_span::{DUMMY_SP, FileName, Span}; + +pub fn parse_expr(psess: &ParseSess, source_code: &str) -> Option
> { + let parser = rustc_parse::unwrap_or_emit_fatal(rustc_parse::new_parser_from_source_str( + psess, + FileName::anon_source_code(source_code), + source_code.to_owned(), + )); + + let mut parser = parser.recovery(Recovery::Forbidden); + let mut expr = parser.parse_expr().map_err(Diag::cancel).ok()?; + if parser.token != token::Eof { + return None; + } + + Normalize.visit_expr(&mut expr); + Some(expr) +} + +// Erase Span information that could distinguish between identical expressions +// parsed from different source strings. +struct Normalize; + +impl MutVisitor for Normalize { + const VISIT_TOKENS: bool = true; + + fn visit_id(&mut self, id: &mut NodeId) { + *id = DUMMY_NODE_ID; + } + + fn visit_span(&mut self, span: &mut Span) { + *span = DUMMY_SP; + } +} diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index 8379ca86494c4..37e328a315f1e 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -1,5 +1,7 @@ //@ run-pass //@ ignore-cross-compile +//@ aux-crate: parser=parser.rs +//@ edition: 2021 // The general idea of this test is to enumerate all "interesting" expressions and check that // `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test: @@ -21,7 +23,6 @@ extern crate rustc_ast; extern crate rustc_ast_pretty; -extern crate rustc_data_structures; extern crate rustc_parse; extern crate rustc_session; extern crate rustc_span; @@ -32,28 +33,17 @@ extern crate thin_vec; #[allow(unused_extern_crates)] extern crate rustc_driver; +use parser::parse_expr; use rustc_ast::mut_visit::{visit_clobber, MutVisitor}; use rustc_ast::ptr::P; use rustc_ast::*; use rustc_ast_pretty::pprust; -use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_session::parse::ParseSess; use rustc_span::source_map::Spanned; use rustc_span::symbol::Ident; -use rustc_span::{FileName, DUMMY_SP}; +use rustc_span::DUMMY_SP; use thin_vec::{thin_vec, ThinVec}; -fn parse_expr(psess: &ParseSess, src: &str) -> Option
> {
- let src_as_string = src.to_string();
-
- let mut p = unwrap_or_emit_fatal(new_parser_from_source_str(
- psess,
- FileName::Custom(src_as_string.clone()),
- src_as_string,
- ));
- p.parse_expr().map_err(|e| e.cancel()).ok()
-}
-
// Helper functions for building exprs
fn expr(kind: ExprKind) -> P > {
- let parser = rustc_parse::unwrap_or_emit_fatal(rustc_parse::new_parser_from_source_str(
- psess,
- FileName::anon_source_code(source_code),
- source_code.to_owned(),
- ));
-
- let mut expr = parser.recovery(Recovery::Forbidden).parse_expr().map_err(Diag::cancel).ok()?;
- Normalize.visit_expr(&mut expr);
- Some(expr)
-}
-
fn main() -> ExitCode {
let mut status = ExitCode::SUCCESS;
let mut fail = |description: &str, before: &str, after: &str| {
@@ -197,7 +166,9 @@ fn main() -> ExitCode {
let psess = &ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]);
for &source_code in EXPRS {
- let expr = parse_expr(psess, source_code).unwrap();
+ let Some(expr) = parse_expr(psess, source_code) else {
+ panic!("Failed to parse original test case: {source_code}");
+ };
// Check for FALSE POSITIVE: pretty-printer inserting parentheses where not needed.
// Pseudocode: