diff options
| author | bors <bors@rust-lang.org> | 2024-07-03 03:48:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-03 03:48:06 +0000 |
| commit | d163e5e515d470a713f7d6907852904622a85d4e (patch) | |
| tree | fbc2c74e3ee311650b3962e6f0836c1fd0fb5747 /compiler | |
| parent | 67f0d43890801f50ef2d24cd66de523f89ccb157 (diff) | |
| parent | 994b58fee7e66c25d4b13a8a95feaff650088301 (diff) | |
| download | rust-d163e5e515d470a713f7d6907852904622a85d4e.tar.gz rust-d163e5e515d470a713f7d6907852904622a85d4e.zip | |
Auto merge of #123737 - compiler-errors:alias-wf, r=lcnr
Check alias args for WF even if they have escaping bound vars
#### What
This PR stops skipping arguments of aliases if they have escaping bound vars, instead recursing into them and only discarding the resulting obligations referencing bounds vars.
#### An example:
From the test:
```
trait Trait {
type Gat<U: ?Sized>;
}
fn test<T>(f: for<'a> fn(<&'a T as Trait>::Gat<&'a [str]>)) where for<'a> &'a T: Trait {}
//~^ ERROR the size for values of type `[()]` cannot be known at compilation time
fn main() {}
```
We now prove that `str: Sized` in order for `&'a [str]` to be well-formed. We were previously unconditionally skipping over `&'a [str]` as it referenced a buond variable. We now recurse into it and instead only discard the `[str]: 'a` obligation because of the escaping bound vars.
#### Why?
This is a change that improves consistency about proving well-formedness earlier in the pipeline, which is necessary for future work on where-bounds in binders and correctly handling higher-ranked implied bounds. I don't expect this to fix any unsoundness.
#### What doesn't it fix?
Specifically, this doesn't check projection predicates' components are well-formed, because there are too many regressions: https://github.com/rust-lang/rust/pull/123737#issuecomment-2052198478
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs | 12 |
1 files changed, 3 insertions, 9 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 066755f7b3e..e3952679f96 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -437,12 +437,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. - fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) { - self.compute_alias_term(data.into()); - } - - /// Pushes the obligations required for an alias (except inherent) to be WF - /// into `self.out`. fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) { // A projection is well-formed if // @@ -498,7 +492,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.out.extend(obligations); } - self.compute_projection_args(data.args); + data.args.visit_with(self); } fn compute_projection_args(&mut self, args: GenericArgsRef<'tcx>) { @@ -702,8 +696,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> { } ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { - self.compute_alias_ty(data); - return; // Subtree handled by compute_projection. + let obligations = self.nominal_obligations(data.def_id, data.args); + self.out.extend(obligations); } ty::Alias(ty::Inherent, data) => { self.compute_inherent_projection(data); |
