- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Description
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.