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

Prevent generic pattern types from being used in libstd #136584

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Feb 5, 2025

Pattern types should follow the same rules that patterns follow. So a pattern type range must not wrap and not be empty. While we reject such invalid ranges at layout computation time, that only happens during monomorphization in the case of const generics. This is the exact same issue as other const generic math has, and since there's no solution there yet, I put these pattern types behind a separate incomplete feature.

These are not necessary for the pattern types MVP (replacing the layout range attributes in libcore and rustc).

cc #136574 (new tracking issue for the generic_pattern_types feature gate)

r? @lcnr

cc @scottmcm @joshtriplett

@rustbot
Copy link
Collaborator

rustbot commented Feb 5, 2025

changes to the core type system

cc @compiler-errors, @lcnr

@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 Feb 5, 2025
@rust-log-analyzer

This comment has been minimized.

@oli-obk oli-obk force-pushed the pattern-types-generic branch from b025089 to f12b963 Compare February 5, 2025 15:06
Comment on lines +714 to +722
self.out.push(traits::Obligation::with_depth(
tcx,
cause.clone(),
self.recursion_depth,
self.param_env,
ty::Binder::dummy(ty::PredicateKind::Clause(
ty::ClauseKind::ConstArgHasType(c, subty),
)),
));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For now this check is redundant, but it may not be anymore in the future, so I put it here just in case

Copy link
Member

@BoxyUwU BoxyUwU Feb 5, 2025

Choose a reason for hiding this comment

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

This feels somewhat structurally wrong to me 🤔 I think I would expect us to want a more general way to require a pattern to be of a specific type in order for a pattern type to be wf. So pretty much PatArgHasType similar to how we have ConstArgHasType. Kind of thinking about this as if we had pattern generics and is was some struct Is<T, pat P: T>(/* builtin */) and so we need to be checking the range pattern is correctly typed.

I think this is in practice correct though- we're just skipping having a PatArgHasType. I think for wf(E..E2) to hold we'd require PatArgHasType(E..E2, T) which itself would require ConstArgHasType(E, T) ConstArgHasType(E2, T) which is just what you're doing here 🤔 And if we dont have a general pattern generics system, only these TyKind::Pat we might aswell just not add a new predicate and inline the logic into wf predicates for TyKind::Pat 👍

lgtm

Comment on lines +724 to +728
let c = self.tcx().normalize_erasing_regions(
self.infcx.typing_env(self.param_env),
c,
);
if c.has_aliases() || c.has_param() {
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 a bit fishy, but I needed more than ClauseKind::ConstEvaluatable. ConstEvaluatable only checks that the constant itself will not fail to evaluate, which a generic parameter will also not (due to how we're enforcing things with const generics elsewhere).

So I took the knowledge that these constants always have concrete types and will normalize to error constants if they have errors themselves, to just evaluate here and check if there are still params or aliases around after normalization.

Oh and I need to normalize, can't just check for aliases and params, since we treat any unevaluated const as an alias, even if it refers to a free const. Which I guess makes sense as we want to cause normalization to actually get to the const and evaluate it.

Copy link
Member

Choose a reason for hiding this comment

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

I think you can/should just use c.has_param() and forget about even normalizing- min const generics doesn't permit Foo<{ <T as Trait>::USIZE }> where the assoc const can be normalized to usize regardless of T so I think design wise it's fine to not be "clever" here and just say that referring to generic parameters syntactically is forbidden.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure why you need to check for aliases 🤔

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 5, 2025

r? @BoxyUwU unless you specifically want a review from lcnr? though my understanding was that they are not particularly involved with pattern types

@rustbot rustbot assigned BoxyUwU and unassigned lcnr Feb 5, 2025
@BoxyUwU BoxyUwU 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 Feb 5, 2025
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
Development

Successfully merging this pull request may close these issues.

6 participants