Repository navigation
wfcheck: name the item that discards an unused type parameter - #161467
rust-bors[bot] merged 1 commit into
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
|
on the "only used recursively" branch, since i kept almost fixing it and stopping. it kicks in whenever the param is mentioned and the item turns out cyclical, but it only checks the item is on a cycle, never that the param goes round it. so struct Bar<X> {}
struct Foo<T> { bar: Bar<T>, next: Option<Box<Foo<u8>>> }blames what's here gives that code the piece it was missing, we now know which item discards each mention. but you can't just drop the discarded ones. with two mutually recursive structs the param is bivariant because of the cycle you're trying to confirm, so you'd throw out your own evidence. it has to follow param slots rather than defids. i had that working and it came out bigger than the fix in this pr, so i took it back out. happy to do it as a follow up. |
|
This isn't something I'm familiar with. r? @fmease maybe? or reroll? |
| for arg in args.args { | ||
| let hir::GenericArg::Type(ty) = arg else { | ||
| intravisit::walk_generic_arg(self, arg); | ||
| continue; | ||
| }; | ||
| let outer = self.discarded_by; | ||
| if self.discarded_by.is_none() && self.discards_nth_ty_arg(def_id, nth_ty_arg) { | ||
| self.discarded_by = Some(def_id); | ||
| } | ||
| self.visit_ty(ty); | ||
| self.discarded_by = outer; | ||
| nth_ty_arg += 1; | ||
| } |
There was a problem hiding this comment.
All of this is so much checking for no practical benefit IINM. Re-querying the variances of ADTs in two separate places even just to double-check that the parameters are bivariant.
Can you come up with an example of any type expression that mentions an (unconstrained) bivariant type parameter but does not "use" it? Personally speaking I couldn't & I really tried. As soon as it's mentioned somewhere it's either used and thus not bivariant or unused & bivariant.
So what I'm saying is that we don't need to perform any of these complex checks. I would even accept a PR that just drops the word likely from … is named here, but is likely unused in the containing type but I guess "containing" is indeed a bit jargon-y. So just reword it to "… is named here, but is not used in the type that wraps it".
There was a problem hiding this comment.
To illustrate what I mean (maybe not needed): Let's assume we're looking at struct MainType<T> { ... }, we know that T is bivariant & unconstrained thus reaching report_bivariance & we're now trying to find usages of T in ....
Then what are the options? If we encounter Adt<..., T, ...> we know that it is not used1 by Adt. Otherwise it wouldn't be bivariant or it would be constrained. Personally speaking, I don't consider constrained bivariant parameters to be used for the purposes of this diagnostic. In any case, we know that the requirement is not satisfied in MainType & that we emit an additional "trait bound unsatisfied" diagnostic which is probably more helpful in such situations anyway.
Etc. you get my point.
Footnotes
-
or only used recursively, of course. ↩
There was a problem hiding this comment.
I've removed the wrapper tracking and alias traversal and restored the original span collector. I wanted to name the type that drops the parameter because I thought that would make the error easier to follow, especially through aliases. But by the time we reach report_bivariance, the caller has already ruled out parameters constrained by variance or associated-type equalities. We already know enough to say the parameter is unused without checking those paths again.
I don't think naming the wrapper adds enough here to justify all that extra code. Your wording, "is named here, but is not used in the type that wraps it", gets the point across and removes the uncertainty that bothered me in the original message. I've used that and updated the test expectations. All four relevant UI tests pass.
|
|
@rustbot ready |
This comment has been minimized.
This comment has been minimized.
* Name the item that discards an unused type parameter E0392 pointed at the mention of the parameter with a label saying it "is likely unused in the containing type", which doesn't say much. It's unclear what the containing type is meant to be, and we hedge with "likely" even though we can just go look. Track the outermost item that throws the argument away while collecting the usage spans, and name it instead. For ADTs that's a bivariant parameter in `variances_of`. Type aliases have no variances of their own, so expand them and check whether the parameter reaches a position that constrains it -- an alias can mention the parameter and still discard it by handing it to something else that ignores it. Free aliases go through `expand_free_alias_tys` rather than `type_of`, since a diverging one would otherwise recurse forever. When none of that pins down a culprit, fall back to saying the mention doesn't constrain the parameter instead of guessing. * Cover free alias types in the unused type parameter error A chain of free aliases used to hide the item doing the discarding, and the same alias applied to different arguments has to be expanded twice or a use of the parameter goes missing. The overflow case is worth a test of its own: with a growing argument there's no repeated alias to spot the divergence with, so the recursion limit is the only thing that stops the walk. * Simplify the unused type parameter diagnostic Variance and associated-type constraints are checked before this diagnostic runs. Restore the span collector and use a definite label without identifying which wrapper discards the parameter. Update the diagnostic expectations and test comments accordingly.
|
🔨 3 commits were squashed into 7ede218. |
5b6650e to
7ede218
Compare
…ame_discarding_item, r=fmease wfcheck: name the item that discards an unused type parameter fixes rust-lang#161365 label was "`T` is named here, but is likely unused in the containing type". the "likely" is the part that bugs me. we can just go look, so now it does: ``` LL | bar: Bar<T>, | - `T` is named here, but `Bar` does not use it ``` while collecting the usage spans it holds on to the outermost thing that throws the argument away. adts are easy, bivariant param in variances_of. aliases have no variances so you expand them and see what's left, and my first version of that only looked for the param in the rhs, which is wrong. `type Alias<T> = DropFirst<T, u8>` mentions T and still drops it. so it walks the expansion skipping bivariant slots. (nested args blame the outer one, `Bar<Vec<T>>` points at Bar.) if it can't work out who's responsible it falls back to "this does not constrain `T`". warning for whoever touches this next: type_of doesn't expand free aliases and you can't chase them yourself. `type Recur<T> = Recur<(T,)>` never repeats its args so there's nothing to stop on, stack goes. expand_free_alias_tys is the one with the limit. variance-overflow.rs has a comment at the top saying exactly this and i wrote it wrong anyway, so i stuck a case in there for the diagnostic path. tests in variance-unused-type-param.rs, new file for alias chains. there's a separate bug in the "only used recursively" branch right next to this one that i left alone, wrote up why in a comment.
…uwer Rollup of 9 pull requests Successful merges: - #163461 (Improve diagnostic deduplication) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - #163483 (Bump bootstrap compiler to 1.100.0 beta) - #161380 (only rerun const eval in next-solver if the const actually references opaques) - #162900 (Some refactorings around metadata encoding) - #163461 (Improve diagnostic deduplication) - #163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - #163584 ([triagebot] Ping me for debugger visualizer changes) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #162904 (Fix ICE for ambiguous candidates on method probing) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163281 (Add `f16` inline ASM support to `spirv.rs`) - #163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163405 (Remove some #[linkage] options) - #163530 (`const impl PartialEq` for `f16b`) - #163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - #163483 (Bump bootstrap compiler to 1.100.0 beta) - #161380 (only rerun const eval in next-solver if the const actually references opaques) - #162900 (Some refactorings around metadata encoding) - #163461 (Improve diagnostic deduplication) - #163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - #163584 ([triagebot] Ping me for debugger visualizer changes) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #162904 (Fix ICE for ambiguous candidates on method probing) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163281 (Add `f16` inline ASM support to `spirv.rs`) - #163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163405 (Remove some #[linkage] options) - #163530 (`const impl PartialEq` for `f16b`) - #163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - #163483 (Bump bootstrap compiler to 1.100.0 beta) - #161380 (only rerun const eval in next-solver if the const actually references opaques) - #162900 (Some refactorings around metadata encoding) - #163461 (Improve diagnostic deduplication) - #163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - #163584 ([triagebot] Ping me for debugger visualizer changes) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #162904 (Fix ICE for ambiguous candidates on method probing) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163281 (Add `f16` inline ASM support to `spirv.rs`) - #163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163405 (Remove some #[linkage] options) - #163530 (`const impl PartialEq` for `f16b`) - #163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
Rollup merge of #161467 - Dnreikronos:wfcheck/unused_param_name_discarding_item, r=fmease wfcheck: name the item that discards an unused type parameter fixes #161365 label was "`T` is named here, but is likely unused in the containing type". the "likely" is the part that bugs me. we can just go look, so now it does: ``` LL | bar: Bar<T>, | - `T` is named here, but `Bar` does not use it ``` while collecting the usage spans it holds on to the outermost thing that throws the argument away. adts are easy, bivariant param in variances_of. aliases have no variances so you expand them and see what's left, and my first version of that only looked for the param in the rhs, which is wrong. `type Alias<T> = DropFirst<T, u8>` mentions T and still drops it. so it walks the expansion skipping bivariant slots. (nested args blame the outer one, `Bar<Vec<T>>` points at Bar.) if it can't work out who's responsible it falls back to "this does not constrain `T`". warning for whoever touches this next: type_of doesn't expand free aliases and you can't chase them yourself. `type Recur<T> = Recur<(T,)>` never repeats its args so there's nothing to stop on, stack goes. expand_free_alias_tys is the one with the limit. variance-overflow.rs has a comment at the top saying exactly this and i wrote it wrong anyway, so i stuck a case in there for the diagnostic path. tests in variance-unused-type-param.rs, new file for alias chains. there's a separate bug in the "only used recursively" branch right next to this one that i left alone, wrote up why in a comment.
…uwer Rollup of 20 pull requests Successful merges: - rust-lang/rust#163483 (Bump bootstrap compiler to 1.100.0 beta) - rust-lang/rust#161380 (only rerun const eval in next-solver if the const actually references opaques) - rust-lang/rust#162900 (Some refactorings around metadata encoding) - rust-lang/rust#163461 (Improve diagnostic deduplication) - rust-lang/rust#163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - rust-lang/rust#163584 ([triagebot] Ping me for debugger visualizer changes) - rust-lang/rust#159021 (windows-gnu: enable native TLS) - rust-lang/rust#161467 (wfcheck: name the item that discards an unused type parameter) - rust-lang/rust#162618 (trait_selection: Preserve eager normalization failures) - rust-lang/rust#162904 (Fix ICE for ambiguous candidates on method probing) - rust-lang/rust#163064 (Avoid computing overflowed goal chains for crate dependencies) - rust-lang/rust#163281 (Add `f16` inline ASM support to `spirv.rs`) - rust-lang/rust#163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - rust-lang/rust#163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - rust-lang/rust#163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - rust-lang/rust#163405 (Remove some #[linkage] options) - rust-lang/rust#163530 (`const impl PartialEq` for `f16b`) - rust-lang/rust#163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - rust-lang/rust#163590 (Make `AllocatorNightly` less clever) - rust-lang/rust#163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - rust-lang/rust#163483 (Bump bootstrap compiler to 1.100.0 beta) - rust-lang/rust#161380 (only rerun const eval in next-solver if the const actually references opaques) - rust-lang/rust#162900 (Some refactorings around metadata encoding) - rust-lang/rust#163461 (Improve diagnostic deduplication) - rust-lang/rust#163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - rust-lang/rust#163584 ([triagebot] Ping me for debugger visualizer changes) - rust-lang/rust#159021 (windows-gnu: enable native TLS) - rust-lang/rust#161467 (wfcheck: name the item that discards an unused type parameter) - rust-lang/rust#162618 (trait_selection: Preserve eager normalization failures) - rust-lang/rust#162904 (Fix ICE for ambiguous candidates on method probing) - rust-lang/rust#163064 (Avoid computing overflowed goal chains for crate dependencies) - rust-lang/rust#163281 (Add `f16` inline ASM support to `spirv.rs`) - rust-lang/rust#163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - rust-lang/rust#163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - rust-lang/rust#163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - rust-lang/rust#163405 (Remove some #[linkage] options) - rust-lang/rust#163530 (`const impl PartialEq` for `f16b`) - rust-lang/rust#163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - rust-lang/rust#163590 (Make `AllocatorNightly` less clever) - rust-lang/rust#163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - #163483 (Bump bootstrap compiler to 1.100.0 beta) - #161380 (only rerun const eval in next-solver if the const actually references opaques) - #162900 (Some refactorings around metadata encoding) - #163461 (Improve diagnostic deduplication) - #163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - #163584 ([triagebot] Ping me for debugger visualizer changes) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #162904 (Fix ICE for ambiguous candidates on method probing) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163281 (Add `f16` inline ASM support to `spirv.rs`) - #163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163405 (Remove some #[linkage] options) - #163530 (`const impl PartialEq` for `f16b`) - #163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - rust-lang/rust#163483 (Bump bootstrap compiler to 1.100.0 beta) - rust-lang/rust#161380 (only rerun const eval in next-solver if the const actually references opaques) - rust-lang/rust#162900 (Some refactorings around metadata encoding) - rust-lang/rust#163461 (Improve diagnostic deduplication) - rust-lang/rust#163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - rust-lang/rust#163584 ([triagebot] Ping me for debugger visualizer changes) - rust-lang/rust#159021 (windows-gnu: enable native TLS) - rust-lang/rust#161467 (wfcheck: name the item that discards an unused type parameter) - rust-lang/rust#162618 (trait_selection: Preserve eager normalization failures) - rust-lang/rust#162904 (Fix ICE for ambiguous candidates on method probing) - rust-lang/rust#163064 (Avoid computing overflowed goal chains for crate dependencies) - rust-lang/rust#163281 (Add `f16` inline ASM support to `spirv.rs`) - rust-lang/rust#163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - rust-lang/rust#163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - rust-lang/rust#163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - rust-lang/rust#163405 (Remove some #[linkage] options) - rust-lang/rust#163530 (`const impl PartialEq` for `f16b`) - rust-lang/rust#163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - rust-lang/rust#163590 (Make `AllocatorNightly` less clever) - rust-lang/rust#163599 (Add union pattern reference change to relnotes)
fixes #161365
label was "
Tis named here, but is likely unused in the containing type". the "likely" is the part that bugs me. we can just go look, so now it does:while collecting the usage spans it holds on to the outermost thing that throws the argument away. adts are easy, bivariant param in variances_of. aliases have no variances so you expand them and see what's left, and my first version of that only looked for the param in the rhs, which is wrong.
type Alias<T> = DropFirst<T, u8>mentions T and still drops it. so it walks the expansion skipping bivariant slots. (nested args blame the outer one,Bar<Vec<T>>points at Bar.) if it can't work out who's responsible it falls back to "this does not constrainT".warning for whoever touches this next: type_of doesn't expand free aliases and you can't chase them yourself.
type Recur<T> = Recur<(T,)>never repeats its args so there's nothing to stop on, stack goes. expand_free_alias_tys is the one with the limit. variance-overflow.rs has a comment at the top saying exactly this and i wrote it wrong anyway, so i stuck a case in there for the diagnostic path.tests in variance-unused-type-param.rs, new file for alias chains.
there's a separate bug in the "only used recursively" branch right next to this one that i left alone, wrote up why in a comment.