Skip to content

cannot fix with overlapping suggestions #13026

Open
@ehuss

Description

@ehuss

Some suggestions include overlapping regions. These cause rustfix to fail with an error like:

Could not replace range 22...47 in file -- maybe parts of it were already replaced?

An example that triggers this is the following where multiple trait bounds are to be removed:

pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;

This results in the following suggestion:

warning: bounds on generic parameters are not enforced in type aliases
 --> src/main.rs:1:25
  |
1 | pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;
  |                         ^^^^^^^^^^^^^^^^^   ^^^^   ^^^^
  |
  = note: `#[warn(type_alias_bounds)]` on by default
help: the bound will not be checked when the type alias is used, and should be removed
  |
1 - pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;
1 + pub type MyResult<T, E> = Result<T, E>;
  |

With the suggested JSON:

{
    "reason": "compiler-message",
    "package_id": "z2 0.1.0 (path+file:///foo)",
    "manifest_path": "/foo/Cargo.toml",
    "target":
    {
        "kind":
        [
            "bin"
        ],
        "crate_types":
        [
            "bin"
        ],
        "name": "z2",
        "src_path": "/foo/src/main.rs",
        "edition": "2018",
        "doc": true,
        "doctest": false,
        "test": true
    },
    "message":
    {
        "rendered": "warning: bounds on generic parameters are not enforced in type aliases\n --> src/main.rs:1:25\n  |\n1 | pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;\n  |                         ^^^^^^^^^^^^^^^^^   ^^^^   ^^^^\n  |\n  = note: `#[warn(type_alias_bounds)]` on by default\nhelp: the bound will not be checked when the type alias is used, and should be removed\n  |\n1 - pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;\n1 + pub type MyResult<T, E> = Result<T, E>;\n  | \n\n",
        "children":
        [
            {
                "children":
                [],
                "code": null,
                "level": "note",
                "message": "`#[warn(type_alias_bounds)]` on by default",
                "rendered": null,
                "spans":
                []
            },
            {
                "children":
                [],
                "code": null,
                "level": "help",
                "message": "the bound will not be checked when the type alias is used, and should be removed",
                "rendered": null,
                "spans":
                [
                    {
                        "byte_end": 41,
                        "byte_start": 22,
                        "column_end": 42,
                        "column_start": 23,
                        "expansion": null,
                        "file_name": "src/main.rs",
                        "is_primary": true,
                        "label": null,
                        "line_end": 1,
                        "line_start": 1,
                        "suggested_replacement": "",
                        "suggestion_applicability": "MachineApplicable",
                        "text":
                        [
                            {
                                "highlight_end": 42,
                                "highlight_start": 23,
                                "text": "pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;"
                            }
                        ]
                    },
                    {
                        "byte_end": 48,
                        "byte_start": 22,
                        "column_end": 49,
                        "column_start": 23,
                        "expansion": null,
                        "file_name": "src/main.rs",
                        "is_primary": true,
                        "label": null,
                        "line_end": 1,
                        "line_start": 1,
                        "suggested_replacement": "",
                        "suggestion_applicability": "MachineApplicable",
                        "text":
                        [
                            {
                                "highlight_end": 49,
                                "highlight_start": 23,
                                "text": "pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;"
                            }
                        ]
                    },
                    {
                        "byte_end": 55,
                        "byte_start": 22,
                        "column_end": 56,
                        "column_start": 23,
                        "expansion": null,
                        "file_name": "src/main.rs",
                        "is_primary": true,
                        "label": null,
                        "line_end": 1,
                        "line_start": 1,
                        "suggested_replacement": "",
                        "suggestion_applicability": "MachineApplicable",
                        "text":
                        [
                            {
                                "highlight_end": 56,
                                "highlight_start": 23,
                                "text": "pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;"
                            }
                        ]
                    }
                ]
            }
        ],
        "code":
        {
            "code": "type_alias_bounds",
            "explanation": null
        },
        "level": "warning",
        "message": "bounds on generic parameters are not enforced in type aliases",
        "spans":
        [
            {
                "byte_end": 41,
                "byte_start": 24,
                "column_end": 42,
                "column_start": 25,
                "expansion": null,
                "file_name": "src/main.rs",
                "is_primary": true,
                "label": null,
                "line_end": 1,
                "line_start": 1,
                "suggested_replacement": null,
                "suggestion_applicability": null,
                "text":
                [
                    {
                        "highlight_end": 42,
                        "highlight_start": 25,
                        "text": "pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;"
                    }
                ]
            },
            {
                "byte_end": 48,
                "byte_start": 44,
                "column_end": 49,
                "column_start": 45,
                "expansion": null,
                "file_name": "src/main.rs",
                "is_primary": true,
                "label": null,
                "line_end": 1,
                "line_start": 1,
                "suggested_replacement": null,
                "suggestion_applicability": null,
                "text":
                [
                    {
                        "highlight_end": 49,
                        "highlight_start": 45,
                        "text": "pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;"
                    }
                ]
            },
            {
                "byte_end": 55,
                "byte_start": 51,
                "column_end": 56,
                "column_start": 52,
                "expansion": null,
                "file_name": "src/main.rs",
                "is_primary": true,
                "label": null,
                "line_end": 1,
                "line_start": 1,
                "suggested_replacement": null,
                "suggestion_applicability": null,
                "text":
                [
                    {
                        "highlight_end": 56,
                        "highlight_start": 52,
                        "text": "pub type MyResult<T, E: std::error::Error + Send + Sync> = Result<T, E>;"
                    }
                ]
            }
        ]
    }
}

This has three overlapping spans that suggest a replacement of an empty string:

  • 22..41
  • 22..48
  • 22..55

I think it might be feasible to support this. At least, the new diff output from rustc is able to handle it, and clicking the "fix" suggestions in my editor is able to handle it (the regions are "smart" and know when the text within it is modified).

Note: This is relatively new behavior introduced by rust-lang/rustfix#195.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Command-fixS-needs-infoStatus: Needs more info, such as a reproduction or more background for a feature request.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions