TMI: Overriding
Oct. 17th, 2012 12:02 amToday, I finished fixing issue 2284 -- I'm just doing the final test run, then I'll submit a pull request (not push directly this time!)
This is sort of a weird bug. Rust had a notion of "kinds" that was distinct from our notion of traits, because kinds existed before traits did. If you know what kinds mean in other languages, it's more or less the same in Rust. If not: a kind is just the type of a type. Just like values have types so that the compiler can check that you're using them in ways that make sense, so do types have kinds, so that you can be prevented from using types in a nonsensical way.
Rust's kinds, though, are unusual: we had four constant kinds, const, owned, send, and copy, which can also be combined. So a given type could have none, some, or all of these kinds. The copy kind, for example, describes types whose values are allowed to be copied.
Once we introduced traits, it made sense to look at kinds as special traits that were wired into the compiler. So that's what I did to fix #2284. This had the nice effect of making the AST representation of type param bounds (a bound is the thing after the colon when you write <T: Copy> as a parameter list) much simpler: there were no longer any special cases for the built-in kinds. Now, resolve resolves references to things like Copy to placeholder traits that get defined in the core library, and the typechecker special-cases to turn these into specially represented bounds in the ty::param_bound data structure when it sees references to the placeholders.
For this bug, the net effect is that now, you can override Copy and other built-in traits/kinds with your own traits if you really want to. The one weird thing that happens now is that if you use the #[no_core] attribute to say you don't want to import the core library, you won't be able to use the Copy trait in your type parameter declarations -- but that's probably not so bad.
This is sort of a weird bug. Rust had a notion of "kinds" that was distinct from our notion of traits, because kinds existed before traits did. If you know what kinds mean in other languages, it's more or less the same in Rust. If not: a kind is just the type of a type. Just like values have types so that the compiler can check that you're using them in ways that make sense, so do types have kinds, so that you can be prevented from using types in a nonsensical way.
Rust's kinds, though, are unusual: we had four constant kinds, const, owned, send, and copy, which can also be combined. So a given type could have none, some, or all of these kinds. The copy kind, for example, describes types whose values are allowed to be copied.
Once we introduced traits, it made sense to look at kinds as special traits that were wired into the compiler. So that's what I did to fix #2284. This had the nice effect of making the AST representation of type param bounds (a bound is the thing after the colon when you write <T: Copy> as a parameter list) much simpler: there were no longer any special cases for the built-in kinds. Now, resolve resolves references to things like Copy to placeholder traits that get defined in the core library, and the typechecker special-cases to turn these into specially represented bounds in the ty::param_bound data structure when it sees references to the placeholders.
For this bug, the net effect is that now, you can override Copy and other built-in traits/kinds with your own traits if you really want to. The one weird thing that happens now is that if you use the #[no_core] attribute to say you don't want to import the core library, you won't be able to use the Copy trait in your type parameter declarations -- but that's probably not so bad.