From 1a549c077232951c8f7f87d168f67a5c36b2c83f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Nov 2024 12:23:36 -0800 Subject: [PATCH] Improve test_unparenthesize to catch more false negatives --- tests/test_unparenthesize.rs | 50 +++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/tests/test_unparenthesize.rs b/tests/test_unparenthesize.rs index 5db2e57a5..5e155bff6 100644 --- a/tests/test_unparenthesize.rs +++ b/tests/test_unparenthesize.rs @@ -12,7 +12,7 @@ use std::panic; use std::path::Path; use std::sync::atomic::{AtomicUsize, Ordering}; use syn::visit_mut::{self, VisitMut}; -use syn::Expr; +use syn::{Expr, Generics, LifetimeParam, TypeParam}; #[macro_use] mod macros; @@ -45,13 +45,55 @@ impl VisitMut for FlattenParens { } } +struct AsIfPrinted; + +impl VisitMut for AsIfPrinted { + fn visit_generics_mut(&mut self, generics: &mut Generics) { + if generics.params.is_empty() { + generics.lt_token = None; + generics.gt_token = None; + } + if let Some(where_clause) = &generics.where_clause { + if where_clause.predicates.is_empty() { + generics.where_clause = None; + } + } + visit_mut::visit_generics_mut(self, generics); + } + + fn visit_lifetime_param_mut(&mut self, param: &mut LifetimeParam) { + if param.bounds.is_empty() { + param.colon_token = None; + } + visit_mut::visit_lifetime_param_mut(self, param); + } + + fn visit_type_param_mut(&mut self, param: &mut TypeParam) { + if param.bounds.is_empty() { + param.colon_token = None; + } + visit_mut::visit_type_param_mut(self, param); + } +} + fn test(path: &Path, failed: &AtomicUsize) { let content = fs::read_to_string(path).unwrap(); match panic::catch_unwind(|| -> syn::Result<()> { - let mut syntax_tree = syn::parse_file(&content)?; - FlattenParens.visit_file_mut(&mut syntax_tree); - syn::parse2::(syntax_tree.to_token_stream())?; + let mut before = syn::parse_file(&content)?; + before.shebang = None; + FlattenParens.visit_file_mut(&mut before); + let printed = before.to_token_stream(); + let mut after = syn::parse2::(printed.clone())?; + FlattenParens.visit_file_mut(&mut after); + // Normalize features that we expect Syn not to print. + AsIfPrinted.visit_file_mut(&mut before); + if before != after { + errorf!("=== {}\n", path.display()); + if failed.fetch_add(1, Ordering::Relaxed) == 0 { + errorf!("BEFORE:\n{:#?}\nAFTER:\n{:#?}\n", before, after); + } + } Ok(()) }) { Err(_) => {