Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reject unconstrained lifetimes in type_of(assoc_ty) instead of during wfcheck of the impl item #127973

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Jul 19, 2024

Opened to discuss as part of https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/unconstrained.20lifetimes.20in.20impls

Lifetimes are allowed to be unconstrained on impls because it made some libcore macros simpler and it was a breaking change to fix it. This becomes a problem when the lifetime is used in a nonconstraining way (e.g. in an associated item), but in a way that it can be used (e.g. via associated types). Associated functions are not an issue, because they must already have a compatible signature to the trait's assoc function decls, which means unconstrained lifetimes can't be a part of them (except via assoc types).

While the current system is sound, it also doesn't mention in the diagnostic why the lifetime is not permitted when it is permitted in other situations.

Instead of rejecting those lifetimes in wfcheck, we now reject them in type_of of associated types. Thus, during hir ty lowering of assoc types, we report any types with unconstrained lifetimes. since this is happening on the hir, we have a fairly good span to report to the user.

We could instead walk the hir and look for the offending lifetime (just for improving the span), but I have a deeper reason for this change:

We can now move the remainder of the check from wfcheck to explicit_predicates_of, which already computes the necessary information, and is on a regular query code path, so we can taint it and suppress follow-up errors and ICEs

fixes #123141
fixes #124350
fixes #125874
fixes #126942

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 19, 2024
@rust-log-analyzer

This comment has been minimized.

MyFrom::my_from(self.0).ok().unwrap()
}
}

fn main() {
let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
//~^ ERROR: no method named `my_index` found for struct `Scope`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is funny and should probably have some more taint tracking to get eliminated (same with the TAIT cycle above)

pub struct GenericPredicates<'tcx> {
pub parent: Option<DefId>,
pub predicates: &'tcx [(Clause<'tcx>, Span)],
pub effects_min_tys: &'tcx ty::List<Ty<'tcx>>,
pub tainted_by_errors: Result<(), ErrorGuaranteed>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain what it means to be tainted here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. If preferred I can also register a dummy predicate {error}: Sized or sth, that would probably result in similar behaviour

@oli-obk
Copy link
Contributor Author

oli-obk commented Jul 23, 2024

FWIW I tried an alternative design that would taint impl_trait_header instead of predicates_of, but that does not work at this time, because if generic parameters are used in bounds before their own bounds a processed, we get bogus ambiguity errors. I hope that's a thing the next solver will also fix, as it's quite funky to rely on that. See https://github.com/oli-obk/rust/pull/new/uplift_wf_checks2 for the branch with the other approach.

while these can be resolved (see https://github.com/oli-obk/rust/pull/new/uplift_wf_checks3), we still have several new cycles:

  • type_of(assoc_ty) checks whether impl_trait_header is None in order to do inherent assoc ty feature gating (easily resolved by checking the hir for of_trait)
  • fn_sig(assoc_fn) if the signature contains Self::Foo, we'll need the trait and impl self type to produce all assoc items with the right name (possibly from super traits).

@rust-log-analyzer

This comment has been minimized.

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding SelectionError -- I wonder if we should instead treat the goal as successful but constrain all the variables with Error instead.

@rust-log-analyzer

This comment has been minimized.

Comment on lines +637 to +604
if let Err(guar) = unsatisfied_predicates.error_reported() {
return guar;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary to avoid bogus diagnostics like


error[E0599]: the method `my_index` exists for struct `Scope<_>`, but its trait bounds were not satisfied
  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:50:51
   |
LL | struct Scope<T>(Phantom2<DummyT<T>>);
   | --------------- method `my_index` not found for this struct because it doesn't satisfy `Scope<{type error}>: MyIndex<DummyT<{type error}>>`
...
LL |     let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
   |                                                   ^^^^^^^^ method cannot be called on `Scope<_>` due to unsatisfied trait bounds
   |
note: trait bound `{type error}: Sized` was not satisfied
  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
   |
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
   |      ^                               ^  ------------------     --------
   |      |                               |
   |      |                               unsatisfied trait bound introduced here
   |      unsatisfied trait bound introduced here
   = help: items from traits can only be used if the trait is implemented and in scope
note: `MyIndex` defines an item `my_index`, perhaps you need to implement it
  --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:9:1
   |
LL | trait MyIndex<T> {
   | ^^^^^^^^^^^^^^^^
help: consider relaxing the type parameter's implicit `Sized` bound
   |
LL | impl<T: ?Sized + MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
   |         ++++++++
help: consider relaxing the type parameter's implicit `Sized` bound
   |
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U: ?Sized> MyIndex<DummyT<T>> for Scope<U> {
   |                                       ++++++++

Not sure yet how to generally avoid these (I don't want to just hide the predicate, I want to hide the entire error), but this change doesn't make things worse really, so 🤷

@bors
Copy link
Contributor

bors commented Jul 29, 2024

☔ The latest upstream changes (presumably #125443) made this pull request unmergeable. Please resolve the merge conflicts.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@Dylan-DPC Dylan-DPC added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 21, 2024
@alex-semenyuk alex-semenyuk removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Oct 8, 2024
@alex-semenyuk alex-semenyuk added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 8, 2024
@Dylan-DPC Dylan-DPC added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 3, 2024
@rust-log-analyzer
Copy link
Collaborator

The job mingw-check-tidy failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
           --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint,cpp:fmt
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---
#13 2.704 Building wheels for collected packages: reuse
#13 2.705   Building wheel for reuse (pyproject.toml): started
#13 2.953   Building wheel for reuse (pyproject.toml): finished with status 'done'
#13 2.954   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-manylinux_2_35_x86_64.whl size=132720 sha256=026f3bb0f1aa8090b861fd0a0939cb1a782396d84c8aab7875096557d637a0f6
#13 2.954   Stored in directory: /tmp/pip-ephem-wheel-cache-d7ssyv7y/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#13 2.957 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, jinja2, chardet, attrs
#13 3.337 Successfully installed attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 jinja2-3.1.4 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#13 3.337 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#13 3.856 Collecting virtualenv
#13 3.856 Collecting virtualenv
#13 3.912   Downloading virtualenv-20.28.0-py3-none-any.whl (4.3 MB)
#13 4.145      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.3/4.3 MB 18.5 MB/s eta 0:00:00
#13 4.184 Collecting distlib<1,>=0.3.7
#13 4.193   Downloading distlib-0.3.9-py2.py3-none-any.whl (468 kB)
#13 4.208      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.0/469.0 KB 36.3 MB/s eta 0:00:00
#13 4.239 Collecting platformdirs<5,>=3.9.1
#13 4.248   Downloading platformdirs-4.3.6-py3-none-any.whl (18 kB)
#13 4.283 Collecting filelock<4,>=3.12.2
#13 4.292   Downloading filelock-3.16.1-py3-none-any.whl (16 kB)
#13 4.374 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#13 4.553 Successfully installed distlib-0.3.9 filelock-3.16.1 platformdirs-4.3.6 virtualenv-20.28.0
#13 DONE 4.6s

#14 [7/8] COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
#14 DONE 0.0s
---
DirectMap4k:      344000 kB
DirectMap2M:     8044544 kB
DirectMap1G:    10485760 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint,cpp:fmt
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint,cpp:fmt
    Finished `dev` profile [unoptimized] target(s) in 0.04s
##[endgroup]
WARN: currently no CI rustc builds have rustc debug assertions enabled. Please either set `rust.debug-assertions` to `false` if you want to use download CI rustc or set `rust.download-rustc` to `false`.
downloading https://static.rust-lang.org/dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz
---
##[endgroup]
fmt check
Diff in /checkout/compiler/rustc_middle/src/ty/generics.rs:2:
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
 use rustc_macros::{HashStable, TyDecodable, TyEncodable};
-use rustc_span::{ErrorGuaranteed, Span};
 use rustc_span::symbol::{Symbol, kw};
+use rustc_span::{ErrorGuaranteed, Span};
 
 
 use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt};
fmt error: Running `"/checkout/obj/build/x86_64-unknown-linux-gnu/rustfmt/bin/rustfmt" "--config-path" "/checkout" "--edition" "2021" "--unstable-features" "--skip-children" "--check" "/checkout/tests/rustdoc-json/trait_alias.rs" "/checkout/tests/rustdoc-json/stripped_modules.rs" "/checkout/tests/rustdoc-json/pub_mod_in_private_mod.rs" "/checkout/tests/rustdoc-json/assoc_type.rs" "/checkout/tests/rustdoc-json/generic_impl.rs" "/checkout/compiler/rustc_middle/src/ty/parameterized.rs" "/checkout/compiler/rustc_middle/src/ty/closure.rs" "/checkout/compiler/rustc_middle/src/ty/vtable.rs" "/checkout/compiler/rustc_middle/src/ty/abstract_const.rs" "/checkout/compiler/rustc_middle/src/ty/adt.rs" "/checkout/compiler/rustc_middle/src/ty/impls_ty.rs" "/checkout/compiler/rustc_middle/src/ty/codec.rs" "/checkout/compiler/rustc_middle/src/ty/generic_args.rs" "/checkout/compiler/rustc_middle/src/ty/error.rs" "/checkout/compiler/rustc_middle/src/ty/predicate.rs" "/checkout/compiler/rustc_middle/src/ty/rvalue_scopes.rs" "/checkout/compiler/rustc_middle/src/ty/typeck_results.rs" "/checkout/compiler/rustc_middle/src/ty/flags.rs" "/checkout/compiler/rustc_middle/src/ty/walk.rs" "/checkout/compiler/rustc_middle/src/ty/layout.rs" "/checkout/compiler/rustc_middle/src/ty/visit.rs" "/checkout/compiler/rustc_middle/src/ty/consts.rs" "/checkout/compiler/rustc_middle/src/ty/intrinsic.rs" "/checkout/compiler/rustc_middle/src/ty/pattern.rs" "/checkout/compiler/rustc_middle/src/ty/erase_regions.rs" "/checkout/compiler/rustc_middle/src/ty/generics.rs" "/checkout/tests/auxiliary/minicore.rs" "/checkout/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs" "/checkout/compiler/rustc_middle/src/ty/inhabitedness/mod.rs" "/checkout/compiler/rustc_middle/src/ty/assoc.rs" "/checkout/compiler/rustc_middle/src/ty/diagnostics.rs" "/checkout/compiler/rustc_middle/src/ty/structural_impls.rs" "/checkout/compiler/rustc_middle/src/ty/print/pretty.rs" "/checkout/compiler/rustc_middle/src/ty/print/mod.rs" "/checkout/compiler/rustc_middle/src/ty/context.rs" "/checkout/compiler/rustc_middle/src/ty/elaborate_impl.rs" "/checkout/compiler/rustc_middle/src/ty/consts/kind.rs" "/checkout/compiler/rustc_middle/src/ty/consts/int.rs" "/checkout/compiler/rustc_middle/src/ty/consts/valtree.rs" "/checkout/compiler/rustc_middle/src/ty/trait_def.rs" "/checkout/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs" "/checkout/compiler/rustc_middle/src/ty/opaque_types.rs" "/checkout/compiler/rustc_middle/src/ty/sty.rs" "/checkout/compiler/rustc_middle/src/ty/region.rs" "/checkout/compiler/rustc_middle/src/ty/context/tls.rs" "/checkout/compiler/rustc_middle/src/ty/list.rs" "/checkout/compiler/rustc_middle/src/ty/relate.rs" "/checkout/compiler/rustc_middle/src/ty/adjustment.rs" "/checkout/compiler/rustc_middle/src/ty/fold.rs" "/checkout/compiler/rustc_middle/src/ty/fast_reject.rs" "/checkout/compiler/rustc_middle/src/ty/mod.rs" "/checkout/compiler/rustc_middle/src/ty/cast.rs" "/checkout/compiler/rustc_middle/src/ty/util.rs" "/checkout/compiler/rustc_middle/src/ty/instance.rs" "/checkout/compiler/rustc_middle/src/metadata.rs" "/checkout/compiler/rustc_middle/src/util/find_self_call.rs" "/checkout/compiler/rustc_middle/src/util/call_kind.rs" "/checkout/compiler/rustc_middle/src/util/bug.rs" "/checkout/compiler/rustc_middle/src/util/common.rs" "/checkout/compiler/rustc_middle/src/util/common/tests.rs" "/checkout/compiler/rustc_middle/src/util/mod.rs" "/checkout/compiler/rustc_middle/src/lib.rs" "/checkout/compiler/stable_mir/src/target.rs" "/checkout/tests/rustdoc-json/the_smallest.rs"` failed.
If you're running `tidy`, try again with `--bless`. Or, if you just want to format code, run `./x.py fmt` instead.
  local time: Tue Dec  3 17:14:57 UTC 2024
  network time: Tue, 03 Dec 2024 17:14:57 GMT
##[error]Process completed with exit code 1.
Post job cleanup.

@compiler-errors
Copy link
Member

compiler-errors commented Dec 3, 2024

Of all of the tests you've linked, as far as I can tell only only one of them continues to ICE (#125874). Am I testing them wrong, or is this true?

I think we should probably reformulate this PR; it seems a bit too invasive for me to be comfortable with landing it, and I think we can find an approach that requires tracking less state than what this PR does.

@oli-obk
Copy link
Contributor Author

oli-obk commented Dec 4, 2024

I think we should probably reformulate this PR; it seems a bit too invasive for me to be comfortable with landing it, and I think we can find an approach that requires tracking less state than what this PR does.

I wonder if we can get most of the way just by stripping lifetimes that are unmentioned in the signature in lowering or generics_of, and then making the error reporting on "unknown lifetime" figure out that it's an unconstrained one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
7 participants