Improve print_tts by making space_between smarter by nnethercote · Pull Request #117433 · rust-lang/rust (original) (raw)

🎉 Experiment pr-117433-1 is completed! 📊 36 regressed and 0 fixed (53 total) 📰 Open the full report.

I still don't understand how to read crater reports properly. But looking at the "regressed: dependencies" section, there are five problems, all involving conversions of a token stream to a string and then "parsing" the resulting string. Annoying stuff, and I'm not sure how to proceed.

atspi-proxies-0.1.0

It uses atspi-macros-0.4.0, which has this code in src/proxy.rs:

// TODO: this is sketchy as all hell // it replaces all mentions of zbus::Result with the Generic std::result::Result, then, adds the Self::Error error type to the second part of the generic // finally, it replaces all mentions of (String, zbus :: zvairnat :: OwnedObjectPath) with &Self. // this menas that implementors will need to return a borrowed value of the same type to comply with the type system. // unsure if this will hold up over time. fn genericize_method_return_type(rt: &ReturnType) -> TokenStream { let original = format!("{}", rt.to_token_stream()); let mut generic_result = original.replace("zbus :: Result", "std :: result :: Result"); let end_of_str = generic_result.len(); generic_result.insert_str(end_of_str - 2, ", Self :: Error"); let mut generic_impl = generic_result.replace(OBJECT_PAIR_NAME, "Self"); generic_impl.push_str(" where Self: Sized"); TokenStream::from_str(&generic_impl).expect("Could not genericize zbus method/property/signal. Attempted to turn "{generic_result}" into a TokenStream.") }

The spacing of zbus :: Result has changed to zbus::Result, which breaks this code.

awto-0.1.2

It uses awto-macros-0.1.2, which has this code in src/proc_macros/schema/database_table.rs:

            let db_type_is_text = ty.to_string().ends_with(":: Text");
            if let Some(max_len) = &field.attrs.max_len {
                if !db_type_is_text {
                    return Err(syn::Error::new(
                        max_len.span(),
                        "max_len can only be used on varchar & char types",
                    ));
                }
                ty = quote!(#ty(Some(#max_len)));
            } else if db_type_is_text {
                ty = quote!(#ty(None));
            }

The change in spacing of :: Text to ::Text breaks this.

ink-analyzer-ir-0.7.0

crates/macro/src/from_ast.rs has this:

pub fn impl_from_ast(ast: &syn::DeriveInput) -> syn::Result {
let name = &ast.ident;

if let Some(fields) = utils::parse_struct_fields(ast) {                                                                                           
    if let Some(ast_field) = utils::find_field(fields, "ast") {                                                                                   
        let ir_crate_path = utils::get_normalized_ir_crate_path();                                                                                
        let ast_field_type = &ast_field.ty;                                                                                                       
        let ast_type = if ast_field_type                                                                                                          
            .to_token_stream()                                                                                                                    
            .to_string()                                                                                                                          
            .starts_with("ast ::")
        {                                                                                                                                         
            quote! { #ast_field_type }                                                                                                            
        } else {                                                                                                                                  
            quote! { ast::#ast_field_type }                                                                                                       
        };  

The change of spacing from ast :: to ast:: breaks this.

kcl-lib-0.1.35

It uses derive-docs-0.4.0 which has this code in src/lib.rs:

let ret_ty = ast.sig.output.clone();
let ret_ty_string = ret_ty
    .into_token_stream()
    .to_string()
    .replace("-> ", "")
    .replace("Result < ", "")
    .replace(", KclError >", "");
let return_type = if !ret_ty_string.is_empty() {
    let ret_ty_string = if ret_ty_string.starts_with("Box <") {
        ret_ty_string
            .trim_start_matches("Box <")
            .trim_end_matches('>')
            .trim()
            .to_string()
    } else {
        ret_ty_string.trim().to_string()
    };

An example return type changes from this:

-> Result < Box < ExtrudeGroup >, KclError > {}

to this:

-> Result < Box < ExtrudeGroup > , KclError > {}

And the space inserted between the > and , breaks the parsing, because trim_end_matches('>') fails due to the trailing space.

pagetop-0.0.46

This uses pagetop-macros-0.0.5, which has this code in in src/lib.rs:

let args: Vec<String> = fn_item                                                                                                  
    .sig                                                                                                                         
    .inputs                                                                                                                      
    .iter()                                                                                                                      
    .skip(1)                                                                                                                     
    .map(|arg| arg.to_token_stream().to_string())                                                                                
    .collect();                                                                                                                  
                                                                                                                                 
let param: Vec<String> = args                                                                                                    
    .iter()                                                                                                                      
    .map(|arg| arg.split_whitespace().next().unwrap().to_string())                                                               
    .collect();                                                                                                                  
                                                                                                                                 
#[rustfmt::skip]                                                                                                                 
let fn_with = parse_str::<ItemFn>(concat_string!("                                                                               
    pub fn ", fn_name.replace("alter_", "with_"), "(mut self, ", args.join(", "), ") -> Self {                                   
        self.", fn_name, "(", param.join(", "), ");                                                                              
        self                                                                                                                     
    }                                                                                                                            
").as_str()).unwrap();                                                                                                           

On a signature like this:

    pub fn alter_value(&mut self, value: impl Into<String>) -> &mut Self {                                                           

the old pretty printer printed value :, the new one does value:, so the arg.split_whitespace().next() returns value: instead of value, which messes up the subsequent code.