Skip to content

"implement the missing item: …" suggestion does not substitute type parameter #89220

Closed
@Tamschi

Description

@Tamschi

Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=0bc82986aeab6421699562569505aa40

trait A<T> {
    fn a(&self) -> &T;
}
struct B {}

impl<T> A<B> for T {} // <-- error[E0046]: not all trait items implemented, missing: `a`

The current output is:

(Note: The whitespace in strings is probably not real due to my manual JSON prettification.)

compiler-message json
{
    "reason": "compiler-message",
    "package_id": "scraps-again 0.1.0 (path+file:///C:/Users/Tamme/Documents/Projekte/scraps-again)",
    "manifest_path": "C:\\Users\\Tamme\\Documents\\Projekte\\scraps-again\\Cargo.toml",
    "target": {
        "kind": [
            "lib"
        ],
        "crate_types": [
            "lib"
        ],
        "name": "scraps-again",
        "src_path": "C:\\Users\\Tamme\\Documents\\Projekte\\scraps-again\\src\\lib.rs",
        "edition": "2018",
        "doc": true,
        "doctest": true,
        "test": true
    },
    "message": {
        "rendered": "error[E0046]: not all trait items implemented, missing: `a`\n --> src\\lib.rs: 6: 1\n  |\n2 |     fn a(&self) -> &T;\n  |     ------------------ `a` from trait\n...\n6 | impl<T> A<B> for T {}\n  | ^^^^^^^^^^^^^^^^^^ missing `a` in implementation\n\n",
        "children": [
            {
                "children": [],
                "code": null,
                "level": "help",
                "message": "implement the missing item: `fn a(&self) -> &T { todo!()            }`",
                "rendered": null,
                "spans": [
                    {
                        "byte_end": 71,
                        "byte_start": 71,
                        "column_end": 21,
                        "column_start": 21,
                        "expansion": null,
                        "file_name": "src\\lib.rs",
                        "is_primary": true,
                        "label": null,
                        "line_end": 6,
                        "line_start": 6,
                        "suggested_replacement": "fn a(&self) -> &T { todo!()                    }\n",
                        "suggestion_applicability": "HasPlaceholders",
                        "text": [
                            {
                                "highlight_end": 21,
                                "highlight_start": 21,
                                "text": "impl<T> A<B> for T {}"
                            }
                        ]
                    }
                ]
            }
        ],
        "code": {
            "code": "E0046",
            "explanation": "Items are missing in a trait implementation.\n\nErroneous code example:\n\n```compile_fail,E0046\ntrait Foo {\n    fn foo();\n        }\n\nstruct Bar;\n\nimpl Foo for Bar {}\n // error: not all trait items implemented, missing: `foo`\n```\n\nWhen trying to make some type implement a trait `Foo`, you must, at minimum,\nprovide implementations for all of `Foo`'s required methods (meaning the\nmethods that do not have default implementations), as well as any required\ntrait items like associated types or constants. Example:\n\n```\ntrait Foo {\n    fn foo();\n}\n\nstruct Bar;\n\nimpl Foo for Bar {\n    fn foo() {} // ok!\n}\n```\n"
        },
        "level": "error",
        "message": "not all trait items implemented, missing: `a`",
        "spans": [
            {
                "byte_end": 69,
                "byte_start": 51,
                "column_end": 19,
                "column_start": 1,
                "expansion": null,
                "file_name": "src\\lib.rs",
                "is_primary": true,
                "label": "missing `a` in implementation",
                "line_end": 6,
                "line_start": 6,
                "suggested_replacement": null,
                "suggestion_applicability": null,
                "text": [
                    {
                        "highlight_end": 19,
                        "highlight_start": 1,
                        "text": "impl<T> A<B> for T {}"
                    }
                ]
            },
            {
                "byte_end": 35,
                "byte_start": 17,
                "column_end": 23,
                "column_start": 5,
                "expansion": null,
                "file_name": "src\\lib.rs",
                "is_primary": false,
                "label": "`a` from trait",
                "line_end": 2,
                "line_start": 2,
                "suggested_replacement": null,
                "suggestion_applicability": null,
                "text": [
                    {
                        "highlight_end": 23,
                        "highlight_start": 5,
                        "text": "    fn a(&self) -> &T;"
                    }
                ]
            }
        ]
    }
}

(with "suggested_replacement": "fn a(&self) -> &T { todo!() }\n" and its message being invalid)

Ideally the output should look like:

compiler-message json
{
    "reason": "compiler-message",
    "package_id": "scraps-again 0.1.0 (path+file:///C:/Users/Tamme/Documents/Projekte/scraps-again)",
    "manifest_path": "C:\\Users\\Tamme\\Documents\\Projekte\\scraps-again\\Cargo.toml",
    "target": {
        "kind": [
            "lib"
        ],
        "crate_types": [
            "lib"
        ],
        "name": "scraps-again",
        "src_path": "C:\\Users\\Tamme\\Documents\\Projekte\\scraps-again\\src\\lib.rs",
        "edition": "2018",
        "doc": true,
        "doctest": true,
        "test": true
    },
    "message": {
        "rendered": "error[E0046]: not all trait items implemented, missing: `a`\n --> src\\lib.rs: 6: 1\n  |\n2 |     fn a(&self) -> &T;\n  |     ------------------ `a` from trait\n...\n6 | impl<T> A<B> for T {}\n  | ^^^^^^^^^^^^^^^^^^ missing `a` in implementation\n\n",
        "children": [
            {
                "children": [],
                "code": null,
                "level": "help",
                "message": "implement the missing item: `fn a(&self) -> &B { todo!()            }`",
                "rendered": null,
                "spans": [
                    {
                        "byte_end": 71,
                        "byte_start": 71,
                        "column_end": 21,
                        "column_start": 21,
                        "expansion": null,
                        "file_name": "src\\lib.rs",
                        "is_primary": true,
                        "label": null,
                        "line_end": 6,
                        "line_start": 6,
                        "suggested_replacement": "fn a(&self) -> &B { todo!()                    }\n",
                        "suggestion_applicability": "HasPlaceholders",
                        "text": [
                            {
                                "highlight_end": 21,
                                "highlight_start": 21,
                                "text": "impl<T> A<B> for T {}"
                            }
                        ]
                    }
                ]
            }
        ],
        "code": {
            "code": "E0046",
            "explanation": "Items are missing in a trait implementation.\n\nErroneous code example:\n\n```compile_fail,E0046\ntrait Foo {\n    fn foo();\n        }\n\nstruct Bar;\n\nimpl Foo for Bar {}\n // error: not all trait items implemented, missing: `foo`\n```\n\nWhen trying to make some type implement a trait `Foo`, you must, at minimum,\nprovide implementations for all of `Foo`'s required methods (meaning the\nmethods that do not have default implementations), as well as any required\ntrait items like associated types or constants. Example:\n\n```\ntrait Foo {\n    fn foo();\n}\n\nstruct Bar;\n\nimpl Foo for Bar {\n    fn foo() {} // ok!\n}\n```\n"
        },
        "level": "error",
        "message": "not all trait items implemented, missing: `a`",
        "spans": [
            {
                "byte_end": 69,
                "byte_start": 51,
                "column_end": 19,
                "column_start": 1,
                "expansion": null,
                "file_name": "src\\lib.rs",
                "is_primary": true,
                "label": "missing `a` in implementation",
                "line_end": 6,
                "line_start": 6,
                "suggested_replacement": null,
                "suggestion_applicability": null,
                "text": [
                    {
                        "highlight_end": 19,
                        "highlight_start": 1,
                        "text": "impl<T> A<B> for T {}"
                    }
                ]
            },
            {
                "byte_end": 35,
                "byte_start": 17,
                "column_end": 23,
                "column_start": 5,
                "expansion": null,
                "file_name": "src\\lib.rs",
                "is_primary": false,
                "label": "`a` from trait",
                "line_end": 2,
                "line_start": 2,
                "suggested_replacement": null,
                "suggestion_applicability": null,
                "text": [
                    {
                        "highlight_end": 23,
                        "highlight_start": 5,
                        "text": "    fn a(&self) -> &T;"
                    }
                ]
            }
        ]
    }
}

(with "suggested_replacement": "fn a(&self) -> &B { todo!() }\n" and its message being valid)


This seems like something the compiler could in theory take care of, and it's not always immediately clear to the programmer (that is: me) why exactly there's an error highlighted if there's another T like in the example above.

That said, the error message resulting from the invalid suggestion already does a fairly decent job of pointing out the fix here, and the suggestion there ("change the output type to match the trait: &B") is correct.


I first misfiled this as rust-lang/rust-analyzer#10327 after reporting rust-lang/rust-analyzer#10326. If the generic type parameter is expanded to something like dyn 'a + Trait, it would also need to be parenthesised in some cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions