-
-
Notifications
You must be signed in to change notification settings - Fork 14.9k
trait cache can be poisoned through an associated type #42796
Copy link
Copy link
Closed
Labels
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Metadata
Metadata
Assignees
Labels
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.
I was trying to root out the root cause of #39970 and I found this:
Meta
STR
Expected result
Code does not compile, because it attempts to copy a string..
Actual result
Code compiles, is UB, generally prints
0wned!Explanation
The global fulfilled predicates cache (
GlobalFulfilledPredicates) tries to cache "environment-independent" predicates. The idea is that if a predicate contains neither parameters nor inference variables, then whether it holds is unaffected by the parameter environment.This property almost holds - because in the absence of inference variables, trait impl search is "predicative", its results are independent of the universe of types, and therefore can be transferred from a "maximal universe" where the type parameters can be assigned variables.
However, that argument isn't 100% correct. If predicates are inconsistent, then there can be no such "maximal universe", and so
String: Copymight be implied by<String as Mirror<T>>::Image: Copy.We can say that this would be "fixed by Chalk" (as of course, in the absence of "intelligent" caching, this is not a problem), but that assumes the implementation of Chalk would not make the same mistake. I think a good way to fix this would be to check global predicates in the empty environment directly - if the current environment is consistent that will return the correct result, and if it is inconsistent we already don't always care about any kind of stability (e.g. we occasionally "know" that
[T]is neverSized, even if some predicate tries to claim so).cc @nikomatsakis @aturon @RalfJung (are you interested in trait systems?)