{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/1524","repository_url":"https://api.github.com/repos/rust-lang/rfcs","labels_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1524/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1524/comments","events_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1524/events","html_url":"https://github.com/rust-lang/rfcs/pull/1524","id":137964773,"number":1524,"title":"Custom Dynamically Sized Types for Rust","user":{"login":"ubsan","id":3479021,"avatar_url":"https://avatars.githubusercontent.com/u/3479021?v=3","gravatar_id":"","url":"https://api.github.com/users/ubsan","html_url":"https://github.com/ubsan","followers_url":"https://api.github.com/users/ubsan/followers","following_url":"https://api.github.com/users/ubsan/following{/other_user}","gists_url":"https://api.github.com/users/ubsan/gists{/gist_id}","starred_url":"https://api.github.com/users/ubsan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ubsan/subscriptions","organizations_url":"https://api.github.com/users/ubsan/orgs","repos_url":"https://api.github.com/users/ubsan/repos","events_url":"https://api.github.com/users/ubsan/events{/privacy}","received_events_url":"https://api.github.com/users/ubsan/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rfcs/labels/T-lang","name":"T-lang","color":"bfd4f2"}],"state":"open","locked":false,"assignee":{"login":"nikomatsakis","id":155238,"avatar_url":"https://avatars.githubusercontent.com/u/155238?v=3","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false},"assignees":[{"login":"nikomatsakis","id":155238,"avatar_url":"https://avatars.githubusercontent.com/u/155238?v=3","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false}],"milestone":null,"comments":50,"created_at":"2016-03-02T19:14:00Z","updated_at":"2016-08-16T17:57:25Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/1524","html_url":"https://github.com/rust-lang/rfcs/pull/1524","diff_url":"https://github.com/rust-lang/rfcs/pull/1524.diff","patch_url":"https://github.com/rust-lang/rfcs/pull/1524.patch"},"body":"I believe this fixes #813, and is a nicer, and far more powerful, solution than #709."},"comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/comments/240184446","html_url":"https://github.com/rust-lang/rfcs/pull/1524#issuecomment-240184446","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1524","id":240184446,"user":{"login":"nikomatsakis","id":155238,"avatar_url":"https://avatars.githubusercontent.com/u/155238?v=3","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false},"created_at":"2016-08-16T17:57:25Z","updated_at":"2016-08-16T17:57:25Z","body":"OK, so, I read the RFC. :) I think this is pretty nifty stuff, and I imagine it could be a good addition to the language. I'm going to give some scattershot responses. The TL;DR: I think the ideas are pretty solid. I'd like to mix this up with japaric's and see if we can't make the code feel a bit more elegant, and I'd like to elaborate out some more examples, but overall, I like it.\r\n\r\n----\r\n\r\nFirst, I want to think a bit about the motivation. There are a couple of problems in this general area of \"working with unsized types\" and I want to be thoughtful about which ones we are trying to solve and which ones we are not. Here are some example problems around DST that come to mind, starting from the one that the RFC clearly aims at and progressing more towards unlikely:\r\n\r\n- Enable more complex notions of slices, notably two- or multi-dimensional slicing. So e.g. being able to make a \"submatrix\" of a matrix. This RFC seems to solve that problem pretty well. I like the way we keep the existing `Index` traits but basically allow them to return additional \"info\" for their fat pointers.\r\n    - That said, it's worth digging a bit more into this I think. Do we aim to support N-dimensional slices, where the N is a dynamic value? If so, I guess that the info would have to have a `Vec<T>` for the slice boundaries, which isn't `Copy`, and hence wouldn't work with this trait.\r\n- What about other kinds of unsized types? For example, trying to model something more like trait objects? Obviously we can't do the full method dispatch magic, but trait objects have other properties (e.g., a dynamically computed alignment) that `[T]` don't have, so it's worth thinking them over.\r\n- Creating a kind of \"newtype'd slice\", such as `Path` and `PathBuf`, requires some tricky unsafe code right now. It seems like this is a kind of \"simple case\" and it might be nice if it could be done w/ safe code. It seems clear though that this RFC doesn't address that problem (and maybe it shouldn't).\r\n    - Would the mechanisms offered in this RFC be a nicer way to solve that problem?\r\n- It has been proposed that could try to support \"compound\" unsized types, such as `[Trait]` (which would be an unsized version of `[T; N]` where `T: Trait`) or `[[T]]` (which would be a two-dimensional slice). Supporting types like these seems slick but I'm not sure it really works out; for example, the existential quantifier doesn't nest in a trivial way (e.g., `[T]` is `exists N. [T;N]` but `[[T]]` is `exists N. exists M. [[T; M]; N]`, not `exists N. [exists M. [T; M]; N]`). This seems to suggest that there will be problems around substitution. I think the RFC does not (and righly so) aim to address this.\r\n- Other possible applications?\r\n\r\n----\r\n\r\nOK, next thing, I had a few nits and questions about the text itself. For example, in the final example of a pixel buffer, I think there are some errors/inconsistencies:\r\n\r\n```rust\r\nimpl Index<Range<usize>> for Pixels {\r\n  type Output = PixelBuffer; // <-- I think this should be Pixels?\r\n  fn index(&self, idx: Range<usize>) -> &Pixels {\r\n     ... // various assertions \r\n     unsafe {\r\n       Pixels::from_raw_parts(\r\n         self.as_ptr().offset(index.start as isize), // <-- where did this `as_ptr` method come from?\r\n         index.end - index.start, // <-- also, s/index/idx/?\r\n         self.stride, // <-- this field `stride` is declared on the auxiliary, perhaps `self.stride()`?\r\n         self.height) // <-- same\r\n     }\r\n  }\r\n}\r\n```\r\n\r\nI'm not trying to nitpick, just to make sure I understand. In particular, in order to access the meta data, you can't just use field access like `self.stride` (I assume), but rather have to do `ptr::fat_ptr_meta(self).stride`, right? And similarly the `as_ptr` method isn't something you would get automatically, but rather something you would write yourself (much like `from_raw_parts`), right?\r\n\r\n---\r\n\r\nOK, third part. If there is a flaw in this RFC, I think it might be that it's not quite ambitious enough. I don't necessarily mean in the *motivation* (though if we could solve the second problem, making it easy to make newtype'd slices, that'd be great) but the mechanism. Normally I'm kind of against new syntax, especially for wizardry :), but I feel like the code resulting from this proposal feels like we could make it more elegant.\r\n\r\nInterestingly, it seems like @japaric and I were thinking along similar lines. When I came back and read his [older RFC](https://github.com/japaric/rfcs/blob/unsized2/text/0000-unsized-types.md), after reading this one, I found it had a lot of the initial ideas I had been tossing around.\r\n\r\nLet me try and elaborate a bit on what didn't feel great to me. Starting point is the definition of `Pixels` itself:\r\n\r\n```rust\r\nstruct Pixels([f32; 0])\r\n```\r\n\r\nThis declaration *looks* deceptively normal, but of course it's kind of misleading. The \"zero-sized field at the end\" has many desirable properties, but it seems to make assumptions about our representation and layout that we don't normally guarantee (for example, one might assume you can take the address of this field to get at the extra data, but that isn't necessarily true since we could opt to reorder fields, right?). I guess I would prefer some kind of more *declarative* syntax for what is happening here, or perhaps a bit more magic.\r\n\r\nI sort of liked how @japaric's RFC handled it. Here is a kind of \"from memory, hybridized\" variant:\r\n\r\n```rust\r\nunsized type Pixels; // basically a placeholder\r\nimpl Unsized for Pixels {\r\n    type Data = f32; // what the (sized) pointer will point at\r\n    type Meta = (usize, usize);\r\n    \r\n    fn size_of_val(&self) -> usize { size_of::<f32>() * meta(self).0 * meta(self).1 }\r\n    fn align_of_val(&self) -> usize { align_of::<f32>() } // I think we need this too =)\r\n}\r\n```\r\n\r\n(Oh, btw, I think that `impl !Sized` feels really weird to me, particularly if we add some more general form of `!` notation. I think I prefer just an `Unsized` lang-item-trait.)\r\n\r\nAnyway, as I wrote initially, I'm largely bikeshedding here. I do think we can make it \"feel\" slicker, but I don't think it's a big change to the core ideas involved."}}
{"actor":{"display_login":"nikomatsakis"}}