From farcaller at gmail.com Tue Apr 1 08:44:52 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Tue, 1 Apr 2014 16:44:52 +0100 Subject: [rust-dev] A new better way to build rust apps Message-ID: I decided to switch away from Rakefiles (after I switched to them from Makefiles) and make a dependency generator / build system in rust to get 20% more coolness factor. Here's a sample config file: https://gist.github.com/farcaller/4c08908fe526e0631989. As you can see, the syntax is somewhat similar to rust code itself, with a few interesting bits like ~ sigil resolving to 'build' dir and @ sigil resolving to 'src' dir, so you can use relative paths safely (Rustfiles are all about safety, you know). It also supports named chainable configurations, so that you can define all the possible build options in one single file, generics (for rules expansion) and a background daemon that looks for files being modified in @ scope to make compilation even faster. TL;DR: Happy April fools' day :-) -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Tue Apr 1 15:44:21 2014 From: alex at crichton.co (Alex Crichton) Date: Tue, 1 Apr 2014 15:44:21 -0700 Subject: [rust-dev] 0.10 prerelease testing Message-ID: Greeting Rustlers! Our lovely automation has recently prepared an 0.10 release candidate recently. I've tested them slightly, and if you'd like to also give them a shot all the links are included at the end of this message. Remember that this is not a signed release yet, we've only got checksums for these files at this time. Signatures will come with the upcoming release. The astute may notice that we have a large number more links for 0.10 than we did for 0.9, and these are all the new binary installers for Linux and Mac. These have seen little testing beyond the recent nightlies, and more usage would be greatly appreciated! These binaries should support Mac OS X 10.7+, Windows 7 and 2008 RC2, and Linux. The source also supports FreeBSD and Android. If all goes well with this RC, it'll get signed in the coming days with a release soon after. commit: a5681d25906fd07eee00dd430a1053ff722da26a http://static.rust-lang.org/dist/rust-0.10.tar.gz 461ef730566d644466f6edee23181e1f8200c83927912e5eb95864a2a83824da http://static.rust-lang.org/dist/rust-0.10-x86_64-unknown-linux-gnu.tar.gz ff65bc52b8486c6df0e44e94e030b912b8d25170db8e498841ca568ab0fc9fe2 http://static.rust-lang.org/dist/rust-0.10-i686-unknown-linux-gnu.tar.gz 7deb2225fe3f6ab01fada566d9a37a0d2db1bae2edb179eb24e5c2574dac02ae http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.tar.gz b018f3649beee30c4f34fa0bbfe1a784c63e8be86d71883b9893d6941af8a429 http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.tar.gz 25c35c762b7c485230bcc5f7893ef961fdba48da537f19f2a16d0f68303b4d3e http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.pkg 5d21be30318137f6c17ad190d8c272e8afe00335666ec547729cba3ebe690246 http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.pkg 5e2b210e2d9ea64ffb7afd376a256fedcb48350bc32472ae8abd4aa72de2535c http://static.rust-lang.org/dist/rust-0.10-install.exe 03a7655bf5e154599efddb9688451664fb2f17acb792ef1a2c74b4ea19636bbe I'm sure that 0.10 will be an amazing release, and I hope everyone is as excited as I am! From danielmicay at gmail.com Tue Apr 1 17:07:35 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 01 Apr 2014 20:07:35 -0400 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: References: Message-ID: <533B54C7.4090804@gmail.com> On 01/04/14 06:44 PM, Alex Crichton wrote: > Greeting Rustlers! > > Our lovely automation has recently prepared an 0.10 release candidate recently. > I've tested them slightly, and if you'd like to also give them a shot all the > links are included at the end of this message. Remember that this is not a > signed release yet, we've only got checksums for these files at this time. > Signatures will come with the upcoming release. > > The astute may notice that we have a large number more links for 0.10 than we > did for 0.9, and these are all the new binary installers for Linux and Mac. > These have seen little testing beyond the recent nightlies, and more usage would > be greatly appreciated! > > These binaries should support Mac OS X 10.7+, Windows 7 and 2008 RC2, and Linux. > The source also supports FreeBSD and Android. If all goes well with this RC, > it'll get signed in the coming days with a release soon after. > > commit: a5681d25906fd07eee00dd430a1053ff722da26a > > http://static.rust-lang.org/dist/rust-0.10.tar.gz > 461ef730566d644466f6edee23181e1f8200c83927912e5eb95864a2a83824da > > http://static.rust-lang.org/dist/rust-0.10-x86_64-unknown-linux-gnu.tar.gz > ff65bc52b8486c6df0e44e94e030b912b8d25170db8e498841ca568ab0fc9fe2 > > http://static.rust-lang.org/dist/rust-0.10-i686-unknown-linux-gnu.tar.gz > 7deb2225fe3f6ab01fada566d9a37a0d2db1bae2edb179eb24e5c2574dac02ae > > http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.tar.gz > b018f3649beee30c4f34fa0bbfe1a784c63e8be86d71883b9893d6941af8a429 > > http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.tar.gz > 25c35c762b7c485230bcc5f7893ef961fdba48da537f19f2a16d0f68303b4d3e > > http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.pkg > 5d21be30318137f6c17ad190d8c272e8afe00335666ec547729cba3ebe690246 > > http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.pkg > 5e2b210e2d9ea64ffb7afd376a256fedcb48350bc32472ae8abd4aa72de2535c > > http://static.rust-lang.org/dist/rust-0.10-install.exe > 03a7655bf5e154599efddb9688451664fb2f17acb792ef1a2c74b4ea19636bbe > > I'm sure that 0.10 will be an amazing release, and I hope everyone is as excited > as I am! The Linux source tarball builds, passes tests and installs fine in a clean packaging container so that's good enough for me :P. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From farcaller at gmail.com Wed Apr 2 03:25:36 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Wed, 2 Apr 2014 11:25:36 +0100 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: <53397650.9000406@gmail.com> References: <53397650.9000406@gmail.com> Message-ID: If I get it right, calls to traits are resolved in runtime (so, traits are kind of similar to C++ virtual methods). What I'm proposing here is a compile-time approach. Let's say we have the following trait: pub trait LCD { fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8); fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, color: u8); fn putc(&mut self, value: char); fn puts(&mut self, s: &str); fn flush(&self); fn clear(&mut self); } which defined a LED screen. There are two structs implementing it: C12832 and ILI9341 (two different lcd controllers). So I want my app to print hello world on lcd, I write the following code: let mut lcd = lcd_c12832::C12832::new(spi); let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; l.puts("hello, world"); Which results in a runtime dispatch, a slower and bigger code than the one I'd have without a trait. A second problem is there is no easy way to write unified code that supports both the lcds based on passed in --cfg, as I can't apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of problematic to return a &LCD out from it given that there is no heap and no analog of placement new from C++. Proposed binding concept solves those two problems: #[cfg(lcd_c12832)] let Binding: binding { let lcd: &lcd_c12832::C12832; let main: &Main; bind main.lcd = lcd; } at this point of time compiler can be sure about what struct is implementing LCD trait for main.lcd and can bind the function bodies as compile time, inlining them if applicable. This also might be something that is already implemented, please advice. The goal here is to minimise runtime code being executed and its size. On Mon, Mar 31, 2014 at 3:06 PM, Daniel Micay wrote: > I'm not really sure exactly what it being proposed here. > > Rust's generic types and functions are already entirely expanded at > compile-time. You *can* use traits as objects for dynamic dispatch, but > it's not how they're used in the vast majority of cases. > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed Apr 2 05:32:44 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 08:32:44 -0400 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: References: <53397650.9000406@gmail.com> Message-ID: <533C036C.5070400@gmail.com> On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: > If I get it right, calls to traits are resolved in runtime (so, traits > are kind of similar to C++ virtual methods). All method calls on regular types are resolved via static dispatch, whether or not they come from a trait. For example, consider a generic function like the following: fn min(a: T, b: T) -> T { if a < b { a } else { b } } This function performs a *static* call of the `lt` method defined on the `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded at compile-time just as C++ templates are. Rust also allows using traits as boxed objects, but this is an entirely transparent choice. They're almost always used for static dispatch via trait bounds on generics, or simply outside of generics. > What I'm proposing here is a compile-time approach. > > Let's say we have the following trait: > > pub trait LCD { > fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8); > fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); > fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, > color: u8); > fn putc(&mut self, value: char); > fn puts(&mut self, s: &str); > > fn flush(&self); > fn clear(&mut self); > } > > which defined a LED screen. There are two structs implementing it: > C12832 and ILI9341 (two different lcd controllers). > > So I want my app to print hello world on lcd, I write the following code: > > let mut lcd = lcd_c12832::C12832::new(spi); > let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; > l.puts("hello, world"); > > Which results in a runtime dispatch, a slower and bigger code than the > one I'd have without a trait. You can call methods defined on a trait without boxing the object as a trait object. The ability to perform dynamic dispatch via a trait object is totally optional. The methods can also be called directly, including inside a generic function by specifying the trait as a type parameter bound. You can simply call the `puts` method directly on the `lcd` object without a cast. > A second problem is there is no easy way to write unified code that > supports both the lcds based on passed in --cfg, as I can't > apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of > problematic to return a &LCD out from it given that there is no heap and > no analog of placement new from C++. Rust supports generic functions, and you can write code supporting both types by making it generic. The choice between static dispatch and dynamic dispatch is entirely up to you in the current system. > Proposed binding concept solves those two problems: > > #[cfg(lcd_c12832)] > let Binding: binding { > let lcd: &lcd_c12832::C12832; > let main: &Main; > > bind main.lcd = lcd; > } > > at this point of time compiler can be sure about what struct is > implementing LCD trait for main.lcd and can bind the function bodies as > compile time, inlining them if applicable. > > This also might be something that is already implemented, please advice. > The goal here is to minimise runtime code being executed and its size. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From alex at crichton.co Wed Apr 2 08:35:37 2014 From: alex at crichton.co (Alex Crichton) Date: Wed, 2 Apr 2014 08:35:37 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away Message-ID: I've noticed recently that there seems to be a bit of confusion about the fate of ~[T] with an impending implementation of DST on the horizon. This has been accompanied with a number of pull requests to completely remove many uses of ~[T] throughout the standard distribution. I'd like to take some time to straighten out what's going on with Vec and ~[T]. # Vec In a post-DST world, Vec will be the "vector builder" type. It will be the only type for building up a block of contiguous elements. This type exists today, and lives inside of std::vec. Today, you cannot index Vec, but this will be enabled in the future once the indexing traits are fleshed out. This type will otherwise largely not change from what it is today. It will continue to occupy three words in memory, and continue to have the same runtime semantics. # ~[T] The type ~[T] will still exist in a post-DST, but its representation will change. Today, a value of type ~[T] is one word (I'll elide the details of this for now). After DST is implemented, ~[T] will be a two-word value of the length and a pointer to an array (similarly to what slices are today). The ~[T] type will continue to have move semantics, and you can borrow it to &[T] as usual. The major difference between today's ~[T] type and a post-DST ~[T] is that the push() method will be removed. There is no knowledge of a capacity in the representation of a ~[T] value, so a push could not be supported at all. In theory a pop() can be efficiently supported, but it will likely not be implemented at first. # [T] As part of DST, the type grammar will start accepting [T] as a possible substitute for type parameters. This basically means that if your type parameters is &T, then &[U] can satisfy the type parameter. While possible, I imagine that it will be rare for this to appear in apis. This is an unsized type, which means that it's more limited what you can do with it than you can with a sized type. The full details of [T] will become apparent once DST is implemented, but it's safe to say that APIs and usage should rarely have to deal with this type, and it will likely be mostly transparent. # Converting between Vec and ~[T] Conversions between these two types will be provided, and the default implementations will be free. Converting from Vec to ~[T] will be simply forgetting the capacity, and converting from ~[T] to Vec will set the capacity to the length. Helper methods will likely be provided to perform a forceful reallocating shrink when going from Vec to ~[T], but it will not be the default. ## The cost of Vec => ~[T] Some concerns have been brought up that this can in theory be a costly transition under the assumption that this does a reallocation of memory to shrink to the capacity to exactly the length. This will likely not be the default implementation. Some concerns have then been brought up that some allocators require the size of the allocation to be passed to free(), and that this model is incompatible with that flavor of allocator. We believe that this fear can be alleviated with a "shrink if necessary" method on allocators. The default allocator (backed by the system malloc) would be a no-op because the size to free is not used. Allocators which use the size passed to free would actually perform a reallocation. # Choosing between Vec and ~[T] Primarily, if you need a growable vector, you should use Vec. If you do not need a growable vector, but you're instead just dealing with an array of items, then you should use ~[T]. As a concrete example, I'll take the read_to_end() method on io's Reader trait. This type must use a Vec internally to read data into the vector, but it will return a ~[T] because the contents are conceptually frozen after they have been read. There is no blanket right decision to choose between Vec and ~[T], this will need to be done on a case-by-case basis to evaluate whether apis should take or consume Vec or ~[T]. # Moving Forward In order to implement DST, it is not necessary to remove all usage of ~[T] today. It is necessary to remove all *growable* usage of ~[T], however. All uses of vectors which need growable or shrinkable vectors need to switch to Vec. If a vector does not need to be grown or shrunk, it can remain as ~[T]. Concretely speaking, the next steps forward for ~[T] would entail: * Add a Vec -> ~[T] conversion. This will be an expensive conversion today because it requires an allocation (due to the layout of today's ~[T]), but it will not be expensive in the future. * Add a ~[T] -> Vec conversion. Like the above step, this will also be expensive, but it will not be so in the future. * Remove the `push` and `pop` families of methods from ~[T] Hopefully that clears up any mystery surrounding what's happening with ~[T] and Vec! If you have any questions, feel free to respond to this email or to join us in IRC. From danielmicay at gmail.com Wed Apr 2 09:25:26 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 12:25:26 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: Message-ID: <533C39F6.6000305@gmail.com> On 02/04/14 11:35 AM, Alex Crichton wrote: > I've noticed recently that there seems to be a bit of confusion about the fate > of ~[T] with an impending implementation of DST on the horizon. This has been > accompanied with a number of pull requests to completely remove many uses of > ~[T] throughout the standard distribution. I'd like to take some time to > straighten out what's going on with Vec and ~[T]. I think this is a difference of opinion, not "confusion". The original pull requests switching `~[T]` to `Vec` were done by pcwalton, and this was with full knowledge of the plans for `~[T]`. > # Vec > > In a post-DST world, Vec will be the "vector builder" type. It will be the > only type for building up a block of contiguous elements. This type exists > today, and lives inside of std::vec. Today, you cannot index Vec, but this > will be enabled in the future once the indexing traits are fleshed out. It will be Rust's vector (dynamic array) type. I don't think it makes sense to call it a 'builder' any more than it makes sense to call `HashMap` a 'hash table builder'. It makes something simple far more complicated than it needs to be. > This type will otherwise largely not change from what it is today. It will > continue to occupy three words in memory, and continue to have the same runtime > semantics. > > # ~[T] > > The type ~[T] will still exist in a post-DST, but its representation will > change. Today, a value of type ~[T] is one word (I'll elide the details of this > for now). After DST is implemented, ~[T] will be a two-word value of the length > and a pointer to an array (similarly to what slices are today). The ~[T] type > will continue to have move semantics, and you can borrow it to &[T] as usual. The `~[T]` type will exist because `[T]` will exist as a type. It won't be an explicit choice to support having it. Some of us consider it an unfortunate consequence of DST rather than a useful type. > The major difference between today's ~[T] type and a post-DST ~[T] is that the > push() method will be removed. There is no knowledge of a capacity in the > representation of a ~[T] value, so a push could not be supported at all. In > theory a pop() can be efficiently supported, but it will likely not be > implemented at first. A `pop` or `shift` function is impossible to implement efficiently if allocators require a size to be passed to `free`. > # [T] > > As part of DST, the type grammar will start accepting [T] as a possible > substitute for type parameters. This basically means that if your type > parameters is &T, then &[U] can satisfy the type parameter. > > While possible, I imagine that it will be rare for this to appear in apis. This > is an unsized type, which means that it's more limited what you can do with it > than you can with a sized type. > > The full details of [T] will become apparent once DST is implemented, but it's > safe to say that APIs and usage should rarely have to deal with this type, and > it will likely be mostly transparent. > > # Converting between Vec and ~[T] > > Conversions between these two types will be provided, and the default > implementations will be free. Converting from Vec to ~[T] will be simply > forgetting the capacity, and converting from ~[T] to Vec will set the > capacity to the length. Converting from `Vec` to `~[T]` will not be free with an efficient allocation scheme. I don't think Rust will want to be using a legacy `malloc`/`free` style API as the underlying default allocator in the future. I see it only as a temporary measure before a modern allocation model is implemented. Without a size parameter to `free`, an allocator needs to track the size of allocations manually. It increases the memory overhead, along with adding bookkeeping overhead. C++ allocators take a `size` parameter to the `deallocate` function for this reason and I expect Rust will want to do the same. The design of `malloc` and `free` is far from ideal, because the length is either known statically or dynamically in nearly every case. I think leaving out the capacity field of vectors in some cases without dropping the excess capacity is an an insignificant micro-optimization. In contract, passing the length to `free` is quite valuable and will result in a measurable performance win across nearly all Rust code with an allocator taking advantage of it. > Helper methods will likely be provided to perform a forceful reallocating > shrink when going from Vec to ~[T], but it will not be the default. It has to be the *only* way to do it if Rust is going to be able to switch to an efficient allocation model in the future. The API of `malloc`, `realloc` and `free` is purely a legacy wart and shouldn't drive the design of a new language/library. > ## The cost of Vec => ~[T] > > Some concerns have been brought up that this can in theory be a costly > transition under the assumption that this does a reallocation of memory to > shrink to the capacity to exactly the length. This will likely not be the > default implementation. I think it likely will be the *only* implementation. > Some concerns have then been brought up that some allocators require the size > of the allocation to be passed to free(), and that this model is incompatible > with that flavor of allocator. We believe that this fear can be > alleviated with a "shrink if necessary" method on allocators. The default > allocator (backed by the system malloc) would be a no-op because the size to > free is not used. Allocators which use the size passed to free would actually > perform a reallocation. The default allocator will be taking a length to `free` if it's an efficient implementation. There's no reason for Rust to remain tied to the obsolete `malloc`, `realloc` and `free` API forever. > # Choosing between Vec and ~[T] > > Primarily, if you need a growable vector, you should use Vec. If you do not > need a growable vector, but you're instead just dealing with an array of items, > then you should use ~[T]. > > As a concrete example, I'll take the read_to_end() method on io's Reader trait. > This type must use a Vec internally to read data into the vector, but it will > return a ~[T] because the contents are conceptually frozen after they have been > read. > > There is no blanket right decision to choose between Vec and ~[T], this will > need to be done on a case-by-case basis to evaluate whether apis should take or > consume Vec or ~[T]. > > # Moving Forward > > In order to implement DST, it is not necessary to remove all usage of ~[T] > today. It is necessary to remove all *growable* usage of ~[T], however. All uses > of vectors which need growable or shrinkable vectors need to switch to Vec. > If a vector does not need to be grown or shrunk, it can remain as ~[T]. If `~[T]` remains used throughout the libraries, Rust will become noisier than languages like C++ with a unified vector type. The need to convert between `Vec` and `~[T]` would add noise to lots of code, without any adding measurable optimization win. A micro-optimization shouldn't drive the design of the libraries, especially when it will prevent making a significant *macro*-optimization (passing a length to the deallocation function). > Concretely speaking, the next steps forward for ~[T] would entail: > > * Add a Vec -> ~[T] conversion. This will be an expensive conversion today > because it requires an allocation (due to the layout of today's ~[T]), but it > will not be expensive in the future. > * Add a ~[T] -> Vec conversion. Like the above step, this will also be > expensive, but it will not be so in the future. It may be expensive in some cases in the future, and I don't think cheap in *some* cases can ever be regarded as free or cheap when it's not a predictable cost. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From steve at steveklabnik.com Wed Apr 2 10:34:50 2014 From: steve at steveklabnik.com (Steve Klabnik) Date: Wed, 2 Apr 2014 13:34:50 -0400 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: <533B54C7.4090804@gmail.com> References: <533B54C7.4090804@gmail.com> Message-ID: I compiled from source just yesterday, but everything's been going swimmingly! I just have one comment on 0.10: It seems like println was removed from the prelude. While I can totally appreciate that most people will use println!, which is automatically use-able, it _is_ making my 'hello world' examples significantly more complex, since basically every one of them needs to either import println or use println!("{}", foo); I'm not sure if this is a good or bad thing, just wanted to raise that as a possible issue. From corey at octayn.net Wed Apr 2 10:43:01 2014 From: corey at octayn.net (Corey Richardson) Date: Wed, 2 Apr 2014 13:43:01 -0400 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: References: <533B54C7.4090804@gmail.com> Message-ID: On Wed, Apr 2, 2014 at 1:34 PM, Steve Klabnik wrote: > I compiled from source just yesterday, but everything's been going swimmingly! > > I just have one comment on 0.10: It seems like println was removed > from the prelude. While I can totally appreciate that most people will > use println!, which is automatically use-able, it _is_ making my > 'hello world' examples significantly more complex, since basically > every one of them needs to either import println or use println!("{}", > foo); > > I'm not sure if this is a good or bad thing, just wanted to raise that > as a possible issue. > It has been raised, as an extension to the macro, that invocation with a single, non-string literal, could expand into `println!("{}", $that_arg)` rather than requiring the `"{}"`. -- http://octayn.net/ From pcwalton at mozilla.com Wed Apr 2 11:28:34 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Wed, 02 Apr 2014 11:28:34 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C39F6.6000305@gmail.com> References: <533C39F6.6000305@gmail.com> Message-ID: <533C56D2.4010501@mozilla.com> On 4/2/14 9:25 AM, Daniel Micay wrote: > On 02/04/14 11:35 AM, Alex Crichton wrote: >> I've noticed recently that there seems to be a bit of confusion about the fate >> of ~[T] with an impending implementation of DST on the horizon. This has been >> accompanied with a number of pull requests to completely remove many uses of >> ~[T] throughout the standard distribution. I'd like to take some time to >> straighten out what's going on with Vec and ~[T]. > > I think this is a difference of opinion, not "confusion". The original > pull requests switching `~[T]` to `Vec` were done by pcwalton, and > this was with full knowledge of the plans for `~[T]`. It was transitionary. I thought that we would have to fully extract `~[T]` from the language before DST would work, but it now seems likely that that won't need to happen. > The `~[T]` type will exist because `[T]` will exist as a type. It won't > be an explicit choice to support having it. Some of us consider it an > unfortunate consequence of DST rather than a useful type. Even if you buy that `~[T]` is useless (which I'm not sure I do), it's no more unfortunate than the fact that the type system allows useless types like `Rc>>` is unfortunate. > If `~[T]` remains used throughout the libraries, Rust will become > noisier than languages like C++ with a unified vector type. The need to > convert between `Vec` and `~[T]` would add noise to lots of code, > without any adding measurable optimization win. A micro-optimization > shouldn't drive the design of the libraries, especially when it will > prevent making a significant *macro*-optimization (passing a length to > the deallocation function). In practice C++ libraries use their own custom vector types all over the place, so I wouldn't say that Rust is going to be significantly noisier no matter what we do. Interoperability between different libraries is not a strong point of C++. Besides, C++ has this too, with `unique_ptr`. This Stack Overflow answer is actually pretty illuminating: http://stackoverflow.com/questions/16711697/is-there-any-use-for-unique-ptr-with-array I think that length-frozen owned vectors are likely to be surprisingly common. We'll see. Patrick From danielmicay at gmail.com Wed Apr 2 11:36:32 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 14:36:32 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C56D2.4010501@mozilla.com> References: <533C39F6.6000305@gmail.com> <533C56D2.4010501@mozilla.com> Message-ID: <533C58B0.300@gmail.com> On 02/04/14 02:28 PM, Patrick Walton wrote: > On 4/2/14 9:25 AM, Daniel Micay wrote: >> On 02/04/14 11:35 AM, Alex Crichton wrote: >>> I've noticed recently that there seems to be a bit of confusion about >>> the fate >>> of ~[T] with an impending implementation of DST on the horizon. This >>> has been >>> accompanied with a number of pull requests to completely remove many >>> uses of >>> ~[T] throughout the standard distribution. I'd like to take some time to >>> straighten out what's going on with Vec and ~[T]. >> >> I think this is a difference of opinion, not "confusion". The original >> pull requests switching `~[T]` to `Vec` were done by pcwalton, and >> this was with full knowledge of the plans for `~[T]`. > > It was transitionary. I thought that we would have to fully extract > `~[T]` from the language before DST would work, but it now seems likely > that that won't need to happen. > >> The `~[T]` type will exist because `[T]` will exist as a type. It won't >> be an explicit choice to support having it. Some of us consider it an >> unfortunate consequence of DST rather than a useful type. > > Even if you buy that `~[T]` is useless (which I'm not sure I do), it's > no more unfortunate than the fact that the type system allows useless > types like `Rc>>` is unfortunate. No one is proposing that we use `Rc>>` in the standard library. Using `~[T]` instead of migrating to `Vec` means there will be conversion noise where there was not going to be conversion noise before. >> If `~[T]` remains used throughout the libraries, Rust will become >> noisier than languages like C++ with a unified vector type. The need to >> convert between `Vec` and `~[T]` would add noise to lots of code, >> without any adding measurable optimization win. A micro-optimization >> shouldn't drive the design of the libraries, especially when it will >> prevent making a significant *macro*-optimization (passing a length to >> the deallocation function). > > In practice C++ libraries use their own custom vector types all over the > place, so I wouldn't say that Rust is going to be significantly noisier > no matter what we do. Interoperability between different libraries is > not a strong point of C++. > > Besides, C++ has this too, with `unique_ptr`. This Stack Overflow > answer is actually pretty illuminating: `std::unique_ptr<[T]>` is useful because lots of legacy code uses the new[]/delete[] memory allocations. Unique pointers also take a custom deleter parameter, because they're usable for managing stuff like files, etc. in C++. > I think that length-frozen owned vectors are likely to be surprisingly > common. We'll see. They'll certainly be common if the standard library forces many conversions to and from `Vec`... It should not be stated that this conversion is free though, because it only remains free as long as you're using a legacy allocation API like `malloc`. It's also not free in terms of language complexity - people are going to wonder when they should use each one, and I know I'm certainly going to be telling people to use `Vec` almost everywhere. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From comexk at gmail.com Wed Apr 2 12:13:20 2014 From: comexk at gmail.com (comex) Date: Wed, 2 Apr 2014 15:13:20 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C39F6.6000305@gmail.com> References: <533C39F6.6000305@gmail.com> Message-ID: On Wed, Apr 2, 2014 at 12:25 PM, Daniel Micay wrote: > Without a size parameter to `free`, an allocator needs to track the size > of allocations manually. It increases the memory overhead, along with > adding bookkeeping overhead. Not by very much... If a chunk's header is stored externally, like tcmalloc and Linux slub, there is virtually no memory overhead at the cost of free involving a quick hash table lookup on the address; if it's stored internally, like jemalloc, the overhead is just possibly some page-size-remainder wastage, and free just masks the pointer. Either way, if chunks are ever going to be freed, you need some kind of header to count free slots. I guess knowing the size would help the fast path for free be really simple and even inlined, since it could just swap a fixed thread-local variable. But is that really worth hanging language features on, one way or the other? From cgaebel at uwaterloo.ca Wed Apr 2 12:18:43 2014 From: cgaebel at uwaterloo.ca (Clark Gaebel) Date: Wed, 2 Apr 2014 15:18:43 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: <533C39F6.6000305@gmail.com> Message-ID: Passing the size to free is currently in a C++14 proposal [1]. It's pretty useful (makes free no slower, might make it faster) and in most code, the size is available on free. I'm not sure it would should be mandatory, but it's definitely useful. [1] http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3536.html On Wed, Apr 2, 2014 at 3:13 PM, comex wrote: > On Wed, Apr 2, 2014 at 12:25 PM, Daniel Micay > wrote: > > Without a size parameter to `free`, an allocator needs to track the size > > of allocations manually. It increases the memory overhead, along with > > adding bookkeeping overhead. > > Not by very much... If a chunk's header is stored externally, like > tcmalloc and Linux slub, there is virtually no memory overhead at the > cost of free involving a quick hash table lookup on the address; if > it's stored internally, like jemalloc, the overhead is just possibly > some page-size-remainder wastage, and free just masks the pointer. > Either way, if chunks are ever going to be freed, you need some kind > of header to count free slots. > > I guess knowing the size would help the fast path for free be really > simple and even inlined, since it could just swap a fixed thread-local > variable. But is that really worth hanging language features on, one > way or the other? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Clark. Key ID : 0x78099922 Fingerprint: B292 493C 51AE F3AB D016 DD04 E5E3 C36F 5534 F907 -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed Apr 2 12:41:51 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 15:41:51 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: <533C39F6.6000305@gmail.com> Message-ID: <533C67FF.6090808@gmail.com> On 02/04/14 03:18 PM, Clark Gaebel wrote: > Passing the size to free is currently in a C++14 proposal [1]. It's > pretty useful (makes free no slower, might make it faster) and in most > code, the size is available on free. I'm not sure it would should be > mandatory, but it's definitely useful. > > [1] http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3536.html Allocators already do take the size, so it already works for containers, etc. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From danielmicay at gmail.com Wed Apr 2 12:53:28 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 15:53:28 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: <533C39F6.6000305@gmail.com> Message-ID: <533C6AB8.1040506@gmail.com> On 02/04/14 03:13 PM, comex wrote: > On Wed, Apr 2, 2014 at 12:25 PM, Daniel Micay wrote: >> Without a size parameter to `free`, an allocator needs to track the size >> of allocations manually. It increases the memory overhead, along with >> adding bookkeeping overhead. > > Not by very much... If a chunk's header is stored externally, like > tcmalloc and Linux slub, there is virtually no memory overhead at the > cost of free involving a quick hash table lookup on the address; if > it's stored internally, like jemalloc, the overhead is just possibly > some page-size-remainder wastage, and free just masks the pointer. > Either way, if chunks are ever going to be freed, you need some kind > of header to count free slots. You're talking about allocators designed around the limitation of an API. The design no longer needs to make the same compromises if you're going to know the size. The difference between no cache miss and a cache miss is not insignificant... > I guess knowing the size would help the fast path for free be really > simple and even inlined, since it could just swap a fixed thread-local > variable. It's a significant optimization. There's a reason this was included in the C++ allocator design and is being extended to more of the language in C++14. > But is that really worth hanging language features on, one way or the other? Is it really worth designing the language around the micro-optimization of leaving off a capacity field? Rust's syntax is verbose enough without needing to convert to and from vector/string builders all the time. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From danielmicay at gmail.com Wed Apr 2 13:03:37 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 16:03:37 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: <533C39F6.6000305@gmail.com> Message-ID: <533C6D19.6000003@gmail.com> On 02/04/14 03:13 PM, comex wrote: > On Wed, Apr 2, 2014 at 12:25 PM, Daniel Micay wrote: > > But is that really worth hanging language features on, one > way or the other? This also isn't the only optimization lost here. Zero-size allocations will need to be clamped to one if passing a size to free isn't required. Why? Rust uses a non-nullable pointer optimization, where Option<~T> and similar enums can be stored without a tag. This optimization should also be extended to types like slices in the future. It applies to the current `~[T]` but would need to be adapted to a new representation. It's important to avoid allocating for a zero-size allocation, in order to save memory for ~Trait with zero-size types and to avoid allocating in zero-size vectors. However, this means that a zero-size allocation needs to be represented as non-null. Rust needs a way of knowing that despite being non-null, there is no allocated capacity. For example, consider a 0-size slice: (0x22, 0) When this is passed to `free`, Rust needs to be sure that a 0-size slice also has a 0-size capacity. In order to do that, shrink_to_fit() needs to happen during Vec -> ~[T] conversions. At the moment, Rust is completely broken in this regard. The following expression evaluates to None: Some(~()) I have no sane proposal to fix this beyond passing a size to free. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From bill_myers at outlook.com Wed Apr 2 13:27:42 2014 From: bill_myers at outlook.com (Bill Myers) Date: Wed, 2 Apr 2014 20:27:42 +0000 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C6D19.6000003@gmail.com> References: , <533C39F6.6000305@gmail.com>, , <533C6D19.6000003@gmail.com> Message-ID: > At the moment, Rust is completely broken in this regard. The following > expression evaluates to None: > Some(~()) Ouch, this is a disaster. Is there a bug filed for this? Anyway, I don't get your argument about size to free having anything to do with fixing it (although I agree that size to free is awesome). If you don't care about equality (i.e. the fact that &*~() != &*~(), but a == a where a = &*~()), just return the address of a single private static 1-byte item for any 0-sized allocation. If you DO care about equality, then you will need at least an integer allocation scheme in all cases on 32-bit platforms, and the real costs are the data structures to track that (at least a bit in a bitmask, probably at least 2 bits for an efficient implementation). If you can't use the 1-2GB of kernel address space, then you'll also need to allocate one byte of actual usable address space (but not committed memory). On 64-bit platforms, you generally have at least around 2^60-2^63 bytes of unusable address space, so you can just increment a pointer pointing there for each allocation, at zero cost. Of course the quick and simple fix is to try to call malloc(0) and if it returns NULL, remember that and switch to using malloc(1) instead. -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed Apr 2 13:56:46 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 16:56:46 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: , <533C39F6.6000305@gmail.com>, , <533C6D19.6000003@gmail.com> Message-ID: <533C798E.7070900@gmail.com> Clamping `malloc(0)` to `malloc(1)` means that allocations of 0-size types will no longer be free, which is sad. It's very useful to be able to have meet the requirement of having a trait object and avoid any memory allocation if there's no state. The sentinel does work, but adds a branch to *every* free call. It will not optimize out even for cases where the size is fixed at compile time. This isn't a significant issue for the default allocator because it will be complex, but it's a significant issue with a bump/arena allocator, or a simple free list. It's less overhead than not having a size available will be, but why not kill two birds with one stone? -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From banderson at mozilla.com Wed Apr 2 13:58:15 2014 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 02 Apr 2014 13:58:15 -0700 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: References: <533B54C7.4090804@gmail.com> Message-ID: <533C79E7.7090900@mozilla.com> I've been worried about this decision too. On 04/02/2014 10:34 AM, Steve Klabnik wrote: > I compiled from source just yesterday, but everything's been going swimmingly! > > I just have one comment on 0.10: It seems like println was removed > from the prelude. While I can totally appreciate that most people will > use println!, which is automatically use-able, it _is_ making my > 'hello world' examples significantly more complex, since basically > every one of them needs to either import println or use println!("{}", > foo); > > I'm not sure if this is a good or bad thing, just wanted to raise that > as a possible issue. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From simon.sapin at exyr.org Wed Apr 2 14:08:06 2014 From: simon.sapin at exyr.org (Simon Sapin) Date: Wed, 02 Apr 2014 22:08:06 +0100 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: References: <533B54C7.4090804@gmail.com> Message-ID: <533C7C36.10103@exyr.org> On 02/04/2014 18:43, Corey Richardson wrote: > On Wed, Apr 2, 2014 at 1:34 PM, Steve Klabnik wrote: >> I compiled from source just yesterday, but everything's been going swimmingly! >> >> I just have one comment on 0.10: It seems like println was removed >> from the prelude. While I can totally appreciate that most people will >> use println!, which is automatically use-able, it _is_ making my >> 'hello world' examples significantly more complex, since basically >> every one of them needs to either import println or use println!("{}", >> foo); >> >> I'm not sure if this is a good or bad thing, just wanted to raise that >> as a possible issue. >> > > It has been raised, as an extension to the macro, that invocation with > a single, non-string literal, could expand into `println!("{}", > $that_arg)` rather than requiring the `"{}"`. This sounds even better than having both println() and println!() (in the prelude) with non-obvious differences. -- Simon Sapin From dbau.pp at gmail.com Wed Apr 2 14:51:18 2014 From: dbau.pp at gmail.com (Huon Wilson) Date: Thu, 03 Apr 2014 08:51:18 +1100 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: Message-ID: <533C8656.6060402@gmail.com> Personally, I'm strongly against doing using ~[] as return values from library functions. Imagine we were in world were we only had Vec and were adding a new type OwnedSlice that was (pointer, length) like ~[T]. For how many library functions would we say "it is sensible to throw away the capacity information before returning"? I don't think anything in libstd etc. would have a strong 'yes' answer to this question. Specifically, I don't see any concrete positives to doing this for library functions other than "lets keep using ~[T]" and ~[T] & &[T] having the same in-memory representation (covered below). Under any scheme I can think of, there are negatives: 1. without calling shrink_to_fit in the conversion, we lose the ability to have sized deallocations (covered by others in this thread) 2. if we do call it, then anything returning a ~[T] after building it with a Vec is unavoidably slower 3. either way, you're throwing away (the knowledge of) any extra capacity that was allocated, so if someone wishes to continue extending the slice returned by e.g. `foo`, then `let v = foo().into_vec(); v.push(1)` will always require a realloc. (And for library functions, we shouldn't be dictating how people use the return values.) 4. it adds two vector-like types that someone needs to think about: in the common case the benefits of ~[] (one word smaller) are completely useless, it's really only mostly-immutable heavily-nested data types with a lot of vectors like Rust's AST where it helps[1]. I.e. almost all situations are fine (or better) with a Vec. 5. how will the built-in ~[] type use allocators? (well, I guess this is really "how will the built-in ~ type use allocators?", but that question still needs answering[2].) On the representation of ~[T] and &[T] being the same: this means that theoretically a ~[T] in covariant(?) position can be coerced to a &[T], e.g. Vec<~[T]> -> Vec<&[T]>. However, this only really matters for functions returning many nested slices/vectors, e.g. the same Vec example, because pretty much anything else will be able to write `vec.as_slice()` cheaply. (In the code base, the only things mentioning /~[~[/ now are a few tests and things handling the raw argc/argv, i.e. returning ~[~[u8]].) I don't think this should be a major concern, because I don't see us suddenly growing functions a pile of new functions returning ~[~[T]], and if we do, I would think that they would be better suited to being an iterator (assuming that's possible) over Vec's, and these internal Vec can be then be mapped to ~[T] cheaply before collecting the iterator to a whole new Vec (or Vec<~[]>) (assuming a &[Vec]/&[~[]] is wanted). I'm concerned we are wanting to stick with ~[T] because it's what we currently have, and is familiar; as I said above, I don't see many positives for doing it for library functions. Huon [1]: And even in those cases, it's not a particularly huge gain, e.g. taking *two* words off the old OptVec type by replacing it with a library equivalent to DST's ~[T] only gained about 40MB: http://huonw.github.io/isrustfastyet/mem/#f5357cf,bbf8cdc [2]: The sanest way to support allocators I can think of would be changing `~T` to `Uniq`, and then we have `Uniq<[T]>` which certainly feels less attractive than `~[T]`. On 03/04/14 02:35, Alex Crichton wrote: > I've noticed recently that there seems to be a bit of confusion about the fate > of ~[T] with an impending implementation of DST on the horizon. This has been > accompanied with a number of pull requests to completely remove many uses of > ~[T] throughout the standard distribution. I'd like to take some time to > straighten out what's going on with Vec and ~[T]. > > # Vec > > In a post-DST world, Vec will be the "vector builder" type. It will be the > only type for building up a block of contiguous elements. This type exists > today, and lives inside of std::vec. Today, you cannot index Vec, but this > will be enabled in the future once the indexing traits are fleshed out. > > This type will otherwise largely not change from what it is today. It will > continue to occupy three words in memory, and continue to have the same runtime > semantics. > > # ~[T] > > The type ~[T] will still exist in a post-DST, but its representation will > change. Today, a value of type ~[T] is one word (I'll elide the details of this > for now). After DST is implemented, ~[T] will be a two-word value of the length > and a pointer to an array (similarly to what slices are today). The ~[T] type > will continue to have move semantics, and you can borrow it to &[T] as usual. > > The major difference between today's ~[T] type and a post-DST ~[T] is that the > push() method will be removed. There is no knowledge of a capacity in the > representation of a ~[T] value, so a push could not be supported at all. In > theory a pop() can be efficiently supported, but it will likely not be > implemented at first. > > # [T] > > As part of DST, the type grammar will start accepting [T] as a possible > substitute for type parameters. This basically means that if your type > parameters is &T, then &[U] can satisfy the type parameter. > > While possible, I imagine that it will be rare for this to appear in apis. This > is an unsized type, which means that it's more limited what you can do with it > than you can with a sized type. > > The full details of [T] will become apparent once DST is implemented, but it's > safe to say that APIs and usage should rarely have to deal with this type, and > it will likely be mostly transparent. > > # Converting between Vec and ~[T] > > Conversions between these two types will be provided, and the default > implementations will be free. Converting from Vec to ~[T] will be simply > forgetting the capacity, and converting from ~[T] to Vec will set the > capacity to the length. > > Helper methods will likely be provided to perform a forceful reallocating > shrink when going from Vec to ~[T], but it will not be the default. > > ## The cost of Vec => ~[T] > > Some concerns have been brought up that this can in theory be a costly > transition under the assumption that this does a reallocation of memory to > shrink to the capacity to exactly the length. This will likely not be the > default implementation. > > Some concerns have then been brought up that some allocators require the size > of the allocation to be passed to free(), and that this model is incompatible > with that flavor of allocator. We believe that this fear can be > alleviated with a "shrink if necessary" method on allocators. The default > allocator (backed by the system malloc) would be a no-op because the size to > free is not used. Allocators which use the size passed to free would actually > perform a reallocation. > > # Choosing between Vec and ~[T] > > Primarily, if you need a growable vector, you should use Vec. If you do not > need a growable vector, but you're instead just dealing with an array of items, > then you should use ~[T]. > > As a concrete example, I'll take the read_to_end() method on io's Reader trait. > This type must use a Vec internally to read data into the vector, but it will > return a ~[T] because the contents are conceptually frozen after they have been > read. > > There is no blanket right decision to choose between Vec and ~[T], this will > need to be done on a case-by-case basis to evaluate whether apis should take or > consume Vec or ~[T]. > > # Moving Forward > > In order to implement DST, it is not necessary to remove all usage of ~[T] > today. It is necessary to remove all *growable* usage of ~[T], however. All uses > of vectors which need growable or shrinkable vectors need to switch to Vec. > If a vector does not need to be grown or shrunk, it can remain as ~[T]. > > Concretely speaking, the next steps forward for ~[T] would entail: > > * Add a Vec -> ~[T] conversion. This will be an expensive conversion today > because it requires an allocation (due to the layout of today's ~[T]), but it > will not be expensive in the future. > * Add a ~[T] -> Vec conversion. Like the above step, this will also be > expensive, but it will not be so in the future. > * Remove the `push` and `pop` families of methods from ~[T] > > > Hopefully that clears up any mystery surrounding what's happening with ~[T] and > Vec! If you have any questions, feel free to respond to this email or to join > us in IRC. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pcwalton at mozilla.com Wed Apr 2 14:54:11 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Wed, 02 Apr 2014 14:54:11 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C8656.6060402@gmail.com> References: <533C8656.6060402@gmail.com> Message-ID: <533C8703.7080702@mozilla.com> On 4/2/14 2:51 PM, Huon Wilson wrote: > Specifically, I don't see any concrete positives to doing this for > library functions other than "lets keep using ~[T]" and ~[T] & &[T] > having the same in-memory representation (covered below). > > Under any scheme I can think of, there are negatives: > > 1. without calling shrink_to_fit in the conversion, we lose the ability > to have sized deallocations (covered by others in this thread) > > 2. if we do call it, then anything returning a ~[T] after building it > with a Vec is unavoidably slower > > 3. either way, you're throwing away (the knowledge of) any extra > capacity that was allocated, so if someone wishes to continue extending > the slice returned by e.g. `foo`, then `let v = foo().into_vec(); > v.push(1)` will always require a realloc. (And for library functions, we > shouldn't be dictating how people use the return values.) > > 4. it adds two vector-like types that someone needs to think about: in > the common case the benefits of ~[] (one word smaller) are completely > useless, it's really only mostly-immutable heavily-nested data types > with a lot of vectors like Rust's AST where it helps[1]. I.e. almost all > situations are fine (or better) with a Vec. > > 5. how will the built-in ~[] type use allocators? (well, I guess this is > really "how will the built-in ~ type use allocators?", but that question > still needs answering[2].) > > > On the representation of ~[T] and &[T] being the same: this means that > theoretically a ~[T] in covariant(?) position can be coerced to a &[T], > e.g. Vec<~[T]> -> Vec<&[T]>. However, this only really matters for > functions returning many nested slices/vectors, e.g. the same Vec > example, because pretty much anything else will be able to write > `vec.as_slice()` cheaply. (In the code base, the only things mentioning > /~[~[/ now are a few tests and things handling the raw argc/argv, i.e. > returning ~[~[u8]].) > > I don't think this should be a major concern, because I don't see us > suddenly growing functions a pile of new functions returning ~[~[T]], > and if we do, I would think that they would be better suited to being an > iterator (assuming that's possible) over Vec's, and these internal Vec > can be then be mapped to ~[T] cheaply before collecting the iterator to > a whole new Vec (or Vec<~[]>) (assuming a &[Vec]/&[~[]] is wanted). > > > > I'm concerned we are wanting to stick with ~[T] because it's what we > currently have, and is familiar; as I said above, I don't see many > positives for doing it for library functions. What about strings? Should we be using `StrBuf` as well? Patrick From dbau.pp at gmail.com Wed Apr 2 15:01:16 2014 From: dbau.pp at gmail.com (Huon Wilson) Date: Thu, 03 Apr 2014 09:01:16 +1100 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C8703.7080702@mozilla.com> References: <533C8656.6060402@gmail.com> <533C8703.7080702@mozilla.com> Message-ID: <533C88AC.80808@gmail.com> On 03/04/14 08:54, Patrick Walton wrote: > On 4/2/14 2:51 PM, Huon Wilson wrote: >> Specifically, I don't see any concrete positives to doing this for >> library functions other than "lets keep using ~[T]" and ~[T] & &[T] >> having the same in-memory representation (covered below). >> >> Under any scheme I can think of, there are negatives: >> >> 1. without calling shrink_to_fit in the conversion, we lose the ability >> to have sized deallocations (covered by others in this thread) >> >> 2. if we do call it, then anything returning a ~[T] after building it >> with a Vec is unavoidably slower >> >> 3. either way, you're throwing away (the knowledge of) any extra >> capacity that was allocated, so if someone wishes to continue extending >> the slice returned by e.g. `foo`, then `let v = foo().into_vec(); >> v.push(1)` will always require a realloc. (And for library functions, we >> shouldn't be dictating how people use the return values.) >> >> 4. it adds two vector-like types that someone needs to think about: in >> the common case the benefits of ~[] (one word smaller) are completely >> useless, it's really only mostly-immutable heavily-nested data types >> with a lot of vectors like Rust's AST where it helps[1]. I.e. almost all >> situations are fine (or better) with a Vec. >> >> 5. how will the built-in ~[] type use allocators? (well, I guess this is >> really "how will the built-in ~ type use allocators?", but that question >> still needs answering[2].) >> >> >> On the representation of ~[T] and &[T] being the same: this means that >> theoretically a ~[T] in covariant(?) position can be coerced to a &[T], >> e.g. Vec<~[T]> -> Vec<&[T]>. However, this only really matters for >> functions returning many nested slices/vectors, e.g. the same Vec >> example, because pretty much anything else will be able to write >> `vec.as_slice()` cheaply. (In the code base, the only things mentioning >> /~[~[/ now are a few tests and things handling the raw argc/argv, i.e. >> returning ~[~[u8]].) >> >> I don't think this should be a major concern, because I don't see us >> suddenly growing functions a pile of new functions returning ~[~[T]], >> and if we do, I would think that they would be better suited to being an >> iterator (assuming that's possible) over Vec's, and these internal Vec >> can be then be mapped to ~[T] cheaply before collecting the iterator to >> a whole new Vec (or Vec<~[]>) (assuming a &[Vec]/&[~[]] is wanted). >> >> >> >> I'm concerned we are wanting to stick with ~[T] because it's what we >> currently have, and is familiar; as I said above, I don't see many >> positives for doing it for library functions. > > What about strings? Should we be using `StrBuf` as well? > > Patrick > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev I don't see why not. The same arguments apply. Huon From niko at alum.mit.edu Wed Apr 2 16:22:57 2014 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 2 Apr 2014 19:22:57 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C6D19.6000003@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> Message-ID: <20140402232257.GE20540@Mr-Bennet> On Wed, Apr 02, 2014 at 04:03:37PM -0400, Daniel Micay wrote: > I have no sane proposal to fix this beyond passing a size to free. I don't believe there is a problem with just not using null to represent such pointers (for example, 1 would suffice). This does impose some additional burdens on slice conversion and the like. This conversation has focused on low-level effects, which is important to understand, but I think the bigger question is: how do we WANT the language to look? Is it useful to have a distinct `Vec` and `~[T]` or -- in our ideal world -- would they be the same? I think we can make the interconversion fast for the default allocator, but we should design for the language we want to use. I could go either way on this. In the kind of programs I write, at least, most vectors get built up to a specific length and then stop growing (frequently they stop changing as well, but not always). Sometimes they continue growing. I actually rather like the idea of using `Vec` as a kind of builder and `~[T]` as the end-product. In those cases where the vector continues to grow, of course, I can just keep the `Vec` around. Following this logic, I would imagine that most APIs want to consume and produce `~[T]`, since they consume and produce end products. On the other hand, I could imagine and appreciate an argument that we should just take and produce `Vec`, which gives somewhat more flexibility. In general, Rust takes the philosophy that "if you own it, you can mutate it", so why make growing harder than it needs to be? Preferring Vec also means fewer choices, usually a good thing. Perhaps the best thing is to wait a month (or two or three) until DST is more of a reality and then see how we feel. Niko From danielmicay at gmail.com Wed Apr 2 18:21:56 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 02 Apr 2014 21:21:56 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <20140402232257.GE20540@Mr-Bennet> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> Message-ID: <533CB7B4.3080009@gmail.com> On 02/04/14 07:22 PM, Niko Matsakis wrote: > On Wed, Apr 02, 2014 at 04:03:37PM -0400, Daniel Micay wrote: >> I have no sane proposal to fix this beyond passing a size to free. > > I don't believe there is a problem with just not using null to > represent such pointers (for example, 1 would suffice). This does > impose some additional burdens on slice conversion and the like. I used a sentinel value in my fix along with providing a guarantee that `free` is never called on zero-size allocation. That's the end of any no-op `Vec` -> `~[T]` conversions since it will need to free a zero size allocation. It's not far from just calling `shrink_to_fit`, and allowing for passing a size to `free`. https://github.com/mozilla/rust/pull/13267 I don't think there's any way around without making `~ZeroSizeType` start allocating memory or losing the `Option` optimization otherwise. > This conversation has focused on low-level effects, which is important > to understand, but I think the bigger question is: how do we WANT the > language to look? Is it useful to have a distinct `Vec` and `~[T]` > or -- in our ideal world -- would they be the same? I think we can > make the interconversion fast for the default allocator, but we should > design for the language we want to use. A distinct `~[T]` and `Vec` will make the language more painful to use, so the only point I'm trying to counter is the performance one because it is *is* a valid micro-optimization in some cases. If our default allocation scheme takes advantage of a known size, then it will be faster. I don't think we should keep using a malloc/realloc/free-style API under the hood in the future. > I could go either way on this. In the kind of programs I write, at > least, most vectors get built up to a specific length and then stop > growing (frequently they stop changing as well, but not > always). Sometimes they continue growing. I actually rather like the > idea of using `Vec` as a kind of builder and `~[T]` as the > end-product. In those cases where the vector continues to grow, of > course, I can just keep the `Vec` around. Following this logic, I > would imagine that most APIs want to consume and produce `~[T]`, since > they consume and produce end products. The language needs to be providing a significant safety/correctness guarantee or performance win in exchange for the extra noise and I don't really think it will be in general. There will be use cases for `~[T]` but I don't think they will be common. If an API consumes `~[T]`, it will lose track of capacity the caller may already be able to provide. If it produces `~[T]`, it will lose track of capacity the caller may want to use later on. > On the other hand, I could imagine and appreciate an argument that we > should just take and produce `Vec`, which gives somewhat more > flexibility. In general, Rust takes the philosophy that "if you own > it, you can mutate it", so why make growing harder than it needs to > be? Preferring Vec also means fewer choices, usually a good thing. > > Perhaps the best thing is to wait a month (or two or three) until DST > is more of a reality and then see how we feel. > > > > Niko -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From marcianx at gmail.com Wed Apr 2 18:46:41 2014 From: marcianx at gmail.com (Ashish Myles) Date: Wed, 2 Apr 2014 21:46:41 -0400 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: <533C036C.5070400@gmail.com> References: <53397650.9000406@gmail.com> <533C036C.5070400@gmail.com> Message-ID: And just in case there is a confusion (as I have noticed others to have), it might help to see a specific example comparing static dispatch with dynamic. // This is a single function for all types implementing the LCD Trait. fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of the object being passed in x.line(....); // dynamic dispatch } // Like C++ templates, this generates a function for each type T that implements LCD. fn foo(x : &T) { // x's type is &T rather than &LCD x.line(....); // static dispatch based on type T known at compile-time } On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay wrote: > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: >> If I get it right, calls to traits are resolved in runtime (so, traits >> are kind of similar to C++ virtual methods). > > All method calls on regular types are resolved via static dispatch, > whether or not they come from a trait. For example, consider a generic > function like the following: > > fn min(a: T, b: T) -> T { > if a < b { a } else { b } > } > > This function performs a *static* call of the `lt` method defined on the > `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded > at compile-time just as C++ templates are. > > Rust also allows using traits as boxed objects, but this is an entirely > transparent choice. They're almost always used for static dispatch via > trait bounds on generics, or simply outside of generics. > >> What I'm proposing here is a compile-time approach. >> >> Let's say we have the following trait: >> >> pub trait LCD { >> fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8); >> fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); >> fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, >> color: u8); >> fn putc(&mut self, value: char); >> fn puts(&mut self, s: &str); >> >> fn flush(&self); >> fn clear(&mut self); >> } >> >> which defined a LED screen. There are two structs implementing it: >> C12832 and ILI9341 (two different lcd controllers). >> >> So I want my app to print hello world on lcd, I write the following code: >> >> let mut lcd = lcd_c12832::C12832::new(spi); >> let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; >> l.puts("hello, world"); >> >> Which results in a runtime dispatch, a slower and bigger code than the >> one I'd have without a trait. > > You can call methods defined on a trait without boxing the object as a > trait object. The ability to perform dynamic dispatch via a trait object > is totally optional. The methods can also be called directly, including > inside a generic function by specifying the trait as a type parameter > bound. You can simply call the `puts` method directly on the `lcd` > object without a cast. > >> A second problem is there is no easy way to write unified code that >> supports both the lcds based on passed in --cfg, as I can't >> apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of >> problematic to return a &LCD out from it given that there is no heap and >> no analog of placement new from C++. > > Rust supports generic functions, and you can write code supporting both > types by making it generic. The choice between static dispatch and > dynamic dispatch is entirely up to you in the current system. > >> Proposed binding concept solves those two problems: >> >> #[cfg(lcd_c12832)] >> let Binding: binding { >> let lcd: &lcd_c12832::C12832; >> let main: &Main; >> >> bind main.lcd = lcd; >> } >> >> at this point of time compiler can be sure about what struct is >> implementing LCD trait for main.lcd and can bind the function bodies as >> compile time, inlining them if applicable. >> >> This also might be something that is already implemented, please advice. >> The goal here is to minimise runtime code being executed and its size. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From kevin at sb.org Wed Apr 2 21:51:32 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 2 Apr 2014 21:51:32 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: Message-ID: <7BA8339E-4C66-43E4-B69F-89A43985A282@sb.org> On Apr 2, 2014, at 8:35 AM, Alex Crichton wrote: > As a concrete example, I'll take the read_to_end() method on io's Reader trait. > This type must use a Vec internally to read data into the vector, but it will > return a ~[T] because the contents are conceptually frozen after they have been > read. This concrete example is great, because it precisely illustrates a major objection I have to returning ~[T]. Reader.read_to_end() internally uses a 64k-byte vector. It reserves 64k bytes, then pushes onto this vector until it hits EOF. Every time it fills up the 64k capacity it reserves another chunk and keeps reading (this, btw, is I think almost certainly unintended behavior and is fixed by #13127, which changes it to always keep 64k of space available for each read rather than potentially requesting smaller and smaller reads). Note that because it uses reserve_at_least() it may actually have more than 64k available. When EOF is reached, this vector is returned to the caller. The problem I have with returning ~[T] here is that both choices for how to deal with this wasted space are terrible: 1. Shrink-to-fit before returning. If I'm going to keep the vector around for a long time this is a good idea, but if I'm just going to process the vector and throw it away, the reallocation was completely unnecessary. 2. Convert to ~[T] without shrinking. The caller has no way to know about the potentially massive amount of wasted space. If I'm going to just process the vector and throw it away that's fine, but if I'm going to keep it around for a while then this is terrible. The only reasonable solution is to return the Vec and let the caller decide if they want to shrink-to-fit or not. -Kevin Ballard From kevin at sb.org Wed Apr 2 21:56:43 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 2 Apr 2014 21:56:43 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533C88AC.80808@gmail.com> References: <533C8656.6060402@gmail.com> <533C8703.7080702@mozilla.com> <533C88AC.80808@gmail.com> Message-ID: <6F0444D6-3CF4-42D1-BB68-C937BEE2B5BE@sb.org> On Apr 2, 2014, at 3:01 PM, Huon Wilson wrote: > On 03/04/14 08:54, Patrick Walton wrote: > >> What about strings? Should we be using `StrBuf` as well? > > I don't see why not. The same arguments apply. I agree. I was actually quite surprised to see that the type was named StrBuf, I assumed it was going to be Str just as Vec is not VecBuf. I'm in full agreement with Huon on this matter. The standard libraries should return Vec instead of ~[T] in pretty much every case (the only real exception I can think of is Vec<~[T]> because of the ability to convert to Vec<&[T]> or &[&T]] for free). Similarly I think we should be returning StrBuf instead of ~str in all cases. And finally, I think we should just name it Str instead of StrBuf. If developers want to use ~[T] and ~str in their own code, that's fine, but the standard libraries should err on the side of preserving information (e.g. capacity) and providing a consistent experience. If there's one thing I really want to avoid above all else, it's confusing people about whether they should be using ~[T] or Vec, because some standard library code uses one and some code uses the other. -Kevin From kevin at sb.org Wed Apr 2 22:11:07 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 2 Apr 2014 22:11:07 -0700 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: <533C7C36.10103@exyr.org> References: <533B54C7.4090804@gmail.com> <533C7C36.10103@exyr.org> Message-ID: <62FFEA03-B648-4A49-8070-1A4ECE89ED4E@sb.org> On Apr 2, 2014, at 2:08 PM, Simon Sapin wrote: > On 02/04/2014 18:43, Corey Richardson wrote: >> On Wed, Apr 2, 2014 at 1:34 PM, Steve Klabnik wrote: >>> I compiled from source just yesterday, but everything's been going swimmingly! >>> >>> I just have one comment on 0.10: It seems like println was removed >>> from the prelude. While I can totally appreciate that most people will >>> use println!, which is automatically use-able, it _is_ making my >>> 'hello world' examples significantly more complex, since basically >>> every one of them needs to either import println or use println!("{}", >>> foo); >>> >>> I'm not sure if this is a good or bad thing, just wanted to raise that >>> as a possible issue. >>> >> >> It has been raised, as an extension to the macro, that invocation with >> a single, non-string literal, could expand into `println!("{}", >> $that_arg)` rather than requiring the `"{}"`. > > This sounds even better than having both println() and println!() (in the prelude) with non-obvious differences. This was discussed a while ago. I am very strongly opposed to this change. The primary reason being that println!("hello world"); and let s = "hello world"; println!(s); should have the same semantics. I don't believe we have any precedence right now for a semantic behavior change when using an identifier in place of an expression. Similarly, println!("hello world"); and println!("hello " + "world"); should behave the same. As with the previous, I don't believe we have any precedence for a semantic behavior change when replacing a constant string with a non-constant expression. -Kevin Ballard From danielmicay at gmail.com Wed Apr 2 22:14:08 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 03 Apr 2014 01:14:08 -0400 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: <62FFEA03-B648-4A49-8070-1A4ECE89ED4E@sb.org> References: <533B54C7.4090804@gmail.com> <533C7C36.10103@exyr.org> <62FFEA03-B648-4A49-8070-1A4ECE89ED4E@sb.org> Message-ID: <533CEE20.8080904@gmail.com> Perhaps we should have `print` and `println` back in the prelude and call these `printf!` and `printfln!`. I think it would be a lot clearer, as people always ask how these are different from `print` and `println`. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From kevin at sb.org Wed Apr 2 22:20:22 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 2 Apr 2014 22:20:22 -0700 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: <533CEE20.8080904@gmail.com> References: <533B54C7.4090804@gmail.com> <533C7C36.10103@exyr.org> <62FFEA03-B648-4A49-8070-1A4ECE89ED4E@sb.org> <533CEE20.8080904@gmail.com> Message-ID: On Apr 2, 2014, at 10:14 PM, Daniel Micay wrote: > Perhaps we should have `print` and `println` back in the prelude and > call these `printf!` and `printfln!`. I think it would be a lot clearer, > as people always ask how these are different from `print` and `println`. I would not be opposed to putting print() and println() back in the prelude, but printf!() and printfln!() are not good names. Out format syntax does not match printf(), and any attempt to use the name printf would only sow confusion. Ultimately, though, I think things are fine as they are. In practice I haven't had any issue with the requirement to say println!("{}", s) if I want to print a variable. And most of the time it turns out I want to print more than just a variable anyway. -Kevin From comexk at gmail.com Wed Apr 2 23:15:55 2014 From: comexk at gmail.com (comex) Date: Thu, 3 Apr 2014 02:15:55 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533CB7B4.3080009@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> Message-ID: On Wed, Apr 2, 2014 at 9:21 PM, Daniel Micay wrote: > I used a sentinel value in my fix along with providing a guarantee that > `free` is never called on zero-size allocation. That's the end of any > no-op `Vec` -> `~[T]` conversions since it will need to free a zero > size allocation. It's not far from just calling `shrink_to_fit`, and > allowing for passing a size to `free`. > > https://github.com/mozilla/rust/pull/13267 I see the benefit of free knowing the size in this case, although it seems that it would strongly call for type-level integers to avoid needing a special case in the compiler. I don't think this issue necessarily guarantees Vec can't be freely converted to ~[T]. You could hypothetically special case allocations for zero-sized types, while keeping all other allocations real (including zero sized, since the impact would be minimal). > You're talking about allocators designed around the limitation of an > API. The design no longer needs to make the same compromises if you're > going to know the size. The difference between no cache miss and a cache > miss is not insignificant... I explained why I think a chunk header is necessary in any case. Maybe it is still a significant win. The C++14 proposal claims Google found one with GCC and tcmalloc, although tcmalloc is rather inefficient to start with... I would like to see numbers. Then again, I agree with the other reasons that using ~[T] is a bad idea, so I have no particular reason to disagree with having the size parameter either. From dbau.pp at gmail.com Wed Apr 2 23:45:23 2014 From: dbau.pp at gmail.com (Huon Wilson) Date: Thu, 03 Apr 2014 17:45:23 +1100 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> Message-ID: <533D0383.8050704@gmail.com> On 03/04/14 17:15, comex wrote: > >> You're talking about allocators designed around the limitation of an >> API. The design no longer needs to make the same compromises if you're >> going to know the size. The difference between no cache miss and a cache >> miss is not insignificant... > I explained why I think a chunk header is necessary in any case. > Maybe it is still a significant win. The C++14 proposal claims Google > found one with GCC and tcmalloc, although tcmalloc is rather > inefficient to start with... I would like to see numbers. Really? I was under the impression that tcmalloc was one of the faster allocators in common use. e.g. two posts I found just now via Google: - https://github.com/blog/1422-tcmalloc-and-mysql - http://www.mysqlperformanceblog.com/2013/03/08/mysql-performance-impact-of-memory-allocators-part-2/ Huon From danielmicay at gmail.com Wed Apr 2 23:47:40 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 03 Apr 2014 02:47:40 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> Message-ID: <533D040C.5040809@gmail.com> On 03/04/14 02:15 AM, comex wrote: > On Wed, Apr 2, 2014 at 9:21 PM, Daniel Micay wrote: >> I used a sentinel value in my fix along with providing a guarantee that >> `free` is never called on zero-size allocation. That's the end of any >> no-op `Vec` -> `~[T]` conversions since it will need to free a zero >> size allocation. It's not far from just calling `shrink_to_fit`, and >> allowing for passing a size to `free`. >> >> https://github.com/mozilla/rust/pull/13267 > > I see the benefit of free knowing the size in this case, although it > seems that it would strongly call for type-level integers to avoid > needing a special case in the compiler. I'm not sure how type-level integers help. This size is often a dynamic one and this doesn't involve any special cases in the compiler. The conversion between Vec and ~[T] is entirely a library feature. > I don't think this issue necessarily guarantees Vec can't be freely > converted to ~[T]. You could hypothetically special case allocations > for zero-sized types, while keeping all other allocations real > (including zero sized, since the impact would be minimal). Vec won't be convertible to ~[T] with a no-op after the fix for `Some(~())` lands: https://github.com/mozilla/rust/pull/13267 It will need to free the allocation if it is zero-size. Calling `shrink_to_fit()` isn't far from that and allows passing the length to the free function. Extending the Option-like enum optimization to other types like `Rc` and `Vec` is planned so this issue applies to them too. >> You're talking about allocators designed around the limitation of an >> API. The design no longer needs to make the same compromises if you're >> going to know the size. The difference between no cache miss and a cache >> miss is not insignificant... > > I explained why I think a chunk header is necessary in any case. > Maybe it is still a significant win. The C++14 proposal claims Google > found one with GCC and tcmalloc, although tcmalloc is rather > inefficient to start with... I would like to see numbers. > > Then again, I agree with the other reasons that using ~[T] is a bad > idea, so I have no particular reason to disagree with having the size > parameter either. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From niko at alum.mit.edu Thu Apr 3 04:39:47 2014 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 3 Apr 2014 07:39:47 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533CB7B4.3080009@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> Message-ID: <20140403113947.GG32313@Mr-Bennet> On Wed, Apr 02, 2014 at 09:21:56PM -0400, Daniel Micay wrote: > ...A distinct `~[T]` and `Vec` will make the language more > painful to use... This is precisely the matter of debate, isn't it? I personally see two sides to this, which is why I was suggesting that maybe we should wait until we can gain a bit more experience before making a final decision here. Niko From dbau.pp at gmail.com Thu Apr 3 05:03:38 2014 From: dbau.pp at gmail.com (Huon Wilson) Date: Thu, 03 Apr 2014 23:03:38 +1100 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <20140402232257.GE20540@Mr-Bennet> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> Message-ID: <533D4E1A.9070000@gmail.com> On 03/04/14 10:22, Niko Matsakis wrote: > On Wed, Apr 02, 2014 at 04:03:37PM -0400, Daniel Micay wrote: >> I have no sane proposal to fix this beyond passing a size to free. > I don't believe there is a problem with just not using null to > represent such pointers (for example, 1 would suffice). This does > impose some additional burdens on slice conversion and the like. > > This conversation has focused on low-level effects, which is important > to understand, but I think the bigger question is: how do we WANT the > language to look? Is it useful to have a distinct `Vec` and `~[T]` > or -- in our ideal world -- would they be the same? I think we can > make the interconversion fast for the default allocator, but we should > design for the language we want to use. > > I could go either way on this. In the kind of programs I write, at > least, most vectors get built up to a specific length and then stop > growing (frequently they stop changing as well, but not > always). Sometimes they continue growing. I actually rather like the > idea of using `Vec` as a kind of builder and `~[T]` as the > end-product. In those cases where the vector continues to grow, of > course, I can just keep the `Vec` around. Following this logic, I > would imagine that most APIs want to consume and produce `~[T]`, since > they consume and produce end products. I don't think the basic routines returning vectors in libstd etc. are producing end-products; they are fundamental building blocks, and their output will be used in untold ways. (There are not many that consume `~[T]`s by-value.) > > On the other hand, I could imagine and appreciate an argument that we > should just take and produce `Vec`, which gives somewhat more > flexibility. In general, Rust takes the philosophy that "if you own > it, you can mutate it", so why make growing harder than it needs to > be? Preferring Vec also means fewer choices, usually a good thing. > > Perhaps the best thing is to wait a month (or two or three) until DST > is more of a reality and then see how we feel. Are you thinking we should also wait before converting the current uses of ~[T] to Vec? Doing the migration gives us the performance[1] and zero-length-zero-alloc benefits, but there were some concerns about additional library churn if we end up converting back to DST's ~[T]. (I'd also guess doing a complete migration now would make the transition slightly easier: no need for staging the libstd changes, and it would allow the current ~[] handling to be removed from libsyntax/librustc completely, leaving a slightly cleaner slate.) Huon [1]: https://github.com/mozilla/rust/issues/8981 From ben.striegel at gmail.com Thu Apr 3 05:15:28 2014 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 3 Apr 2014 08:15:28 -0400 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: References: <533B54C7.4090804@gmail.com> Message-ID: In terms of making hello world nice in 0.10, I prefer to simply put something else in the format string in order to clarify what the first argument is there for: fn main() { let x = "world"; println!("Hello, {:s}!", x); } Also remember that saying `println!("Hello, world!");` by itself still works. On Wed, Apr 2, 2014 at 1:34 PM, Steve Klabnik wrote: > I compiled from source just yesterday, but everything's been going > swimmingly! > > I just have one comment on 0.10: It seems like println was removed > from the prelude. While I can totally appreciate that most people will > use println!, which is automatically use-able, it _is_ making my > 'hello world' examples significantly more complex, since basically > every one of them needs to either import println or use println!("{}", > foo); > > I'm not sure if this is a good or bad thing, just wanted to raise that > as a possible issue. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Apr 3 09:24:35 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 03 Apr 2014 12:24:35 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <20140403113947.GG32313@Mr-Bennet> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> <20140403113947.GG32313@Mr-Bennet> Message-ID: <533D8B43.4000206@gmail.com> On 03/04/14 07:39 AM, Niko Matsakis wrote: > On Wed, Apr 02, 2014 at 09:21:56PM -0400, Daniel Micay wrote: >> ...A distinct `~[T]` and `Vec` will make the language more >> painful to use... > > This is precisely the matter of debate, isn't it? I personally see two > sides to this, which is why I was suggesting that maybe we should wait > until we can gain a bit more experience before making a final decision > here. I don't think there's much doubt that it will add conversions between the two to Rust code, requiring more code to get stuff done. It won't improve either safety or performance to be using it in the library API boundaries. It may aid in writing correct code by catching programmer errors, but there has yet to be someone arguing that this is the case with compelling examples. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From hatahet at gmail.com Thu Apr 3 10:22:26 2014 From: hatahet at gmail.com (Ziad Hatahet) Date: Thu, 3 Apr 2014 10:22:26 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533D8B43.4000206@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> <20140403113947.GG32313@Mr-Bennet> <533D8B43.4000206@gmail.com> Message-ID: Would it be useful to look at what other languages are doing? For instance, slices in Go are appendable, so perhaps it would be worth looking at code bases written in Go to see how they deal with slices, or how often they append to slices returned from standard library routines. -- Ziad On Thu, Apr 3, 2014 at 9:24 AM, Daniel Micay wrote: > On 03/04/14 07:39 AM, Niko Matsakis wrote: > > On Wed, Apr 02, 2014 at 09:21:56PM -0400, Daniel Micay wrote: > >> ...A distinct `~[T]` and `Vec` will make the language more > >> painful to use... > > > > This is precisely the matter of debate, isn't it? I personally see two > > sides to this, which is why I was suggesting that maybe we should wait > > until we can gain a bit more experience before making a final decision > > here. > > I don't think there's much doubt that it will add conversions between > the two to Rust code, requiring more code to get stuff done. It won't > improve either safety or performance to be using it in the library API > boundaries. It may aid in writing correct code by catching programmer > errors, but there has yet to be someone arguing that this is the case > with compelling examples. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Apr 3 11:09:53 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 03 Apr 2014 14:09:53 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> <20140403113947.GG32313@Mr-Bennet> <533D8B43.4000206@gmail.com> Message-ID: <533DA3F1.2010807@gmail.com> On 03/04/14 01:22 PM, Ziad Hatahet wrote: > Would it be useful to look at what other languages are doing? For > instance, slices in Go are appendable, so perhaps it would be worth > looking at code bases written in Go to see how they deal with slices, or > how often they append to slices returned from standard library routines. > > -- > Ziad Go doesn't have an equivalent to what `~[T]` will be. std::unique_ptr is rarely used in C++, and exists solely for interoperability with legacy code. This is a common use case for std::unique_ptr in C++, which is why it takes a destructor parameter. For example, a lone function returning a FILE * pointer can be dealt with by doing `auto file = make_unique(get_file(), fclose)`, which gives you a `std::unique_ptr`. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From alex at crichton.co Thu Apr 3 11:23:42 2014 From: alex at crichton.co (Alex Crichton) Date: Thu, 3 Apr 2014 11:23:42 -0700 Subject: [rust-dev] Rust 0.10 Released Message-ID: Mozilla and the Rust community are pleased to announce version 0.10 of the Rust compiler and tools. Rust is a systems programming language with a focus on safety, performance and concurrency. This was an exciting release cycle where we broke apart the libextra library, introduced cross-crate syntax extensions and macros, improved the smart pointer experience with the Deref trait, and improved error handling in I/O. Outside of the compiler, this release has seen the introduction of a new RFC process as well as support for nightly binary installers. The brief release notes are included in this announcement, and there is further explanation in the detailed release [notes] on the wiki. Documentation and all the links in this email are available on the [website]. As usual, version 0.10 should be considered an alpha release, suitable for early adopters and language enthusiasts. Please file [bugs] and join the [fun]. [website]: http://www.rust-lang.org [notes]: https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes [bugs]: https://github.com/mozilla/rust/issues [fun]: https://github.com/mozilla/rust/wiki/Note-guide-for-new-contributors This release introduces some brand new methods to install Rust for Linux and Mac OS X. In addition to a source tarball, binary installers are now available for download in a variety of formats. Source * http://static.rust-lang.org/dist/rust-0.10.tar.gz http://static.rust-lang.org/dist/rust-0.10.tar.gz.asc SHA256 (of .tar.gz): c72cfbbf03016804a81d7b68e8258ffaf018f8f5a25550ad64571ce6c2642cf9 Windows installer * http://static.rust-lang.org/dist/rust-0.10-install.exe http://static.rust-lang.org/dist/rust-0.10-install.exe.asc SHA256 (of .exe): ee7ea67845f5dd3b545b225135cca21fa5786baef4ab03f9f996f2e72bf40c6e Linux binary tarballs * http://static.rust-lang.org/dist/rust-0.10-x86_64-unknown-linux-gnu.tar.gz http://static.rust-lang.org/dist/rust-0.10-x86_64-unknown-linux-gnu.tar.gz.asc SHA256 (of .tar.gz): e5d6d490beee3c8f2d284f62e730193a92080d4cdf46bf972a8ddbec5bc16045 * http://static.rust-lang.org/dist/rust-0.10-i686-unknown-linux-gnu.tar.gz http://static.rust-lang.org/dist/rust-0.10-i686-unknown-linux-gnu.tar.gz.asc SHA256 (of .tar.gz): 7e17912b23dc790ca8ff3272500beba41afc9a1cd923bbf7a606e7d21d3ea89a Mac OS X binary installers * http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.pkg http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.pkg.asc SHA256 (of .pkg): 332253023b8f641b6d0b21289a1542521d83d1e77c6aa4d1a9b94c2927769407 * http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.pkg http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.pkg.asc SHA256 (of .pkg): 26b5630083afd2286526128158e9d83fb9d4b7d965d9d89e6c6cf536105ed756 Mac OS X binary tarballs * http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.tar.gz http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.tar.gz.asc SHA256 (of .tar.gz): ad0ad37886a43f0817f8115ae4e5daf17912fc31d258ebf79a73647bcc5f4eb8 * http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.tar.gz http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.tar.gz.asc SHA256 (of .tar.gz): 96c51f784e0f5c13d02c1fa4f4ad35936c0396afd8e2217b07f9708be08e06bb Thanks to everyone who contributed! Regards, The Rust Team Version 0.10 (April 2014) ------------------------- * ~1500 changes, numerous bugfixes * Language * A new RFC process is now in place for modifying the language. * Patterns with `@`-pointers have been removed from the language. * Patterns with unique vectors (`~[T]`) have been removed from the language. * Patterns with unique strings (`~str`) have been removed from the language. * `@str` has been removed from the language. * `@[T]` has been removed from the language. * `@self` has been removed from the language. * `@Trait` has been removed from the language. * Headers on `~` allocations which contain `@` boxes inside the type for reference counting have been removed. * The semantics around the lifetimes of temporary expressions have changed, see #3511 and #11585 for more information. * Cross-crate syntax extensions are now possible, but feature gated. See #11151 for more information. This includes both `macro_rules!` macros as well as syntax extensions such as `format!`. * New lint modes have been added, and older ones have been turned on to be warn-by-default. * Unnecessary parentheses * Uppercase statics * Camel Case types * Uppercase variables * Publicly visible private types * `#[deriving]` with raw pointers * Unsafe functions can no longer be coerced to closures. * Various obscure macros such as `log_syntax!` are now behind feature gates. * The `#[simd]` attribute is now behind a feature gate. * Visibility is no longer allowed on `extern crate` statements, and unnecessary visibility (`priv`) is no longer allowed on `use` statements. * Trailing commas are now allowed in argument lists and tuple patterns. * The `do` keyword has been removed, it is now a reserved keyword. * Default type parameters have been implemented, but are feature gated. * Borrowed variables through captures in closures are now considered soundly. * `extern mod` is now `extern crate` * The `Freeze` trait has been removed. * The `Share` trait has been added for types that can be shared among threads. * Labels in macros are now hygienic. * Expression/statement macro invocations can be delimited with `{}` now. * Treatment of types allowed in `static mut` locations has been tweaked. * The `*` and `.` operators are now overloadable through the `Deref` and `DerefMut` traits. * `~Trait` and `proc` no longer have `Send` bounds by default. * Partial type hints are now supported with the `_` type marker. * An `Unsafe` type was introduced for interior mutability. It is now considered undefined to transmute from `&T` to `&mut T` without using the `Unsafe` type. * The #[linkage] attribute was implemented for extern statics/functions. * The inner attribute syntax has changed from `#[foo];` to `#![foo]`. * `Pod` was renamed to `Copy`. * Libraries * The `libextra` library has been removed. It has now been decomposed into component libraries with smaller and more focused nuggets of functionality. The full list of libraries can be found on the documentation index page. * std: `std::condition` has been removed. All I/O errors are now propagated through the `Result` type. In order to assist with error handling, a `try!` macro for unwrapping errors with an early return and an lint for unused results has been added. See #12039 for more information. * std: The `vec` module has been renamed to `slice`. * std: A new vector type, `Vec`, has been added in preparation for DST. This will become the only growable vector in the future. * std: `std::io` now has more public-reexports. Types such as `BufferedReader` are now found at `std::io::BufferedReader` instead of `std::io::buffered::BufferedReader`. * std: `print` and `println` are no longer in the prelude, the `print!` and `println!` macros are intended to be used instead. * std: `Rc` now has a `Weak` pointer for breaking cycles, and it no longer attempts to statically prevent cycles. * std: The standard distribution is adopting the policy of pushing failure to the user rather than failing in libraries. Many functions (such as `slice::last()`) now return `Option` instead of `T` + failing. * std: `fmt::Default` has been renamed to `fmt::Show`, and it now has a new deriving mode: `#[deriving(Show)]`. * std: `ToStr` is now implemented for all types implementing `Show`. * std: The formatting trait methods now take `&self` instead of `&T` * std: The `invert()` method on iterators has been renamed to `rev()` * std: `std::num` has seen a reduction in the genericity of its traits, consolidating functionality into a few core traits. * std: Backtraces are now printed on task failure if the environment variable `RUST_BACKTRACE` is present. * std: Naming conventions for iterators have been standardized. More details can be found on the wiki's style guide. * std: `eof()` has been removed from the `Reader` trait. Specific types may still implement the function. * std: Networking types are now cloneable to allow simultaneous reads/writes. * std: `assert_approx_eq!` has been removed * std: The `e` and `E` formatting specifiers for floats have been added to print them in exponential notation. * std: The `Times` trait has been removed * std: Indications of variance and opting out of builtin bounds is done through marker types in `std::kinds::marker` now * std: `hash` has been rewritten, `IterBytes` has been removed, and `#[deriving(Hash)]` is now possible. * std: `SharedChan` has been removed, `Sender` is now cloneable. * std: `Chan` and `Port` were renamed to `Sender` and `Receiver`. * std: `Chan::new` is now `channel()`. * std: A new synchronous channel type has been implemented. * std: A `select!` macro is now provided for selecting over `Receiver`s. * std: `hashmap` and `trie` have been moved to `libcollections` * std: `run` has been rolled into `io::process` * std: `assert_eq!` now uses `{}` instead of `{:?}` * std: The equality and comparison traits have seen some reorganization. * std: `rand` has moved to `librand`. * std: `to_{lower,upper}case` has been implemented for `char`. * std: Logging has been moved to `liblog`. * collections: `HashMap` has been rewritten for higher performance and less memory usage. * native: The default runtime is now `libnative`. If `libgreen` is desired, it can be booted manually. The runtime guide has more information and examples. * native: All I/O functionality except signals has been implemented. * green: Task spawning with `libgreen` has been optimized with stack caching and various trimming of code. * green: Tasks spawned by `libgreen` now have an unmapped guard page. * sync: The `extra::sync` module has been updated to modern rust (and moved to the `sync` library), tweaking and improving various interfaces while dropping redundant functionality. * sync: A new `Barrier` type has been added to the `sync` library. * sync: An efficient mutex for native and green tasks has been implemented. * serialize: The `base64` module has seen some improvement. It treats newlines better, has non-string error values, and has seen general cleanup. * fourcc: A `fourcc!` macro was introduced * hexfloat: A `hexfloat!` macro was implemented for specifying floats via a hexadecimal literal. * Tooling * `rustpkg` has been deprecated and removed from the main repository. Its replacement, `cargo`, is under development. * Nightly builds of rust are now available * The memory usage of rustc has been improved many times throughout this release cycle. * The build process supports disabling rpath support for the rustc binary itself. * Code generation has improved in some cases, giving more information to the LLVM optimization passes to enable more extensive optimizations. * Debuginfo compatibility with lldb on OSX has been restored. * The master branch is now gated on an android bot, making building for android much more reliable. * Output flags have been centralized into one `--emit` flag. * Crate type flags have been centralized into one `--crate-type` flag. * Codegen flags have been consolidated behind a `-C` flag. * Linking against outdated crates now has improved error messages. * Error messages with lifetimes will often suggest how to annotate the function to fix the error. * Many more types are documented in the standard library, and new guides were written. * Many `rustdoc` improvements: * code blocks are syntax highlighted. * render standalone markdown files. * the --test flag tests all code blocks by default. * exported macros are displayed. * reexported types have their documentation inlined at the location of the first reexport. * search works across crates that have been rendered to the same output directory. Contributors to Rust 0.10 ------------------------ Adrien T?tar Alan Andrade Alex Crichton Alex Whitney a_m0d Andre Arko Andrew Chin aochagavia Arcterus Axel Viala aydin.kim b1nd Ben Harris Ben Noordhuis Ben Striegel Birunthan Mohanathas Bj?rn Steinbrink Brendan Zabarauskas Brian Anderson Brian Leibig Bruno de Oliveira Abinader Byron Williams Cadence Marseille Carl-Anton Ingmarsson Chris Morgan Chris Wong chromatic Clark Gaebel Cole Mickens Colin Sherratt comex Corey Richardson Daniel Fagnan Daniel MacDougall Daniel Micay Dave Hodder David Manescu Davis Silverman Derek Chiang Derek Guenther Div Shekhar
Dmitry Promsky Dmitry Vasiliev Douglas Young Dylan Braithwaite Eduard Bopp Eduard Burtescu Edward Wang Edward Z. Yang Ehsanul Hoque Erick Tryzelaar Eunchong Yu Felix Crux Felix S. Klock II Flavio Percoco Florian Hahn Florian Zeitz G?bor Lehel Gary M. Josack gentlefolk Geoffroy Couprie George Papanikolaou gifnksm Guillaume Pinot HeroesGrave Hong Chulju Huon Wilson Ian Daniher Ivan Enderlin Jack Moffitt Jag Talon Jake Kerr James Deng James Miller Jan Kobler Jan Niklas Hasse Jason Fager Jed Davis Jeff Olson JeremyLetang joaoxsouls Johannes L?thberg Johannes Muenzel Jonathan S Jorge Aparicio Jyun-Yan You Kang Seonghoon Keshav Kini Kevin Ballard Kiet Tran klutzy korenchkin kud1ing kvark Laurent Bonnans Liigo Zhuang Lindsey Kuper lpy Luca Bruno lucy Luqman Aden Luqman Aden Marcel Rodrigues Marvin L?bel Matt Brubeck Matthew McPherrin Matthias Einwag Matthijs van der Vleuten Micah Chalmer Michael Darakananda Michael Woerister Micka?l Delahaye Mike Boutin mr.Shu Ms2ger musitdev Nathaniel Herman Nick Cameron Nick Desaulniers Nif Ward Niko Matsakis noam OGINO Masanori Olle Jonsson Palmer Cox

Patrick Walton Peter Marheine Petter Remen Piotr Czarnecki Piotr Zolnierek Q.P.Liu Raphael Catolino Richard Diamond Robert Gawdzik Ryan Scheel (Havvy) Salem Talha Scott Jenkins Scott Lawrence Sean Chalmers Sean McArthur Seo Sanghyeon Shamir Khodzha SiegeLord Simon Sapin Stepan Koltsov Sterling Greene Steven Fackler Steven Stewart-Gallus Ted Horst Tobias Bucher Tomas Sedovic Tom Lee TorstenWeber Trent Ogren Vadim Chugunov Virgile Andreani WebeWizard William Ting xales Yehuda Katz Yuri Kunde Schlesner Zach Kamsler Ziad Hatahet zslayton From hatahet at gmail.com Thu Apr 3 12:40:48 2014 From: hatahet at gmail.com (Ziad Hatahet) Date: Thu, 3 Apr 2014 12:40:48 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533DA3F1.2010807@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533CB7B4.3080009@gmail.com> <20140403113947.GG32313@Mr-Bennet> <533D8B43.4000206@gmail.com> <533DA3F1.2010807@gmail.com> Message-ID: On Thu, Apr 3, 2014 at 11:09 AM, Daniel Micay wrote: > > Go doesn't have an equivalent to what `~[T]` will be. > > Which was my point. From what I understand, Go's slices are analogous to Rust's Vec in that they are growable. So I was suggesting perusing existing Go code bases to see how often slices returned from standard library routines are appended to; which seems to be one motivator for ~[T]. -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From hatahet at gmail.com Thu Apr 3 12:43:29 2014 From: hatahet at gmail.com (Ziad Hatahet) Date: Thu, 3 Apr 2014 12:43:29 -0700 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: <533C79E7.7090900@mozilla.com> References: <533B54C7.4090804@gmail.com> <533C79E7.7090900@mozilla.com> Message-ID: But `println!("hello world")` works. What am I missing? -- Ziad On Wed, Apr 2, 2014 at 1:58 PM, Brian Anderson wrote: > I've been worried about this decision too. > > > On 04/02/2014 10:34 AM, Steve Klabnik wrote: > >> I compiled from source just yesterday, but everything's been going >> swimmingly! >> >> I just have one comment on 0.10: It seems like println was removed >> from the prelude. While I can totally appreciate that most people will >> use println!, which is automatically use-able, it _is_ making my >> 'hello world' examples significantly more complex, since basically >> every one of them needs to either import println or use println!("{}", >> foo); >> >> I'm not sure if this is a good or bad thing, just wanted to raise that >> as a possible issue. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu Apr 3 12:58:06 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 03 Apr 2014 15:58:06 -0400 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: References: <533B54C7.4090804@gmail.com> <533C79E7.7090900@mozilla.com> Message-ID: <533DBD4E.2050601@gmail.com> On 03/04/14 03:43 PM, Ziad Hatahet wrote: > But `println!("hello world")` works. What am I missing? > > -- > Ziad It works when there's a string constants, not with a variable. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From rusty.gates at icloud.com Thu Apr 3 17:18:13 2014 From: rusty.gates at icloud.com (Tommi) Date: Fri, 04 Apr 2014 03:18:13 +0300 Subject: [rust-dev] Tagged integral & floating-point types Message-ID: I have a suggestion. Let's add new primitive data types: i7, i15, i31, i63, u7, u15, u31, u63, f31 and f63 Those would behave exactly like the integral data and floating-point data types: i8, i16, i32, i64, u8, u16, u32, u64, f32 and f64 ...except that the new data types would come with the (unchecked) promise that the high-order bit of each of those new data types' representations would never be set to 1 (with the floating-point types it would be the high-order bit of the exponent). That would reduce the range of values the user is supposed to represent with those types. But the new types would give rise to an optimization for Option, where X is one of the new primitive data types: Option wouldn't need to use extra memory for a separate tag, but could simply use the high-order bit as a tag to indicate the None case. If a user assigns a value which sets the high-order bit of those data types, then it would be considered a logical overflow (even though the actually representation hasn't overflown) and Some(x) where x is such a logical overflown value would be None (which, to me, kind of makes sense). From rusty.gates at icloud.com Thu Apr 3 17:26:38 2014 From: rusty.gates at icloud.com (Tommi) Date: Fri, 04 Apr 2014 03:26:38 +0300 Subject: [rust-dev] Tagged integral & floating-point types In-Reply-To: References: Message-ID: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> I forgot to mention that this same space-optimization could be done for Option already. On 2014-04-04, at 03:18, Tommi wrote: > I have a suggestion. Let's add new primitive data types: > > i7, i15, i31, i63, u7, u15, u31, u63, f31 and f63 > > Those would behave exactly like the integral data and floating-point data types: > > i8, i16, i32, i64, u8, u16, u32, u64, f32 and f64 > > ...except that the new data types would come with the (unchecked) promise that the high-order bit of each of those new data types' representations would never be set to 1 (with the floating-point types it would be the high-order bit of the exponent). That would reduce the range of values the user is supposed to represent with those types. But the new types would give rise to an optimization for Option, where X is one of the new primitive data types: Option wouldn't need to use extra memory for a separate tag, but could simply use the high-order bit as a tag to indicate the None case. If a user assigns a value which sets the high-order bit of those data types, then it would be considered a logical overflow (even though the actually representation hasn't overflown) and Some(x) where x is such a logical overflown value would be None (which, to me, kind of makes sense). > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From corey at octayn.net Thu Apr 3 17:37:33 2014 From: corey at octayn.net (Corey Richardson) Date: Thu, 3 Apr 2014 20:37:33 -0400 Subject: [rust-dev] Tagged integral & floating-point types In-Reply-To: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> References: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> Message-ID: Language suggestions should go through our new RFC process: https://github.com/rust-lang/rfcs/blob/master/active/0001-rfc-process.md On Thu, Apr 3, 2014 at 8:26 PM, Tommi wrote: > I forgot to mention that this same space-optimization could be done for Option already. > > > On 2014-04-04, at 03:18, Tommi wrote: > >> I have a suggestion. Let's add new primitive data types: >> >> i7, i15, i31, i63, u7, u15, u31, u63, f31 and f63 >> >> Those would behave exactly like the integral data and floating-point data types: >> >> i8, i16, i32, i64, u8, u16, u32, u64, f32 and f64 >> >> ...except that the new data types would come with the (unchecked) promise that the high-order bit of each of those new data types' representations would never be set to 1 (with the floating-point types it would be the high-order bit of the exponent). That would reduce the range of values the user is supposed to represent with those types. But the new types would give rise to an optimization for Option, where X is one of the new primitive data types: Option wouldn't need to use extra memory for a separate tag, but could simply use the high-order bit as a tag to indicate the None case. If a user assigns a value which sets the high-order bit of those data types, then it would be considered a logical overflow (even though the actually representation hasn't overflown) and Some(x) where x is such a logical overflown value would be None (which, to me, kind of makes sense). >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ From ncm at cantrip.org Thu Apr 3 20:48:20 2014 From: ncm at cantrip.org (Nathan Myers) Date: Thu, 03 Apr 2014 20:48:20 -0700 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533D4E1A.9070000@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> Message-ID: <533E2B84.3070806@cantrip.org> >> Perhaps the best thing is to wait a month (or two or three) until DST >> is more of a reality and then see how we feel. > > Are you thinking we should also wait before converting the current uses > of ~[T] to Vec? Doing the migration gives us the performance[1] and > zero-length-zero-alloc benefits, but there were some concerns about > additional library churn if we end up converting back to DST's ~[T]. I can't speak about how a usage choice affects the standard library, but it seems worth mentioning that vector capacity doesn't have to be in the base object; it can live in the secondary storage, prepended before the elements. A zero-length Vec might be null for the case of zero capacity, or non-null when it has room to grow. For maximally trivial conversion to ~T[], the pointer in Vec would point to the first element, with the capacity at a negative offset. Nathan Myers From com.liigo at gmail.com Thu Apr 3 21:13:49 2014 From: com.liigo at gmail.com (Liigo Zhuang) Date: Fri, 4 Apr 2014 12:13:49 +0800 Subject: [rust-dev] 0.10 prerelease testing In-Reply-To: <533CEE20.8080904@gmail.com> References: <533B54C7.4090804@gmail.com> <533C7C36.10103@exyr.org> <62FFEA03-B648-4A49-8070-1A4ECE89ED4E@sb.org> <533CEE20.8080904@gmail.com> Message-ID: +1 for printf! and printfln! 2014?4?3? ??1:14? "Daniel Micay" ??? > Perhaps we should have `print` and `println` back in the prelude and > call these `printf!` and `printfln!`. I think it would be a lot clearer, > as people always ask how these are different from `print` and `println`. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Fri Apr 4 00:13:07 2014 From: rusty.gates at icloud.com (Tommi) Date: Fri, 04 Apr 2014 10:13:07 +0300 Subject: [rust-dev] Tagged integral & floating-point types In-Reply-To: References: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> Message-ID: <851A4659-40EC-4AC9-BDC8-609FA768B36D@icloud.com> Okay. But first I'd like to get some input on for what types T should the language guarantee this suggested optimization for Option. Because the optimization could be done for any type T from which at least one or more of these new primitive data types is accessible. But it's not clear whether or not it should be done if accessing one of those has to go through one or more indirections. I assume that if at least one of these new primitive data types can be accessed through T without any indirections, then it always makes sense to do this optimization. On 2014-04-04, at 03:37, Corey Richardson wrote: > Language suggestions should go through our new RFC process: > https://github.com/rust-lang/rfcs/blob/master/active/0001-rfc-process.md > > On Thu, Apr 3, 2014 at 8:26 PM, Tommi wrote: >> I forgot to mention that this same space-optimization could be done for Option already. >> >> >> On 2014-04-04, at 03:18, Tommi wrote: >> >>> I have a suggestion. Let's add new primitive data types: >>> >>> i7, i15, i31, i63, u7, u15, u31, u63, f31 and f63 >>> >>> Those would behave exactly like the integral data and floating-point data types: >>> >>> i8, i16, i32, i64, u8, u16, u32, u64, f32 and f64 >>> >>> ...except that the new data types would come with the (unchecked) promise that the high-order bit of each of those new data types' representations would never be set to 1 (with the floating-point types it would be the high-order bit of the exponent). That would reduce the range of values the user is supposed to represent with those types. But the new types would give rise to an optimization for Option, where X is one of the new primitive data types: Option wouldn't need to use extra memory for a separate tag, but could simply use the high-order bit as a tag to indicate the None case. If a user assigns a value which sets the high-order bit of those data types, then it would be considered a logical overflow (even though the actually representation hasn't overflown) and Some(x) where x is such a logical overflown value would be None (which, to me, kind of makes sense). >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > > -- > http://octayn.net/ From rust-dev at tomlee.co Fri Apr 4 00:32:53 2014 From: rust-dev at tomlee.co (Tom Lee) Date: Fri, 4 Apr 2014 00:32:53 -0700 Subject: [rust-dev] A More Detailed Tour of the Rust Compiler Message-ID: Hey folks, I took the slides from my talk at last week's PDX-Rust meetup & slapped together a blog post that covers some of the innards of the Rust compiler in a little more detail: http://tomlee.co/2014/04/03/a-more-detailed-tour-of-the-rust-compiler/ It kind of reads somewhere between a high level overview and a detailed look at compiler innards, but hopefully it's useful to somebody out there. Cheers, Tom -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From vadimcn at gmail.com Fri Apr 4 02:30:08 2014 From: vadimcn at gmail.com (Vadim Chugunov) Date: Fri, 4 Apr 2014 02:30:08 -0700 Subject: [rust-dev] Tagged integral & floating-point types In-Reply-To: <851A4659-40EC-4AC9-BDC8-609FA768B36D@icloud.com> References: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> <851A4659-40EC-4AC9-BDC8-609FA768B36D@icloud.com> Message-ID: Regarding the original idea: Why use a whole bit, when you only need one value out of all possible type's values? For example, for floats, one of the NaNs could be used for this purpose without any issues with overflow as would happen in your proposal. Regarding "which types?": Perhaps this should be controlled via another built-in trait, such as the following: trait Invalid { fn invalid() -> Self; } The compiler could then perform option space optimization for any type implementing 'Invalid'. On Fri, Apr 4, 2014 at 12:13 AM, Tommi wrote: > Okay. But first I'd like to get some input on for what types T should the > language guarantee this suggested optimization for Option. Because the > optimization could be done for any type T from which at least one or more > of these new primitive data types is accessible. But it's not clear whether > or not it should be done if accessing one of those has to go through one or > more indirections. I assume that if at least one of these new primitive > data types can be accessed through T without any indirections, then it > always makes sense to do this optimization. > > > On 2014-04-04, at 03:37, Corey Richardson wrote: > > > Language suggestions should go through our new RFC process: > > https://github.com/rust-lang/rfcs/blob/master/active/0001-rfc-process.md > > > > On Thu, Apr 3, 2014 at 8:26 PM, Tommi wrote: > >> I forgot to mention that this same space-optimization could be done for > Option already. > >> > >> > >> On 2014-04-04, at 03:18, Tommi wrote: > >> > >>> I have a suggestion. Let's add new primitive data types: > >>> > >>> i7, i15, i31, i63, u7, u15, u31, u63, f31 and f63 > >>> > >>> Those would behave exactly like the integral data and floating-point > data types: > >>> > >>> i8, i16, i32, i64, u8, u16, u32, u64, f32 and f64 > >>> > >>> ...except that the new data types would come with the (unchecked) > promise that the high-order bit of each of those new data types' > representations would never be set to 1 (with the floating-point types it > would be the high-order bit of the exponent). That would reduce the range > of values the user is supposed to represent with those types. But the new > types would give rise to an optimization for Option, where X is one of > the new primitive data types: Option wouldn't need to use extra memory > for a separate tag, but could simply use the high-order bit as a tag to > indicate the None case. If a user assigns a value which sets the high-order > bit of those data types, then it would be considered a logical overflow > (even though the actually representation hasn't overflown) and Some(x) > where x is such a logical overflown value would be None (which, to me, kind > of makes sense). > >>> > >>> _______________________________________________ > >>> Rust-dev mailing list > >>> Rust-dev at mozilla.org > >>> https://mail.mozilla.org/listinfo/rust-dev > >> > >> _______________________________________________ > >> Rust-dev mailing list > >> Rust-dev at mozilla.org > >> https://mail.mozilla.org/listinfo/rust-dev > > > > > > > > -- > > http://octayn.net/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Fri Apr 4 05:11:25 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Fri, 4 Apr 2014 13:11:25 +0100 Subject: [rust-dev] matching on a few bits in int In-Reply-To: References: Message-ID: I've submitted an RFC for this one: https://github.com/rust-lang/rfcs/pull/29 On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers wrote: > I think the best solution is to add uN and sN types where N is not a power > of two, which LLVM should already support. > > Then you can write your match like this: > match (val >> 6) as u2 > { > ... > } > > And it will work as desired. > > Biggest issue is that to make it work nicely you'd need to add some way to > generalize over the bit-length and integers, and that's going to require > generics with int parameters and work to add those. > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Fri Apr 4 05:32:37 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 04 Apr 2014 08:32:37 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533E2B84.3070806@cantrip.org> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> Message-ID: <533EA665.9070501@gmail.com> On 03/04/14 11:48 PM, Nathan Myers wrote: > >>> Perhaps the best thing is to wait a month (or two or three) until DST >>> is more of a reality and then see how we feel. >> >> Are you thinking we should also wait before converting the current uses >> of ~[T] to Vec? Doing the migration gives us the performance[1] and >> zero-length-zero-alloc benefits, but there were some concerns about >> additional library churn if we end up converting back to DST's ~[T]. > > I can't speak about how a usage choice affects the standard library, > but it seems worth mentioning that vector capacity doesn't have to be > in the base object; it can live in the secondary storage, prepended > before the elements. Needing to use a header seriously hurts the performance. The new vector is 7x faster at pushing elements when space isn't reserved compared to the old one, all due to leaving off the length/capacity header. The overhead would be less if it stored the capacity inside *and* outside the vector, but it's still overhead. It's an extra overflow check branch along with needing to calculate padding for alignment in the future, extra space in the memory allocation and more pointer aliasing issues. > A zero-length Vec might be null for the case of zero capacity, > or non-null when it has room to grow. It's going to be forbidden from actually being null in the future when the Option-like enum optimization is applied to it via an attribute. This work has already landed - calling exchange_free on a zero-size allocation is *forbidden*. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From rusty.gates at icloud.com Fri Apr 4 06:40:43 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Fri, 04 Apr 2014 16:40:43 +0300 Subject: [rust-dev] Tagged integral & floating-point types In-Reply-To: References: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> <851A4659-40EC-4AC9-BDC8-609FA768B36D@icloud.com> Message-ID: <137EBABF-083A-438A-AB43-309DE8F87A45@icloud.com> > On 04 Apr 2014, at 12:30, Vadim Chugunov wrote: > > Regarding the original idea: Why use a whole bit, when you only need one value out of all possible type's values? For example, for floats, one of the NaNs could be used for this purpose without any issues with overflow as would happen in your proposal. Yes, you're quite right. > Regarding "which types?": Perhaps this should be controlled via another built-in trait, such as the following: > trait Invalid { > fn invalid() -> Self; > } > The compiler could then perform option space optimization for any type implementing 'Invalid'. Again, that makes more sense than my proposal. But I do wonder if it would be necessary to make the restriction that only a compile-time constant would be allowed for the 'invalid' sentinel value. That would require type associated constants and also that traits would be able to require such a constant be defined by its implementor type. But I think those features are bound to land at some point. From manu at meshcapital.com Fri Apr 4 07:51:54 2014 From: manu at meshcapital.com (Manu Thambi) Date: Fri, 04 Apr 2014 10:51:54 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533EA665.9070501@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> <533EA665.9070501@gmail.com> Message-ID: <533EC70A.3040803@meshcapital.com> > Needing to use a header seriously hurts the performance. The new > vector is 7x faster at pushing elements when space isn't reserved > compared to the old one, all due to leaving off the length/capacity > header. The overhead would be less if it stored the capacity inside > *and* outside the vector, but it's still overhead. It's an extra > overflow check branch along with needing to calculate padding for > alignment in the future, extra space in the memory allocation and more > pointer aliasing issues. Perhaps I am not understanding you correctly. Assuming that the capacity is stored inside and outside Vec, the only overhead I see is during allocation/deallocation. Otherwise the code will be identical. If you are worried about space, there is a cost of passing around Vecs ( vs ~[T]), which consumes and extra register for the capacity. > It's going to be forbidden from actually being null in the future when > the Option-like enum optimization is applied to it via an attribute. > This work has already landed - calling exchange_free on a zero-size > allocation is *forbidden*. As mentioned elsewhere on this thread, we can use another invalid pointer value to represent either Option-None or 0 capacity depending on which is more efficient. Manu From danielmicay at gmail.com Fri Apr 4 08:37:52 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 04 Apr 2014 11:37:52 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533EC70A.3040803@meshcapital.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> <533EA665.9070501@gmail.com> <533EC70A.3040803@meshcapital.com> Message-ID: <533ED1D0.1000600@gmail.com> On 04/04/14 10:51 AM, Manu Thambi wrote: > >> Needing to use a header seriously hurts the performance. The new >> vector is 7x faster at pushing elements when space isn't reserved >> compared to the old one, all due to leaving off the length/capacity >> header. The overhead would be less if it stored the capacity inside >> *and* outside the vector, but it's still overhead. It's an extra >> overflow check branch along with needing to calculate padding for >> alignment in the future, extra space in the memory allocation and more >> pointer aliasing issues. > Perhaps I am not understanding you correctly. Assuming that the capacity > is stored inside and outside Vec, the only overhead > I see is during allocation/deallocation. Otherwise the code will be > identical. It bloats the code size by requiring extra overflow checks in functions like `push`, which impacts performance. Unwinding prevents many LLVM passes from doing their job, since it adds significant complexity to the control flow. In addition to this, there is even an impact on the performance of immutable operations like indexing. There's a need to calculate the offset to the first element in the vector, which includes compensating for alignment because there can be padding in between the capacity and the first element in the vector. You can deny that this has performance implications, but the fact is that I have looked at the performance and code size impact in depth and and have hard numbers from benchmarks proving that there is a enormous performance overhead for this choice. > If you are worried about space, there is a cost of > passing around Vecs ( vs ~[T]), which consumes and extra register for > the capacity. Passing vectors around by-value isn't a common operation. In the common case, functions operate on mutable or immutable borrowed slices. In uncommon cases, they operator on `&mut Vec` in order to change the length in place. There are rare cases when ownership needs to be moved, but it's rare for it not to correspond by a constant factor to the number of allocations. >> It's going to be forbidden from actually being null in the future when >> the Option-like enum optimization is applied to it via an attribute. >> This work has already landed - calling exchange_free on a zero-size >> allocation is *forbidden*. > As mentioned elsewhere on this thread, we can use another invalid > pointer value to represent > either Option-None or 0 capacity depending on which is more efficient. I've already implemented support for this in the compiler some time ago and the library portion is now in master. This means it's invalid to call exchange_free on an allocation with a zero size capacity, so slices need to track whether the allocation is zero size. A zero size length does not imply a zero size capacity unless `Vec` -> `~[T]` is not a no-op, which is what I am saying. Commits: 1778b6361627c5894bf75ffecf427573af02d390 898669c4e203ae91e2048fb6c0f8591c867bccc6 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From manu at meshcapital.com Fri Apr 4 10:50:30 2014 From: manu at meshcapital.com (Manu Thambi) Date: Fri, 04 Apr 2014 13:50:30 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533ED1D0.1000600@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> <533EA665.9070501@gmail.com> <533EC70A.3040803@meshcapital.com> <533ED1D0.1000600@gmail.com> Message-ID: <533EF0E6.9050905@meshcapital.com> Thanks for the detailed reply. You clearly have done a lot of work on the code, and I have just been following the mailing lists for a while. So, I might be misunderstanding something here. On 04/04/2014 11:37 AM, Daniel Micay wrote: > It bloats the code size by requiring extra overflow checks in functions > like `push`, which impacts performance. Unwinding prevents many LLVM > passes from doing their job, since it adds significant complexity to the > control flow. > > In addition to this, there is even an impact on the performance of > immutable operations like indexing. There's a need to calculate the > offset to the first element in the vector, which includes compensating > for alignment because there can be padding in between the capacity and > the first element in the vector. > > You can deny that this has performance implications, but the fact is > that I have looked at the performance and code size impact in depth and > and have hard numbers from benchmarks proving that there is a enormous > performance overhead for this choice. As Nathan mentioned, the capacity is stored at a negative offset to the pointer to the heap. So the Vec code should be identical, except that during allocation/re-allocation, we need to compute the heap pointer by adding sizeof(uint) to the value returned by malloc(). (and the opposite computation on free()) indexing, etc, will not change, from how it is done now. > Passing vectors around by-value isn't a common operation. In the > common case, functions operate on mutable or immutable borrowed > slices. In uncommon cases, they operator on `&mut Vec` in order to > change the length in place. There are rare cases when ownership needs > to be moved, but it's rare for it not to correspond by a constant > factor to the number of allocations. I agree that passing around Vec by value is uncommon. But you seem to be concerned about Vec -> ~[T] performance, which should also be a rare transfer of ownership. > I've already implemented support for this in the compiler some time ago > and the library portion is now in master. This means it's invalid to > call exchange_free on an allocation with a zero size capacity, so slices > need to track whether the allocation is zero size. A zero size length > does not imply a zero size capacity unless `Vec` -> `~[T]` is not a > no-op, which is what I am saying. Commits: > > 1778b6361627c5894bf75ffecf427573af02d390 > 898669c4e203ae91e2048fb6c0f8591c867bccc6 I understand that we cannot call free with a zero size/capacity. There are three possibilities: a) Use the special pointer value to represent Option::None. The Vec -> ~[T] would be a no-op. b) If that makes implementation of Option complicated, then use the special pointer value to represent a zero capacity. We can use that special value in Vec as well, even though it is not needed. This will keep Vec -> ~[T] a no-op. c) Conversion between Vec -> ~[T] is not likely to be common. So, doing an additional check is okay? Thanks. Manu From danielmicay at gmail.com Fri Apr 4 11:51:17 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 04 Apr 2014 14:51:17 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533EF0E6.9050905@meshcapital.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> <533EA665.9070501@gmail.com> <533EC70A.3040803@meshcapital.com> <533ED1D0.1000600@gmail.com> <533EF0E6.9050905@meshcapital.com> Message-ID: <533EFF25.7020401@gmail.com> On 04/04/14 01:50 PM, Manu Thambi wrote: > > As Nathan mentioned, the capacity is stored at a negative offset to the > pointer to the heap. Storing at a negative index removes the cost at indexing, but not elsewhere. It still consumes more memory and makes `push` slower, especially since it has to do more than more offset based on alignment with at least one overflow check. > So the Vec code should be identical, except that during > allocation/re-allocation, we need > to compute the heap pointer by adding sizeof(uint) to the value returned > by malloc(). > (and the opposite computation on free()) > > indexing, etc, will not change, from how it is done now. It has to check for overflow on any addition like this. The inability to pass a size to `dealloc` is not going to be free either. Teaching LLVM to understand the pointer gymnastics here means trying to make it simpler rather than allowing it to become more complicated. >> Passing vectors around by-value isn't a common operation. In the >> common case, functions operate on mutable or immutable borrowed >> slices. In uncommon cases, they operator on `&mut Vec` in order to >> change the length in place. There are rare cases when ownership needs >> to be moved, but it's rare for it not to correspond by a constant >> factor to the number of allocations. > > I agree that passing around Vec by value is uncommon. But you seem to be > concerned about > Vec -> ~[T] performance, which should also be a rare transfer of > ownership. I'm not at all concerned about it. I think it would be a huge mistake to use `~[T]` frequently at all, and I'm simply pointing out that this is not going to be a no-op because that claim was made several times. >> I've already implemented support for this in the compiler some time ago >> and the library portion is now in master. This means it's invalid to >> call exchange_free on an allocation with a zero size capacity, so slices >> need to track whether the allocation is zero size. A zero size length >> does not imply a zero size capacity unless `Vec` -> `~[T]` is not a >> no-op, which is what I am saying. Commits: >> >> 1778b6361627c5894bf75ffecf427573af02d390 >> 898669c4e203ae91e2048fb6c0f8591c867bccc6 > > I understand that we cannot call free with a zero size/capacity. > > There are three possibilities: > > a) Use the special pointer value to represent Option::None. The Vec > -> ~[T] would be a no-op. An empty vector is not the same as `None`. Reserving an address is also not possible in all environments Rust is going to be used in as a language, and I think it should be up to the allocator implementation rather than hard-coded knowledge in the compiler. At the moment, the `Some(~())` problem is fixed with no overhead anywhere, and allocators have the choice between a sentinel and clamping zero-size allocations to 1. > b) If that makes implementation of Option complicated, then use the > special pointer value to represent > a zero capacity. We can use that special value in Vec as well, even > though it is not needed. This > will keep Vec -> ~[T] a no-op. This will add a branch to every deallocation call. > c) Conversion between Vec -> ~[T] is not likely to be common. So, > doing an additional check is okay? It's not about there being an additional check. It's about it having to drop excess capacity, which will make conversions to and from `~[T]` hurt. This can easily result in higher time complexity rather than just a constant factor slowdown. I don't think conversion from `Vec` -> `~[T]` is important, and I just want to make it clear that there's no way it is going to be free. The cost can not simply be hand-waved away by moving it elsewhere, such as requiring new branches and losing the ability to pass a size to `dealloc`. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From farcaller at gmail.com Fri Apr 4 12:53:08 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Fri, 4 Apr 2014 20:53:08 +0100 Subject: [rust-dev] Building a static array of pointers Message-ID: Is it possible to port the following C code to rust? __attribute__ ((section(".isr_vector"))) void (* const isr_vector_table[])(void) = { &_stack_base, main, // Reset isr_nmi, // NMI isr_hardfault, // Hard Fault 0, // CM3 Memory Management Fault 0, // CM3 Bus Fault 0, // CM3 Usage Fault &_boot_checksum, // NXP Checksum code 0, // Reserved 0, // Reserved 0, // Reserved isr_svcall, // SVCall 0, // Reserved for debug 0, // Reserved isr_pendsv, // PendSV isr_systick, // SysTick }; here main and isr_* are rust external functions, and _stack_base is defined as extern void _stack_base() and gets loaded from linker script. Also, is it possible to make a weak symbol in rust or somehow emulate it? Weak symbols are used in C code to provide the following functionality: isr_* functions are stubs with default implementation (morse out id code with led, loop forever), but if any of those requires actual code, than it is overrides the weak "morse-blinking" function symbol. -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Fri Apr 4 13:06:02 2014 From: alex at crichton.co (Alex Crichton) Date: Fri, 4 Apr 2014 13:06:02 -0700 Subject: [rust-dev] Building a static array of pointers In-Reply-To: References: Message-ID: As you've discovered in bug #13325, dealing with external constants in static expressions is sometimes a little tricky. I would avoid casting for now (as happens in the bug) in favor of stronger types. For example, this compiles and runs for me: extern { fn foo(); fn bar(); } static table: &'static [extern unsafe fn()] = &[foo, bar]; pub mod test { #[no_mangle] pub extern fn foo() { println!("foo"); } #[no_mangle] pub extern fn bar() { println!("bar"); } } fn main() { for f in table.iter() { unsafe { (*f)(); } } } Note that in rust, a value of type `extern fn()` cannot be null, but `Option` can indeed be null. You'll probably want something along the lines of: #[link_section = ".isr_vector"] pub static ISR_VECTOR_TABLE: [Option, ..N] = [Some(...), None, Some(...), ...]; On Fri, Apr 4, 2014 at 12:53 PM, Vladimir Pouzanov wrote: > Is it possible to port the following C code to rust? > > __attribute__ ((section(".isr_vector"))) > void (* const isr_vector_table[])(void) = { > &_stack_base, > main, // Reset > isr_nmi, // NMI > isr_hardfault, // Hard Fault > 0, // CM3 Memory Management Fault > 0, // CM3 Bus Fault > 0, // CM3 Usage Fault > &_boot_checksum, // NXP Checksum code > 0, // Reserved > 0, // Reserved > 0, // Reserved > isr_svcall, // SVCall > 0, // Reserved for debug > 0, // Reserved > isr_pendsv, // PendSV > isr_systick, // SysTick > }; > > here main and isr_* are rust external functions, and _stack_base is defined > as > > extern void _stack_base() > > and gets loaded from linker script. > > Also, is it possible to make a weak symbol in rust or somehow emulate it? > Weak symbols are used in C code to provide the following functionality: > isr_* functions are stubs with default implementation (morse out id code > with led, loop forever), but if any of those requires actual code, than it > is overrides the weak "morse-blinking" function symbol. > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From manu at meshcapital.com Fri Apr 4 13:12:51 2014 From: manu at meshcapital.com (Manu Thambi) Date: Fri, 04 Apr 2014 16:12:51 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533EFF25.7020401@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> <533EA665.9070501@gmail.com> <533EC70A.3040803@meshcapital.com> <533ED1D0.1000600@gmail.com> <533EF0E6.9050905@meshcapital.com> <533EFF25.7020401@gmail.com> Message-ID: <533F1243.4000200@meshcapital.com> On 04/04/2014 02:51 PM, Daniel Micay wrote: > > Storing at a negative index removes the cost at indexing, but not > elsewhere. It still consumes more memory and makes `push` slower, > especially since it has to do more than more offset based on alignment > with at least one overflow check. In the "negative index scheme", the length and capacity in the Vec would be identical to what is it in the current implementation. Hence the code will be identical, except for while allocating/deallocatiing. (ie, push() would have the same performance) > It has to check for overflow on any addition like this. The inability to > pass a size to `dealloc` is not going to be free either. Teaching LLVM > to understand the pointer gymnastics here means trying to make it > simpler rather than allowing it to become more complicated. I don't understand what addition you mean? The only time you need the size stored in the negative index is to call dealloc. You absolutely can pass size into dealloc while destructing ~[T]. Just use the size, stored in the negative index. > > I'm not at all concerned about it. I think it would be a huge mistake to > use `~[T]` frequently at all, and I'm simply pointing out that this is > not going to be a no-op because that claim was made several times. I will be a no-op, if you use null (0) to indicate 0-capacity, and special value(1?) to indicate Option::None. > An empty vector is not the same as `None`. Reserving an address is also > not possible in all environments Rust is going to be used in as a > language, and I think it should be up to the allocator implementation > rather than hard-coded knowledge in the compiler. At the moment, the > `Some(~())` problem is fixed with no overhead anywhere, and allocators > have the choice between a sentinel and clamping zero-size allocations to 1. Can you name one architecture, where we are not able to find a single extra invalid virtual address other than 0? Just to clear, the "negative index scheme", will allow free() to take the size argument. >> b) If that makes implementation of Option complicated, then use the >> special pointer value to represent >> a zero capacity. We can use that special value in Vec as well, even >> though it is not needed. This >> will keep Vec -> ~[T] a no-op. > This will add a branch to every deallocation call. No it wouldn't. Vec, doesn't have to check the pointer. Just check the capacity. >> c) Conversion between Vec -> ~[T] is not likely to be common. So, >> doing an additional check is okay? > It's not about there being an additional check. It's about it having to > drop excess capacity, which will make conversions to and from `~[T]` > hurt. This can easily result in higher time complexity rather than just > a constant factor slowdown. > > I don't think conversion from `Vec` -> `~[T]` is important, and I > just want to make it clear that there's no way it is going to be free. > > The cost can not simply be hand-waved away by moving it elsewhere, such > as requiring new branches and losing the ability to pass a size to > `dealloc`. > We "negative index scheme" does not require you to drop excess capacity. With this scheme, ~[T] and Vec would contain the same amount info. The only difference is that in ~[T], the capacity is stored at a negative index. In Vec, capacity is stored, both inline and at the negative index. The only overhead would be a couple of checks/additions during allocation/deallocation. Everything else would perform exactly as it does now. Manu From philippe.delrieu at free.fr Fri Apr 4 13:41:01 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Fri, 04 Apr 2014 22:41:01 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion Message-ID: <533F18DD.5040803@free.fr> Hello, I've some problem to find a solution for something I want to do with a vector of enum. This is an example of what I want to do: trait Base { fn set_something(&mut self); } struct FirstThink; impl Base for FirstThink { fn set_something(&mut self) {} } struct SecondThink; impl Base for SecondThink { fn set_something(&mut self) {} } enum BaseImpl { FirstThinkImpl(~FirstThink), SecondThinkImpl(~SecondThink), } fn some_process(list: &mut Vec<&mut ~Base>) { for think in list.mut_iter() { think.set_something(); } } struct Container { nodeList: Vec<~BaseImpl>, } impl Container { fn add_FirstThink(&mut self, think: ~FirstThink) { self.nodeList.push(~FirstThinkImpl(think)); } fn add_SecondThink(&mut self, think: ~SecondThink) { self.nodeList.push(~SecondThinkImpl(think)); } fn do_some_process(&mut self, fct: fn(&mut Vec<&mut ~Base>)) { I didn't find a simple way to convert the Vec<~BaseImpl> to a &mut Vec<&mut ~Base> to do the call fct(self.nodeList); } } I use the enum pattern to have only one collection of object that impl Base but sometime I have to do specific processing depending if the Base is a FirstThink or SecondThink (not in the example). I use the match as follow match think { FirstThinkImpl(first) => do specific first, SecondThinkImpl(second)=> do specific second, }); Perhaps there is a better way to do. Any suggestions would be appreciated. Philippe From danielmicay at gmail.com Fri Apr 4 14:09:53 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 04 Apr 2014 17:09:53 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533F1243.4000200@meshcapital.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> <533EA665.9070501@gmail.com> <533EC70A.3040803@meshcapital.com> <533ED1D0.1000600@gmail.com> <533EF0E6.9050905@meshcapital.com> <533EFF25.7020401@gmail.com> <533F1243.4000200@meshcapital.com> Message-ID: <533F1FA1.4000506@gmail.com> On 04/04/14 04:12 PM, Manu Thambi wrote: > > On 04/04/2014 02:51 PM, Daniel Micay wrote: >> >> Storing at a negative index removes the cost at indexing, but not >> elsewhere. It still consumes more memory and makes `push` slower, >> especially since it has to do more than more offset based on alignment >> with at least one overflow check. > > In the "negative index scheme", the length and capacity in the Vec would > be identical > to what is it in the current implementation. Hence the code will be > identical, except > for while allocating/deallocatiing. (ie, push() would have the same > performance) It won't have the same performance, because the performance hit comes from the code size increase needed to handle offsetting and overflow checking along with aliasing issues. It was slow because a header involves offsets and overflow checks. It also screws up the alias analysis. The negative index solution suffers from this almost as much as the old vector representation. I feel I've made the reasons why it's slower clear and you simply don't believe what I said. The performance gains from removing the header from vectors weren't imaginary. Even a better implementation than the one in `std::slice` is still slower. >> It has to check for overflow on any addition like this. The inability to >> pass a size to `dealloc` is not going to be free either. Teaching LLVM >> to understand the pointer gymnastics here means trying to make it >> simpler rather than allowing it to become more complicated. > I don't understand what addition you mean? The only time you need the > size stored in the negative index > is to call dealloc. > > You absolutely can pass size into dealloc while destructing ~[T]. Just > use the size, stored in the negative index. You can pass it for the negative index proposal, but not the other proposals. The negative index proposal involves bloating the `Vec` type to micro-optimize what is going to be an incredibly rare conversion, while the other proposals lose the ability to pass the length. I don't see a valid reason to change the status quo. >> I'm not at all concerned about it. I think it would be a huge mistake to >> use `~[T]` frequently at all, and I'm simply pointing out that this is >> not going to be a no-op because that claim was made several times. > I will be a no-op, if you use null (0) to indicate 0-capacity, and > special value(1?) to indicate > Option::None. You can't use a special value to indicate None without adding a lang item, no other pointer values are specified by Rust or LLVM as being invalid. >> An empty vector is not the same as `None`. Reserving an address is also >> not possible in all environments Rust is going to be used in as a >> language, and I think it should be up to the allocator implementation >> rather than hard-coded knowledge in the compiler. At the moment, the >> `Some(~())` problem is fixed with no overhead anywhere, and allocators >> have the choice between a sentinel and clamping zero-size allocations >> to 1. > Can you name one architecture, where we are not able to find a single > extra invalid virtual address > other than 0? Whether or not *I* can name such an architecture doesn't matter. Rust is meant to be a portable language, even to platforms this specific contributor is not familiar with. This would add a dependency on global variables for unique pointers, even though you could implement them on in an environment with only a stack using a fixed-size pool. > Just to clear, the "negative index scheme", will allow free() to take > the size argument. I'm talking about all of the proposed solutions such as the ones at the end of your message in isolation from the proposal to require `Vec` to have a header (not going to happen). >>> b) If that makes implementation of Option complicated, then use the >>> special pointer value to represent >>> a zero capacity. We can use that special value in Vec as well, even >>> though it is not needed. This >>> will keep Vec -> ~[T] a no-op. >> This will add a branch to every deallocation call. > > No it wouldn't. Vec, doesn't have to check the pointer. Just check the > capacity. Checking the capacity is a branch. > The only overhead would be a couple of checks/additions during > allocation/deallocation. Everything > else would perform exactly as it does now. It will cause `push` to perform worse than it does now and it will cause `Vec` to allocate more memory. All to micro-optimize a conversion to a nearly useless type. I've made it clear why adding headers to vectors decreases the performance. You clearly don't believe me and I won't be wasting my time on this thread anymore. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From manu at meshcapital.com Fri Apr 4 15:50:19 2014 From: manu at meshcapital.com (Manu Thambi) Date: Fri, 04 Apr 2014 18:50:19 -0400 Subject: [rust-dev] Reminder: ~[T] is not going away In-Reply-To: <533F1FA1.4000506@gmail.com> References: <533C39F6.6000305@gmail.com> <533C6D19.6000003@gmail.com> <20140402232257.GE20540@Mr-Bennet> <533D4E1A.9070000@gmail.com> <533E2B84.3070806@cantrip.org> <533EA665.9070501@gmail.com> <533EC70A.3040803@meshcapital.com> <533ED1D0.1000600@gmail.com> <533EF0E6.9050905@meshcapital.com> <533EFF25.7020401@gmail.com> <533F1243.4000200@meshcapital.com> <533F1FA1.4000506@gmail.com> Message-ID: <533F372B.50702@meshcapital.com> Most of your comments below do not apply to a properly implemented negative index scheme. So, it seems clear to me, that I haven't been able to get it across to you. I guess we can both agree that spending more time on this thread is unproductive, especially since the real question is whether we would *want* to have ~[T] used. Thank you for your time. Manu On 04/04/2014 05:09 PM, Daniel Micay wrote: > On 04/04/14 04:12 PM, Manu Thambi wrote: >> On 04/04/2014 02:51 PM, Daniel Micay wrote: >>> Storing at a negative index removes the cost at indexing, but not >>> elsewhere. It still consumes more memory and makes `push` slower, >>> especially since it has to do more than more offset based on alignment >>> with at least one overflow check. >> In the "negative index scheme", the length and capacity in the Vec would >> be identical >> to what is it in the current implementation. Hence the code will be >> identical, except >> for while allocating/deallocatiing. (ie, push() would have the same >> performance) > It won't have the same performance, because the performance hit comes > from the code size increase needed to handle offsetting and overflow > checking along with aliasing issues. > > It was slow because a header involves offsets and overflow checks. It > also screws up the alias analysis. The negative index solution suffers > from this almost as much as the old vector representation. > > I feel I've made the reasons why it's slower clear and you simply don't > believe what I said. The performance gains from removing the header from > vectors weren't imaginary. Even a better implementation than the one in > `std::slice` is still slower. > >>> It has to check for overflow on any addition like this. The inability to >>> pass a size to `dealloc` is not going to be free either. Teaching LLVM >>> to understand the pointer gymnastics here means trying to make it >>> simpler rather than allowing it to become more complicated. >> I don't understand what addition you mean? The only time you need the >> size stored in the negative index >> is to call dealloc. >> >> You absolutely can pass size into dealloc while destructing ~[T]. Just >> use the size, stored in the negative index. > You can pass it for the negative index proposal, but not the other > proposals. The negative index proposal involves bloating the `Vec` > type to micro-optimize what is going to be an incredibly rare > conversion, while the other proposals lose the ability to pass the > length. I don't see a valid reason to change the status quo. > >>> I'm not at all concerned about it. I think it would be a huge mistake to >>> use `~[T]` frequently at all, and I'm simply pointing out that this is >>> not going to be a no-op because that claim was made several times. >> I will be a no-op, if you use null (0) to indicate 0-capacity, and >> special value(1?) to indicate >> Option::None. > You can't use a special value to indicate None without adding a lang > item, no other pointer values are specified by Rust or LLVM as being > invalid. > >>> An empty vector is not the same as `None`. Reserving an address is also >>> not possible in all environments Rust is going to be used in as a >>> language, and I think it should be up to the allocator implementation >>> rather than hard-coded knowledge in the compiler. At the moment, the >>> `Some(~())` problem is fixed with no overhead anywhere, and allocators >>> have the choice between a sentinel and clamping zero-size allocations >>> to 1. >> Can you name one architecture, where we are not able to find a single >> extra invalid virtual address >> other than 0? > Whether or not *I* can name such an architecture doesn't matter. > > Rust is meant to be a portable language, even to platforms this specific > contributor is not familiar with. > > This would add a dependency on global variables for unique pointers, > even though you could implement them on in an environment with only a > stack using a fixed-size pool. > >> Just to clear, the "negative index scheme", will allow free() to take >> the size argument. > I'm talking about all of the proposed solutions such as the ones at the > end of your message in isolation from the proposal to require `Vec` > to have a header (not going to happen). > >>>> b) If that makes implementation of Option complicated, then use the >>>> special pointer value to represent >>>> a zero capacity. We can use that special value in Vec as well, even >>>> though it is not needed. This >>>> will keep Vec -> ~[T] a no-op. >>> This will add a branch to every deallocation call. >> No it wouldn't. Vec, doesn't have to check the pointer. Just check the >> capacity. > Checking the capacity is a branch. > >> The only overhead would be a couple of checks/additions during >> allocation/deallocation. Everything >> else would perform exactly as it does now. > It will cause `push` to perform worse than it does now and it will cause > `Vec` to allocate more memory. All to micro-optimize a conversion to > a nearly useless type. I've made it clear why adding headers to vectors > decreases the performance. > > You clearly don't believe me and I won't be wasting my time on this > thread anymore. > -- Manu Thambi Mesh Capital, LLC 201-918-4202 -------------- next part -------------- An HTML attachment was scrubbed... URL: From fiedzia at gmail.com Fri Apr 4 21:05:01 2014 From: fiedzia at gmail.com (Maciej Dziardziel) Date: Sat, 5 Apr 2014 05:05:01 +0100 Subject: [rust-dev] conditional compilation and macros Message-ID: I am trying to define macro that would only expand to anything if certain cfg option is defined, otherwise it should be no-op, but I cannot find a way to do it. Pretty much I want some form of #ifdef. The closest thing I can find is to enclose generated code in a function, and just do this: #cfg(foo)] def foo(){ //do something } #[cfg(not(foo))] def foo()){} Is there a better way to do that? -- Maciej Dziardziel fiedzia at gmail.com From remifontan at yahoo.fr Sat Apr 5 01:30:16 2014 From: remifontan at yahoo.fr (=?UTF-8?B?UsOpbWkgRm9udGFu?=) Date: Sat, 5 Apr 2014 21:30:16 +1300 Subject: [rust-dev] TotalOrd and cmp::max Message-ID: Hi, when compiling following code with rust 0.10 I get following error: use std::cmp; struct vec2d { a:f32, b:f32 } impl vec2d { pub fn max(&self) -> f32 { cmp::max(self.a, self.b) } } test.rs:6:9: 6:17 error: failed to find an implementation of trait std::cmp::TotalOrd for f32 test.rs:6 cmp::max(self.a, self.b) ^~~~~~~~ make: *** [test-test] Error 101 have I missed something? cheers, R?mi -- R?mi Fontan : remifontan at yahoo.fr mobile: +64 21 855 351 93 Otaki Street, Miramar 6022 Wellington, New Zealand -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Sat Apr 5 01:34:16 2014 From: dbau.pp at gmail.com (Huon Wilson) Date: Sat, 05 Apr 2014 19:34:16 +1100 Subject: [rust-dev] TotalOrd and cmp::max In-Reply-To: References: Message-ID: <533FC008.5040805@gmail.com> Floating point numbers don't have a total ordering (all of these are false: NaN < NaN, NaN == NaN, NaN > NaN). Use the floating-point specific method, `self.a.max(self.b)`. Huon On 05/04/14 19:30, R?mi Fontan wrote: > Hi, > > when compiling following code with rust 0.10 I get following error: > > use std::cmp; > struct vec2d { a:f32, b:f32 } > impl vec2d { > pub fn max(&self) -> f32 { > cmp::max(self.a, self.b) > } > } > > test.rs:6:9: 6:17 error: failed to find an implementation of trait > std::cmp::TotalOrd for f32 > test.rs:6 cmp::max(self.a, self.b) > ^~~~~~~~ > make: *** [test-test] Error 101 > > > have I missed something? > > > cheers, > > R?mi > > > -- > R?mi Fontan : remifontan at yahoo.fr > mobile: +64 21 855 351 > 93 Otaki Street, Miramar 6022 > Wellington, New Zealand > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From remifontan at yahoo.fr Sat Apr 5 02:10:41 2014 From: remifontan at yahoo.fr (=?UTF-8?B?UsOpbWkgRm9udGFu?=) Date: Sat, 5 Apr 2014 22:10:41 +1300 Subject: [rust-dev] TotalOrd and cmp::max In-Reply-To: <533FC008.5040805@gmail.com> References: <533FC008.5040805@gmail.com> Message-ID: ok, got it. thanks R?mi On Sat, Apr 5, 2014 at 9:34 PM, Huon Wilson wrote: > Floating point numbers don't have a total ordering (all of these are > false: NaN < NaN, NaN == NaN, NaN > NaN). > > Use the floating-point specific method, `self.a.max(self.b)`. > > > Huon > > > On 05/04/14 19:30, R?mi Fontan wrote: > > Hi, > > when compiling following code with rust 0.10 I get following error: > > use std::cmp; > struct vec2d { a:f32, b:f32 } > impl vec2d { > pub fn max(&self) -> f32 { > cmp::max(self.a, self.b) > } > } > > test.rs:6:9: 6:17 error: failed to find an implementation of trait > std::cmp::TotalOrd for f32 > test.rs:6 cmp::max(self.a, self.b) > ^~~~~~~~ > make: *** [test-test] Error 101 > > > have I missed something? > > > cheers, > > R?mi > > -- > R?mi Fontan : remifontan at yahoo.fr > mobile: +64 21 855 351 > 93 Otaki Street, Miramar 6022 > Wellington, New Zealand > > > _______________________________________________ > Rust-dev mailing listRust-dev at mozilla.orghttps://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- R?mi Fontan : remifontan at yahoo.fr mobile: +64 21 855 351 93 Otaki Street, Miramar 6022 Wellington, New Zealand -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Sat Apr 5 03:39:30 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Sat, 5 Apr 2014 11:39:30 +0100 Subject: [rust-dev] Building a static array of pointers In-Reply-To: References: Message-ID: The problem is that &[extern unsafe fn()] results in 8 bytes, pointer to the actual array and its size. Is there any way I can get a plain C-style array in rust? On Fri, Apr 4, 2014 at 9:06 PM, Alex Crichton wrote: > As you've discovered in bug #13325, dealing with external constants in > static expressions is sometimes a little tricky. I would avoid casting > for now (as happens in the bug) in favor of stronger types. For > example, this compiles and runs for me: > > extern { > fn foo(); > fn bar(); > } > > static table: &'static [extern unsafe fn()] = &[foo, bar]; > > pub mod test { > #[no_mangle] pub extern fn foo() { println!("foo"); } > #[no_mangle] pub extern fn bar() { println!("bar"); } > } > > fn main() { > for f in table.iter() { > unsafe { (*f)(); } > } > } > > Note that in rust, a value of type `extern fn()` cannot be null, but > `Option` can indeed be null. You'll probably want > something along the lines of: > > #[link_section = ".isr_vector"] > pub static ISR_VECTOR_TABLE: [Option, ..N] = > [Some(...), None, Some(...), ...]; > > On Fri, Apr 4, 2014 at 12:53 PM, Vladimir Pouzanov > wrote: > > Is it possible to port the following C code to rust? > > > > __attribute__ ((section(".isr_vector"))) > > void (* const isr_vector_table[])(void) = { > > &_stack_base, > > main, // Reset > > isr_nmi, // NMI > > isr_hardfault, // Hard Fault > > 0, // CM3 Memory Management Fault > > 0, // CM3 Bus Fault > > 0, // CM3 Usage Fault > > &_boot_checksum, // NXP Checksum code > > 0, // Reserved > > 0, // Reserved > > 0, // Reserved > > isr_svcall, // SVCall > > 0, // Reserved for debug > > 0, // Reserved > > isr_pendsv, // PendSV > > isr_systick, // SysTick > > }; > > > > here main and isr_* are rust external functions, and _stack_base is > defined > > as > > > > extern void _stack_base() > > > > and gets loaded from linker script. > > > > Also, is it possible to make a weak symbol in rust or somehow emulate it? > > Weak symbols are used in C code to provide the following functionality: > > isr_* functions are stubs with default implementation (morse out id code > > with led, loop forever), but if any of those requires actual code, than > it > > is overrides the weak "morse-blinking" function symbol. > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.sapin at exyr.org Sat Apr 5 03:53:01 2014 From: simon.sapin at exyr.org (Simon Sapin) Date: Sat, 05 Apr 2014 11:53:01 +0100 Subject: [rust-dev] Building a static array of pointers In-Reply-To: References: Message-ID: <533FE08D.7010301@exyr.org> On 05/04/2014 11:39, Vladimir Pouzanov wrote: > The problem is that &[extern unsafe fn()] results in 8 bytes, pointer to > the actual array and its size. Is there any way I can get a plain > C-style array in rust? If the size is known as compile-time you can use: static table: [extern unsafe fn(), ..2] = [foo, bar]; -- Simon Sapin From corey at octayn.net Sat Apr 5 04:00:57 2014 From: corey at octayn.net (Corey Richardson) Date: Sat, 5 Apr 2014 07:00:57 -0400 Subject: [rust-dev] Building a static array of pointers In-Reply-To: <533FE08D.7010301@exyr.org> References: <533FE08D.7010301@exyr.org> Message-ID: A C-style array is written `*T`, much like in C (note: I'm not saying `T*` and `T[]` are the same type, I know they aren't) On Sat, Apr 5, 2014 at 6:53 AM, Simon Sapin wrote: > On 05/04/2014 11:39, Vladimir Pouzanov wrote: >> >> The problem is that &[extern unsafe fn()] results in 8 bytes, pointer to >> the actual array and its size. Is there any way I can get a plain >> C-style array in rust? > > > If the size is known as compile-time you can use: > > static table: [extern unsafe fn(), ..2] = [foo, bar]; > > -- > Simon Sapin > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ From farcaller at gmail.com Sat Apr 5 05:28:15 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Sat, 5 Apr 2014 13:28:15 +0100 Subject: [rust-dev] Building a static array of pointers In-Reply-To: References: <533FE08D.7010301@exyr.org> Message-ID: Ended up specifying array size as per Simon's suggestion: #[link_section=".isr_vector_temp"] #[no_mangle] pub static ISRVectors: [extern unsafe fn(), ..4] = [ _stack_base, main, isr_nmi, isr_hardfault, ]; Given that table size is an architecture-dependent time constant, it also adds a tiny bit of verification that all ISRs are defined. Also tried defining something along the lines of *[extern unsafe fn()], but I guess size is also required in this case. Thanks all! On Sat, Apr 5, 2014 at 12:00 PM, Corey Richardson wrote: > A C-style array is written `*T`, much like in C (note: I'm not saying > `T*` and `T[]` are the same type, I know they aren't) > > On Sat, Apr 5, 2014 at 6:53 AM, Simon Sapin wrote: > > On 05/04/2014 11:39, Vladimir Pouzanov wrote: > >> > >> The problem is that &[extern unsafe fn()] results in 8 bytes, pointer to > >> the actual array and its size. Is there any way I can get a plain > >> C-style array in rust? > > > > > > If the size is known as compile-time you can use: > > > > static table: [extern unsafe fn(), ..2] = [foo, bar]; > > > > -- > > Simon Sapin > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > > -- > http://octayn.net/ > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.sapin at exyr.org Sat Apr 5 06:07:22 2014 From: simon.sapin at exyr.org (Simon Sapin) Date: Sat, 05 Apr 2014 14:07:22 +0100 Subject: [rust-dev] Building a static array of pointers In-Reply-To: References: <533FE08D.7010301@exyr.org> Message-ID: <5340000A.2060508@exyr.org> On 05/04/2014 12:00, Corey Richardson wrote: > A C-style array is written `*T`, much like in C (note: I'm not saying > `T*` and `T[]` are the same type, I know they aren't) *T in Rust is not an array, it is a raw pointer. It may happen to point to the start of an array that you could unsafely access with .offset() and ptr::read(), but you can not index it like an array. -- Simon Sapin From simon.sapin at exyr.org Sat Apr 5 06:09:38 2014 From: simon.sapin at exyr.org (Simon Sapin) Date: Sat, 05 Apr 2014 14:09:38 +0100 Subject: [rust-dev] Building a static array of pointers In-Reply-To: References: <533FE08D.7010301@exyr.org> Message-ID: <53400092.3000505@exyr.org> On 05/04/2014 13:28, Vladimir Pouzanov wrote: > Also tried defining something along the lines of *[extern unsafe fn()], > but I guess size is also required in this case. This will probably work once we have DST, but it will result in a fixed-size pointer to an array, rather than the actual array like [extern unsafe fn(), ..4] whose size is proportional to the number of elements. DST: https://github.com/mozilla/rust/issues/6308 -- Simon Sapin From corey at octayn.net Sat Apr 5 06:14:28 2014 From: corey at octayn.net (Corey Richardson) Date: Sat, 5 Apr 2014 09:14:28 -0400 Subject: [rust-dev] Building a static array of pointers In-Reply-To: <5340000A.2060508@exyr.org> References: <533FE08D.7010301@exyr.org> <5340000A.2060508@exyr.org> Message-ID: Sure, same thing as a C-style array, minus the fact that we don't have Index implemented for unsafe ptrs. On Sat, Apr 5, 2014 at 9:07 AM, Simon Sapin wrote: > On 05/04/2014 12:00, Corey Richardson wrote: >> >> A C-style array is written `*T`, much like in C (note: I'm not saying >> `T*` and `T[]` are the same type, I know they aren't) > > > *T in Rust is not an array, it is a raw pointer. It may happen to point to > the start of an array that you could unsafely access with .offset() and > ptr::read(), but you can not index it like an array. > > -- > Simon Sapin -- http://octayn.net/ From simon.sapin at exyr.org Sat Apr 5 06:23:14 2014 From: simon.sapin at exyr.org (Simon Sapin) Date: Sat, 05 Apr 2014 14:23:14 +0100 Subject: [rust-dev] Building a static array of pointers In-Reply-To: References: <533FE08D.7010301@exyr.org> <5340000A.2060508@exyr.org> Message-ID: <534003C2.2070500@exyr.org> On 05/04/2014 14:14, Corey Richardson wrote: > Sure, same thing as a C-style array, minus the fact that we don't have > Index implemented for unsafe ptrs. Sure, but that difference is the important part. It?s idiomatic C to pretend that a pointer is like an array, but not in Rust. -- Simon Sapin From danielmicay at gmail.com Sat Apr 5 07:24:46 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Sat, 05 Apr 2014 10:24:46 -0400 Subject: [rust-dev] Building a static array of pointers In-Reply-To: <534003C2.2070500@exyr.org> References: <533FE08D.7010301@exyr.org> <5340000A.2060508@exyr.org> <534003C2.2070500@exyr.org> Message-ID: <5340122E.4070508@gmail.com> On 05/04/14 09:23 AM, Simon Sapin wrote: > On 05/04/2014 14:14, Corey Richardson wrote: >> Sure, same thing as a C-style array, minus the fact that we don't have >> Index implemented for unsafe ptrs. > > Sure, but that difference is the important part. It?s idiomatic C to > pretend that a pointer is like an array, but not in Rust. I wouldn't say it's not idiomatic in Rust, it's simply a missing feature for raw pointers along with pointer arithmetic operators. There were previously operator overloads, but I had to remove them when switching to inbounds pointer arithmetic since it no longer satisfies the safety requirement of the traits. It can and should be added back to the compiler, just without trait implementations. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From me at nongraphical.com Sat Apr 5 12:57:14 2014 From: me at nongraphical.com (Frank Huang) Date: Sat, 5 Apr 2014 12:57:14 -0700 Subject: [rust-dev] Is it possible to implement "extension methods" on existing traits? Message-ID: Hello everyone, I have a question about making "extension methods" on something like io::Writer. Basically, I have a data format that requires strings to be serialized as an 8-byte length header and then the string bytes themselves. Instead of having to type writer.write_u64(...); writer.write_str(...); over and over again, I would like to implement some "extension methods" or something like that on io::Writer, like the following pseudocode: trait MySerialization { fn write_my_string(&mut self, s: &str) -> io::IoResult<()>; } impl MySerialization for io::Writer { fn write_my_string(&mut self, s: &str) -> io::IoResult<()> { try!(self.write_u64(s.len()); self.write_str(s); } } However, this of course doesn't work, because I can't implement a trait for a trait. Rustc says: "reference to trait `io::Writer` where a type is expected; try `@io::Writer`, `~io::Writer`, or `&io::Writer`", however when I try "&io::Writer" as suggested, rustc complains about lifetimes. Is this sort of thing possible in Rust? Thanks for your help! - Frank -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodrigorivascosta at gmail.com Sat Apr 5 12:59:12 2014 From: rodrigorivascosta at gmail.com (Rodrigo Rivas) Date: Sat, 5 Apr 2014 21:59:12 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: <533F18DD.5040803@free.fr> References: <533F18DD.5040803@free.fr> Message-ID: On Fri, Apr 4, 2014 at 10:41 PM, Philippe Delrieu wrote: > Hello, > > I've some problem to find a solution for something I want to do with a > vector of enum. This is an example of what I want to do: > > trait Base { > fn set_something(&mut self); > } > > struct FirstThink; > > impl Base for FirstThink { > fn set_something(&mut self) {} > } > > struct SecondThink; > impl Base for SecondThink { > fn set_something(&mut self) {} > } > > enum BaseImpl { > FirstThinkImpl(~FirstThink), > SecondThinkImpl(~SecondThink), > } > > fn some_process(list: &mut Vec<&mut ~Base>) { > for think in list.mut_iter() { > think.set_something(); > } > } > > struct Container { > nodeList: Vec<~BaseImpl>, > } > > impl Container { > fn add_FirstThink(&mut self, think: ~FirstThink) { > self.nodeList.push(~FirstThinkImpl(think)); > } > fn add_SecondThink(&mut self, think: ~SecondThink) { > self.nodeList.push(~SecondThinkImpl(think)); > } > > fn do_some_process(&mut self, fct: fn(&mut Vec<&mut ~Base>)) { > I didn't find a simple way to convert the Vec<~BaseImpl> to a &mut > Vec<&mut ~Base> > to do the call > fct(self.nodeList); > > } > } > > I use the enum pattern to have only one collection of object that impl Base > but sometime I have to do specific processing depending if the Base is a > FirstThink or SecondThink (not in the example). I use the match as follow > > match think { > FirstThinkImpl(first) => do specific first, > SecondThinkImpl(second)=> do specific second, > }); > > Perhaps there is a better way to do. Any suggestions would be appreciated. I think that would be better if the `fct` function take an `std::iter::Iterator<&mut ~Base>` instead of a `Vec`. Naturally, you will not be able to modify the vector, only to iterate through it. But if `fct` is allowed to modify the vector your requirements are impossible in the first place! Then you can write a simple adaptor: impl std::iter::Iterator<&mut ~Base> for Container { // left as an exercise to the reader ;-) } -- Rodrigo From sfackler at gmail.com Sat Apr 5 13:17:59 2014 From: sfackler at gmail.com (Steven Fackler) Date: Sat, 5 Apr 2014 13:17:59 -0700 Subject: [rust-dev] Is it possible to implement "extension methods" on existing traits? In-Reply-To: References: Message-ID: You can do it like this: impl MySerialization for T { ... } Steven Fackler On Sat, Apr 5, 2014 at 12:57 PM, Frank Huang wrote: > Hello everyone, > > I have a question about making "extension methods" on something like > io::Writer. Basically, I have a data format that requires strings to be > serialized as an 8-byte length header and then the string bytes themselves. > Instead of having to type writer.write_u64(...); writer.write_str(...); > over and over again, I would like to implement some "extension methods" or > something like that on io::Writer, like the following pseudocode: > > trait MySerialization { > fn write_my_string(&mut self, s: &str) -> io::IoResult<()>; > } > > impl MySerialization for io::Writer { > fn write_my_string(&mut self, s: &str) -> io::IoResult<()> { > try!(self.write_u64(s.len()); > self.write_str(s); > } > } > > However, this of course doesn't work, because I can't implement a trait > for a trait. Rustc says: "reference to trait `io::Writer` where a type is > expected; try `@io::Writer`, `~io::Writer`, or `&io::Writer`", however when > I try "&io::Writer" as suggested, rustc complains about lifetimes. Is this > sort of thing possible in Rust? > > Thanks for your help! > - Frank > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From philippe.delrieu at free.fr Sat Apr 5 13:26:59 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Sat, 05 Apr 2014 22:26:59 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: References: <533F18DD.5040803@free.fr> Message-ID: <53406713.1060906@free.fr> Very good idea. The vector don't have to be modified so it'll work. Thank you for the advice. I make a try an I'll post the result. Philippe Le 05/04/2014 21:59, Rodrigo Rivas a ?crit : > On Fri, Apr 4, 2014 at 10:41 PM, Philippe Delrieu > wrote: >> Hello, >> >> I've some problem to find a solution for something I want to do with a >> vector of enum. This is an example of what I want to do: >> >> trait Base { >> fn set_something(&mut self); >> } >> >> struct FirstThink; >> >> impl Base for FirstThink { >> fn set_something(&mut self) {} >> } >> >> struct SecondThink; >> impl Base for SecondThink { >> fn set_something(&mut self) {} >> } >> >> enum BaseImpl { >> FirstThinkImpl(~FirstThink), >> SecondThinkImpl(~SecondThink), >> } >> >> fn some_process(list: &mut Vec<&mut ~Base>) { >> for think in list.mut_iter() { >> think.set_something(); >> } >> } >> >> struct Container { >> nodeList: Vec<~BaseImpl>, >> } >> >> impl Container { >> fn add_FirstThink(&mut self, think: ~FirstThink) { >> self.nodeList.push(~FirstThinkImpl(think)); >> } >> fn add_SecondThink(&mut self, think: ~SecondThink) { >> self.nodeList.push(~SecondThinkImpl(think)); >> } >> >> fn do_some_process(&mut self, fct: fn(&mut Vec<&mut ~Base>)) { >> I didn't find a simple way to convert the Vec<~BaseImpl> to a &mut >> Vec<&mut ~Base> >> to do the call >> fct(self.nodeList); >> >> } >> } >> >> I use the enum pattern to have only one collection of object that impl Base >> but sometime I have to do specific processing depending if the Base is a >> FirstThink or SecondThink (not in the example). I use the match as follow >> >> match think { >> FirstThinkImpl(first) => do specific first, >> SecondThinkImpl(second)=> do specific second, >> }); >> >> Perhaps there is a better way to do. Any suggestions would be appreciated. > I think that would be better if the `fct` function take an > `std::iter::Iterator<&mut ~Base>` instead of a `Vec`. Naturally, you > will not be able to modify the vector, only to iterate through it. But > if `fct` is allowed to modify the vector your requirements are > impossible in the first place! > > Then you can write a simple adaptor: > > impl std::iter::Iterator<&mut ~Base> for Container { > // left as an exercise to the reader ;-) > } > From me at nongraphical.com Sat Apr 5 13:55:53 2014 From: me at nongraphical.com (Frank Huang) Date: Sat, 5 Apr 2014 13:55:53 -0700 Subject: [rust-dev] Is it possible to implement "extension methods" on existing traits? In-Reply-To: References: Message-ID: Thanks for the quick response, Steven! Having done what you suggested, I'm now getting the following error (for serializing a larger struct in which some fields are strings): impl MySerialization for T { fn write_my_string(&mut self, s: &str) -> IoResult<()> { ... } } impl StructToBeSerialized { fn save_to(&self, writer: &mut io::Writer) -> io::IoResult<()> { try!(writer.write_my_string(self.string_field_1)); // error at this line } } The error is at the indicated line and it says: cannot borrow immutable argument `writer` as mutable. However, the function argument writer to save_to is a &mut io::Writer, which would seem to be mutable to me. Would you happen to know what's going wrong with this code? Thanks again! Frank On Sat, Apr 5, 2014 at 1:17 PM, Steven Fackler wrote: > You can do it like this: > > impl MySerialization for T { > ... > } > > Steven Fackler > > > On Sat, Apr 5, 2014 at 12:57 PM, Frank Huang wrote: > >> Hello everyone, >> >> I have a question about making "extension methods" on something like >> io::Writer. Basically, I have a data format that requires strings to be >> serialized as an 8-byte length header and then the string bytes themselves. >> Instead of having to type writer.write_u64(...); writer.write_str(...); >> over and over again, I would like to implement some "extension methods" or >> something like that on io::Writer, like the following pseudocode: >> >> trait MySerialization { >> fn write_my_string(&mut self, s: &str) -> io::IoResult<()>; >> } >> >> impl MySerialization for io::Writer { >> fn write_my_string(&mut self, s: &str) -> io::IoResult<()> { >> try!(self.write_u64(s.len()); >> self.write_str(s); >> } >> } >> >> However, this of course doesn't work, because I can't implement a trait >> for a trait. Rustc says: "reference to trait `io::Writer` where a type is >> expected; try `@io::Writer`, `~io::Writer`, or `&io::Writer`", however when >> I try "&io::Writer" as suggested, rustc complains about lifetimes. Is this >> sort of thing possible in Rust? >> >> Thanks for your help! >> - Frank >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From smcarthur at mozilla.com Sat Apr 5 14:57:07 2014 From: smcarthur at mozilla.com (Sean McArthur) Date: Sat, 5 Apr 2014 14:57:07 -0700 Subject: [rust-dev] Is it possible to implement "extension methods" on existing traits? In-Reply-To: References: Message-ID: I can't say why the "immutable argument" error is happening, but there's another error in that function. You're using a `Writer`, but Writer doesn't have `write_my_string`, only `MySerialization` does. I'd write that like this: fn save_to(&self, writer: &mut T) -> io::IoResult<()> { writer.write_my_string(self.string_field_1) // don't need try!, since you're returning an IoResult } On Sat, Apr 5, 2014 at 1:55 PM, Frank Huang wrote: > Thanks for the quick response, Steven! Having done what you suggested, I'm > now getting the following error (for serializing a larger struct in which > some fields are strings): > > impl MySerialization for T { > fn write_my_string(&mut self, s: &str) -> IoResult<()> { > ... > } > } > > impl StructToBeSerialized { > fn save_to(&self, writer: &mut io::Writer) -> io::IoResult<()> { > try!(writer.write_my_string(self.string_field_1)); // error at this > line > } > } > > The error is at the indicated line and it says: cannot borrow immutable > argument `writer` as mutable. However, the function argument writer to > save_to is a &mut io::Writer, which would seem to be mutable to me. Would > you happen to know what's going wrong with this code? > > Thanks again! > Frank > > > > > On Sat, Apr 5, 2014 at 1:17 PM, Steven Fackler wrote: > >> You can do it like this: >> >> impl MySerialization for T { >> ... >> } >> >> Steven Fackler >> >> >> On Sat, Apr 5, 2014 at 12:57 PM, Frank Huang wrote: >> >>> Hello everyone, >>> >>> I have a question about making "extension methods" on something like >>> io::Writer. Basically, I have a data format that requires strings to be >>> serialized as an 8-byte length header and then the string bytes themselves. >>> Instead of having to type writer.write_u64(...); writer.write_str(...); >>> over and over again, I would like to implement some "extension methods" or >>> something like that on io::Writer, like the following pseudocode: >>> >>> trait MySerialization { >>> fn write_my_string(&mut self, s: &str) -> io::IoResult<()>; >>> } >>> >>> impl MySerialization for io::Writer { >>> fn write_my_string(&mut self, s: &str) -> io::IoResult<()> { >>> try!(self.write_u64(s.len()); >>> self.write_str(s); >>> } >>> } >>> >>> However, this of course doesn't work, because I can't implement a trait >>> for a trait. Rustc says: "reference to trait `io::Writer` where a type is >>> expected; try `@io::Writer`, `~io::Writer`, or `&io::Writer`", however when >>> I try "&io::Writer" as suggested, rustc complains about lifetimes. Is this >>> sort of thing possible in Rust? >>> >>> Thanks for your help! >>> - Frank >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcwalton at mozilla.com Sat Apr 5 14:58:12 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Sat, 05 Apr 2014 14:58:12 -0700 Subject: [rust-dev] Is it possible to implement "extension methods" on existing traits? In-Reply-To: References: Message-ID: <53407C74.8060302@mozilla.com> Try this: On 4/5/14 1:55 PM, Frank Huang wrote: > impl MySerialization for T { > fn write_my_string(&mut self, s: &str) -> IoResult<()> { > ... > } > } > > impl StructToBeSerialized { > fn save_to(&self, mut writer: &mut io::Writer) -> io::IoResult<()> { > try!(writer.write_my_string(self.string_field_1)); // error at this > line > } > } This error will probably go away with DST. Patrick From remifontan at yahoo.fr Sun Apr 6 01:25:26 2014 From: remifontan at yahoo.fr (=?UTF-8?B?UsOpbWkgRm9udGFu?=) Date: Sun, 6 Apr 2014 20:25:26 +1200 Subject: [rust-dev] impl num::Zero and std::ops::Add error Message-ID: Hi, when compiling following code I get following error: use std::num; struct vec2d { a:f32, b:f32 } impl num::Zero for vec2d { fn zero() -> vec2d { vec2d{a:0.0, b:0.0} } fn is_zero(&self) -> bool { self.a==0.0 && self.b==0.0 } } test.rs:4:1: 12:2 error: failed to find an implementation of trait std::ops::Add for vec2d test.rs:4 impl num::Zero for vec2d { test.rs:5 fn zero() -> vec2d { test.rs:6 vec2d{a:0.0, b:0.0} test.rs:7 } test.rs:8 test.rs:9 fn is_zero(&self) -> bool { Would you know why the Add trait seems to be a requirement for implementing the zero trait. cheers, R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Sun Apr 6 04:28:50 2014 From: rusty.gates at icloud.com (Tommi) Date: Sun, 06 Apr 2014 14:28:50 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: Message-ID: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> The tutorial (17.7) says the following: "We can write a trait declaration that inherits from other traits, called supertraits. Types that implement a trait must also implement its supertraits. Since num::Zero inherits from Add, you must implement it (the supertrait) also. On 2014-06-04, at 11:25, R?mi Fontan wrote: > Hi, > > when compiling following code I get following error: > use std::num; > struct vec2d { a:f32, b:f32 } > impl num::Zero for vec2d { > fn zero() -> vec2d { > vec2d{a:0.0, b:0.0} > } > > fn is_zero(&self) -> bool { > self.a==0.0 && self.b==0.0 > } > } > > > > test.rs:4:1: 12:2 error: failed to find an implementation of trait std::ops::Add for vec2d > test.rs:4 impl num::Zero for vec2d { > test.rs:5 fn zero() -> vec2d { > test.rs:6 vec2d{a:0.0, b:0.0} > test.rs:7 } > test.rs:8 > test.rs:9 fn is_zero(&self) -> bool { > > > Would you know why the Add trait seems to be a requirement for implementing the zero trait. > > cheers, > > R?mi > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Sun Apr 6 04:45:23 2014 From: rusty.gates at icloud.com (Tommi) Date: Sun, 06 Apr 2014 14:45:23 +0300 Subject: [rust-dev] Tagged integral & floating-point types In-Reply-To: References: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> <851A4659-40EC-4AC9-BDC8-609FA768B36D@icloud.com> Message-ID: <5E920AC5-A2FB-45B3-B1B9-B51C986F4301@icloud.com> On 2014-04-04, at 12:30, Vadim Chugunov wrote: > trait Invalid { > fn invalid() -> Self; > } > The compiler could then perform option space optimization for any type implementing 'Invalid'. I just realized that Rust already uses static methods just like the one you suggested for defining values that should be compile-time constants. For example std::num::Zero requires a static method 'zero' which should always return the same value. I do think that a more robust language design would be to force those things to be compile-time constants rather than just specifying in the documentation that they should return one. -------------- next part -------------- An HTML attachment was scrubbed... URL: From philippe.delrieu at free.fr Sun Apr 6 10:50:28 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Sun, 06 Apr 2014 19:50:28 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: References: <533F18DD.5040803@free.fr> Message-ID: <534193E4.5080800@free.fr> I need some more help. The impl Iterator<&mut ~Base> for Container declaration generate the error: error: missing lifetime specifier So I had it but I can't manage to return the next value with the specified life time. The code : impl<'a> Iterator<&'a mut ~Base> for Container { /// Advance the iterator and return the next value. Return `None` when the end is reached. fn next(&mut self) -> Option<&'a mut ~Base> { if self.iter_counter == self.nodeList.len() { None } else { self.iter_counter += 1; Some(&'a mut match **self.nodeList.get(self.iter_counter){ FirstThinkImpl(first) => first as ~Base, SecondThinkImpl(second)=> second as ~Base, }) } } } Generate these errors : test_enum.rs:58:18: 61:14 error: borrowed value does not live long enough test/test_enum.rs:58 Some(&'a mut match **self.nodeList.get(self.iter_counter){ test/test_enum.rs:59 FirstThinkImpl(first) => first as ~Base, test_enum.rs:60 SecondThinkImpl(second)=> second as ~Base, test_enum.rs:61 }) test_enum.rs:53:52: 63:6 note: reference must be valid for the lifetime &'a as defined on the block at 53:51... test_enum.rs:53 fn next(&mut self) -> Option<&'a mut ~Base> { test_enum.rs:54 if self.iter_counter == self.nodeList.len() { test/test_enum.rs:55 None test_enum.rs:56 } else { test_enum.rs:57 self.iter_counter += 1; test_enum.rs:58 Some(&'a mut match **self.nodeList.get(self.iter_counter){ ... test_enum.rs:56:17: 62:10 note: ...but borrowed value is only valid for the expression at 56:16 test_enum.rs:56 } else { test_enum.rs:57 self.iter_counter += 1; test_enum.rs:58 Some(&'a mut match **self.nodeList.get(self.iter_counter){ test_enum.rs:59 FirstThinkImpl(first) => first as ~Base, test_enum.rs:60 SecondThinkImpl(second)=> second as ~Base, test/test_enum.rs:61 }) ... test_enum.rs:59:17: 59:38 error: cannot move out of dereference of `&`-pointer test_enum.rs:59 FirstThinkImpl(first) => first as ~Base, ^~~~~~~~~~~~~~~~~~~~~ test_enum.rs:60:17: 60:40 error: cannot move out of dereference of `&`-pointer test_enum.rs:60 SecondThinkImpl(second)=> second as ~Base, Le 05/04/2014 21:59, Rodrigo Rivas a ?crit : > On Fri, Apr 4, 2014 at 10:41 PM, Philippe Delrieu > wrote: >> Hello, >> >> I've some problem to find a solution for something I want to do with a >> vector of enum. This is an example of what I want to do: >> >> trait Base { >> fn set_something(&mut self); >> } >> >> struct FirstThink; >> >> impl Base for FirstThink { >> fn set_something(&mut self) {} >> } >> >> struct SecondThink; >> impl Base for SecondThink { >> fn set_something(&mut self) {} >> } >> >> enum BaseImpl { >> FirstThinkImpl(~FirstThink), >> SecondThinkImpl(~SecondThink), >> } >> >> fn some_process(list: &mut Vec<&mut ~Base>) { >> for think in list.mut_iter() { >> think.set_something(); >> } >> } >> >> struct Container { >> nodeList: Vec<~BaseImpl>, >> } >> >> impl Container { >> fn add_FirstThink(&mut self, think: ~FirstThink) { >> self.nodeList.push(~FirstThinkImpl(think)); >> } >> fn add_SecondThink(&mut self, think: ~SecondThink) { >> self.nodeList.push(~SecondThinkImpl(think)); >> } >> >> fn do_some_process(&mut self, fct: fn(&mut Vec<&mut ~Base>)) { >> I didn't find a simple way to convert the Vec<~BaseImpl> to a &mut >> Vec<&mut ~Base> >> to do the call >> fct(self.nodeList); >> >> } >> } >> >> I use the enum pattern to have only one collection of object that impl Base >> but sometime I have to do specific processing depending if the Base is a >> FirstThink or SecondThink (not in the example). I use the match as follow >> >> match think { >> FirstThinkImpl(first) => do specific first, >> SecondThinkImpl(second)=> do specific second, >> }); >> >> Perhaps there is a better way to do. Any suggestions would be appreciated. > I think that would be better if the `fct` function take an > `std::iter::Iterator<&mut ~Base>` instead of a `Vec`. Naturally, you > will not be able to modify the vector, only to iterate through it. But > if `fct` is allowed to modify the vector your requirements are > impossible in the first place! > > Then you can write a simple adaptor: > > impl std::iter::Iterator<&mut ~Base> for Container { > // left as an exercise to the reader ;-) > } > From rusty.gates at icloud.com Mon Apr 7 01:02:48 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Mon, 07 Apr 2014 11:02:48 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> Message-ID: <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> > On 07 Apr 2014, at 08:44, Nicholas Radford wrote: > > I think the original question was, why does the zero trait require the add trait. > If that was the original question, then my answer would be that std::num::Zero requires the Add trait because of the way it is specified: "Defines an additive identity element for Self". Then the question becomes: "why is Zero specified like that?", and I would answer: because then you can use it in generic algorithms which require their argument(s) to have an additional identity. > And it's a valid question. What does saying a value can have a zero value have to do with adding numbers. > > In other words, it is possible for something to have a zero value without requiring addition, so why does the Zero trait not reflect this. > >> On 6 Apr 2014 12:29, "Tommi" wrote: >> The tutorial (17.7) says the following: >> "We can write a trait declaration that inherits from other traits, called supertraits. Types that implement a trait must also implement its supertraits. >> >> Since num::Zero inherits from Add, you must implement it (the supertrait) also. >> >>> On 2014-06-04, at 11:25, R?mi Fontan wrote: >>> >>> Hi, >>> >>> when compiling following code I get following error: >>> use std::num; >>> struct vec2d { a:f32, b:f32 } >>> impl num::Zero for vec2d { >>> fn zero() -> vec2d { >>> vec2d{a:0.0, b:0.0} >>> } >>> >>> fn is_zero(&self) -> bool { >>> self.a==0.0 && self.b==0.0 >>> } >>> } >>> >>> >>> >>> test.rs:4:1: 12:2 error: failed to find an implementation of trait std::ops::Add for vec2d >>> test.rs:4 impl num::Zero for vec2d { >>> test.rs:5 fn zero() -> vec2d { >>> test.rs:6 vec2d{a:0.0, b:0.0} >>> test.rs:7 } >>> test.rs:8 >>> test.rs:9 fn is_zero(&self) -> bool { >>> >>> >>> Would you know why the Add trait seems to be a requirement for implementing the zero trait. >>> >>> cheers, >>> >>> R?mi >>> >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodrigorivascosta at gmail.com Mon Apr 7 01:27:26 2014 From: rodrigorivascosta at gmail.com (Rodrigo Rivas) Date: Mon, 7 Apr 2014 10:27:26 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: <534193E4.5080800@free.fr> References: <533F18DD.5040803@free.fr> <534193E4.5080800@free.fr> Message-ID: On Sun, Apr 6, 2014 at 7:50 PM, Philippe Delrieu wrote: > I need some more help. > > The impl Iterator<&mut ~Base> for Container declaration generate the error: > error: missing lifetime specifier > So I had it but I can't manage to return the next value with the specified > life time. > The code : > impl<'a> Iterator<&'a mut ~Base> for Container { > /// Advance the iterator and return the next value. Return `None` when > the end is reached. > fn next(&mut self) -> Option<&'a mut ~Base> { > if self.iter_counter == self.nodeList.len() { > None > } else { > self.iter_counter += 1; > Some(&'a mut match **self.nodeList.get(self.iter_counter){ > FirstThinkImpl(first) => first as ~Base, > SecondThinkImpl(second)=> second as ~Base, > }) > } > } > } > > Generate these errors : > test_enum.rs:58:18: 61:14 error: borrowed value does not live long enough > test/test_enum.rs:58 Some(&'a mut match Oh, I think I may have misleaded you... You cannot implement the iterator directly in Container, because the iterator must handle the current position, while the Container just holds the values. You need a intermediate struct that implements the Iterator traits. That's what the `iter()` and ' move_iter()` functions do for vectors and other standard containers. So you'll need something along the lines of this (disclaimer: totally untested!!): struct Container { //.... fn iter(&'a self) -> BaseItems<'a> { let iter = nodeList.iter(); BaseItems{ iter : iter } } } struct BaseItems<'a> { iter : Items<'a, ~Base> } impl<'a> Iterator<&'a mut ~Base> for BaseItems<'a> { //.... } BTW, why all the double pointer in all the "&mut ~Base" instead of just "&mut Base"? -- Rodrigo From philippe.delrieu at free.fr Mon Apr 7 02:27:14 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Mon, 07 Apr 2014 11:27:14 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: References: <533F18DD.5040803@free.fr> <534193E4.5080800@free.fr> Message-ID: <53426F72.8050302@free.fr> Thanks for your help. I'll test ASAP. I use the counter mutable var to have a simple implantation of the iterator to make the code works. Thank for you're example to show a better way. I was thinking of a similar way but I would like to avoid the specific struct with perhaps use a recursive call. I'll think about it later. Le 07/04/2014 10:27, Rodrigo Rivas a ?crit : > BTW, why all the double pointer in all the "&mut ~Base" instead of > just "&mut Base"? For your question, I have &mut ~Base because i didn't find a way to convert the &mut ~Base to &mut Base (or &~Base to &Base) without copy. I have the error error: mismatched types: expected `std::option::Option<&'a mut ~Base>` but found `std::option::Option<&mut &~Base>` I try & (error above), &* error type `~Base` cannot be dereferenced. So I stop searching and try to make it works with ~Base. The callback function is modifying the Vec instance. It's a method that update all the of the Vec element after an event occurs. I have to keep the reference to the Vec instance during the call. Perhaps there's a conception problem that I'll look later to remove most of the mut call but I try this type of call to learn who Rust works. Perhaps you can help me for this part. Philippe From philippe.delrieu at free.fr Mon Apr 7 04:17:43 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Mon, 07 Apr 2014 13:17:43 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: References: <533F18DD.5040803@free.fr> <534193E4.5080800@free.fr> Message-ID: <53428957.2080500@free.fr> I try to implement the iterator like that: struct BaseItems<'a> { iter : Items<'a, ~BaseImpl> } impl<'a> Iterator<&'a ~Base> for BaseItems<'a> { fn next(&mut self) -> Option<&'a ~Base> { match self.iter.next() { Some(ref baseimpl) => { Some(&'a match ***baseimpl{ FirstThinkImpl(ref first) => *first as ~Base, SecondThinkImpl(ref second)=> *second as ~Base, }) }, None => None, } } } But I have a lifetime problem. The error is : borrowed value does not live long enough and reference must be valid for the lifetime &'a as defined on the block and : cannot move out of dereference of `&`-pointer SecondThinkImpl(ref second)=> *second as ~Base, Another possibility: fn next(&mut self) -> Option<&'a ~Base> { match self.iter.next() { Some(ref baseimpl) => { Some(match ***baseimpl{ FirstThinkImpl(ref first) => first as &'a ~Base, SecondThinkImpl(ref second)=> second as &'a ~Base, }) }, None => None, } } generate the error: non-scalar cast: `&~FirstThink` as `&'a ~Base` I try different possibility but I didn't find how to return a <'a> lifetime ~Base or Base I remove the mut to simplify the test of the different lifetime possibilities. Philippe Le 07/04/2014 10:27, Rodrigo Rivas a ?crit : > On Sun, Apr 6, 2014 at 7:50 PM, Philippe Delrieu > wrote: >> I need some more help. >> >> The impl Iterator<&mut ~Base> for Container declaration generate the error: >> error: missing lifetime specifier >> So I had it but I can't manage to return the next value with the specified >> life time. >> The code : >> impl<'a> Iterator<&'a mut ~Base> for Container { >> /// Advance the iterator and return the next value. Return `None` when >> the end is reached. >> fn next(&mut self) -> Option<&'a mut ~Base> { >> if self.iter_counter == self.nodeList.len() { >> None >> } else { >> self.iter_counter += 1; >> Some(&'a mut match **self.nodeList.get(self.iter_counter){ >> FirstThinkImpl(first) => first as ~Base, >> SecondThinkImpl(second)=> second as ~Base, >> }) >> } >> } >> } >> >> Generate these errors : >> test_enum.rs:58:18: 61:14 error: borrowed value does not live long enough >> test/test_enum.rs:58 Some(&'a mut match > Oh, I think I may have misleaded you... You cannot implement the > iterator directly in Container, because the iterator must handle the > current position, while the Container just holds the values. You need > a intermediate struct that implements the Iterator traits. That's what > the `iter()` and ' move_iter()` functions do for vectors and other > standard containers. So you'll need something along the lines of this > (disclaimer: totally untested!!): > > struct Container { > //.... > fn iter(&'a self) -> BaseItems<'a> { > let iter = nodeList.iter(); > BaseItems{ iter : iter } > } > } > > struct BaseItems<'a> { > iter : Items<'a, ~Base> > } > > impl<'a> Iterator<&'a mut ~Base> for BaseItems<'a> { > //.... > } > > BTW, why all the double pointer in all the "&mut ~Base" instead of > just "&mut Base"? > From rusty.gates at icloud.com Tue Apr 8 03:48:17 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Tue, 08 Apr 2014 13:48:17 +0300 Subject: [rust-dev] Tagged integral & floating-point types In-Reply-To: <7FB88CE6-14B7-45B6-9C99-87FC5574A26C@yahoo.com.au> References: <8FDA69CC-D891-4871-BB1E-9A268EEE5BF3@icloud.com> <851A4659-40EC-4AC9-BDC8-609FA768B36D@icloud.com> <5E920AC5-A2FB-45B3-B1B9-B51C986F4301@icloud.com> <7FB88CE6-14B7-45B6-9C99-87FC5574A26C@yahoo.com.au> Message-ID: <0C50882B-49EB-4C04-A48A-CEE8FEDE7F8D@icloud.com> I just realized that this 'Invalid' trait is also a prime example of why traits must be able to specify their items as private. Obviously that 'invalid' static method / constant should not be part of the public interface. Heck, the sole reason for the existence of the type could be that it protects itself from becoming invalid. And I'd also argue that private should be the default for the items specified by traits so that there's no need for 'priv' keyword. From peter at taricorp.net Tue Apr 8 08:53:37 2014 From: peter at taricorp.net (Peter Marheine) Date: Tue, 8 Apr 2014 10:53:37 -0500 Subject: [rust-dev] matching on a few bits in int In-Reply-To: References: Message-ID: I had a go at building a macro to do this sort of thing, and it turned out to be easier than I expected. https://gist.github.com/tari/10144385 Use like this: let x = match_bitfield!(do_something(), bits 4 to 8 { 0 => DivideBy1, 1 => DivideBy2, 2 => DivideBy4, _ => UnknownDivisor }; On Fri, Apr 4, 2014 at 7:11 AM, Vladimir Pouzanov wrote: > I've submitted an RFC for this one: > https://github.com/rust-lang/rfcs/pull/29 > > > On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers wrote: >> >> I think the best solution is to add uN and sN types where N is not a power >> of two, which LLVM should already support. >> >> Then you can write your match like this: >> match (val >> 6) as u2 >> { >> ... >> } >> >> And it will work as desired. >> >> Biggest issue is that to make it work nicely you'd need to add some way to >> generalize over the bit-length and integers, and that's going to require >> generics with int parameters and work to add those. >> > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Peter Marheine Don't Panic From farcaller at gmail.com Tue Apr 8 09:09:01 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Tue, 8 Apr 2014 17:09:01 +0100 Subject: [rust-dev] matching on a few bits in int In-Reply-To: References: Message-ID: Awesome use of unreachable! On Tue, Apr 8, 2014 at 4:53 PM, Peter Marheine wrote: > I had a go at building a macro to do this sort of thing, and it turned > out to be easier than I expected. > > https://gist.github.com/tari/10144385 > > Use like this: > let x = match_bitfield!(do_something(), bits 4 to 8 { > 0 => DivideBy1, > 1 => DivideBy2, > 2 => DivideBy4, > _ => UnknownDivisor > }; > > On Fri, Apr 4, 2014 at 7:11 AM, Vladimir Pouzanov > wrote: > > I've submitted an RFC for this one: > > https://github.com/rust-lang/rfcs/pull/29 > > > > > > On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers > wrote: > >> > >> I think the best solution is to add uN and sN types where N is not a > power > >> of two, which LLVM should already support. > >> > >> Then you can write your match like this: > >> match (val >> 6) as u2 > >> { > >> ... > >> } > >> > >> And it will work as desired. > >> > >> Biggest issue is that to make it work nicely you'd need to add some way > to > >> generalize over the bit-length and integers, and that's going to require > >> generics with int parameters and work to add those. > >> > > > > > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > > > > -- > Peter Marheine > Don't Panic > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Tue Apr 8 10:20:09 2014 From: kevin at sb.org (Kevin Ballard) Date: Tue, 8 Apr 2014 10:20:09 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> Message-ID: <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > On 07 Apr 2014, at 08:44, Nicholas Radford wrote: > >> I think the original question was, why does the zero trait require the add trait. >> > If that was the original question, then my answer would be that std::num::Zero requires the Add trait because of the way it is specified: "Defines an additive identity element for Self". Then the question becomes: "why is Zero specified like that?", and I would answer: because then you can use it in generic algorithms which require their argument(s) to have an additional identity. If you want a zero value for a type that doesn't support addition, std::default::Default may be a good choice to use. Semantically, that actually returns the "default value" for a type instead of the "zero value", but in a type without addition, how do you define "zero value"? -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Tue Apr 8 10:23:24 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Tue, 8 Apr 2014 18:23:24 +0100 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: References: <53397650.9000406@gmail.com> <533C036C.5070400@gmail.com> Message-ID: I might have found an unsupported case. Consider the following: trait SPI { ... } struct McuSPI; impl SPI for McuSPI { ... } struct LCD { spi: &SPI, ... } This code results in a dynamic dispatch to SPI, as "trait bounds are not allowed in structure definitions". Is it in any way possible to use static dispatch from LCD to SPI given the exact implementations are known at compile time? On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: > And just in case there is a confusion (as I have noticed others to > have), it might help to see a specific example comparing static > dispatch with dynamic. > > // This is a single function for all types implementing the LCD Trait. > fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of > the object being passed in > x.line(....); // dynamic dispatch > } > > // Like C++ templates, this generates a function for each type T that > implements LCD. > fn foo(x : &T) { // x's type is &T rather than &LCD > x.line(....); // static dispatch based on type T known at compile-time > } > > On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay > wrote: > > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: > >> If I get it right, calls to traits are resolved in runtime (so, traits > >> are kind of similar to C++ virtual methods). > > > > All method calls on regular types are resolved via static dispatch, > > whether or not they come from a trait. For example, consider a generic > > function like the following: > > > > fn min(a: T, b: T) -> T { > > if a < b { a } else { b } > > } > > > > This function performs a *static* call of the `lt` method defined on the > > `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded > > at compile-time just as C++ templates are. > > > > Rust also allows using traits as boxed objects, but this is an entirely > > transparent choice. They're almost always used for static dispatch via > > trait bounds on generics, or simply outside of generics. > > > >> What I'm proposing here is a compile-time approach. > >> > >> Let's say we have the following trait: > >> > >> pub trait LCD { > >> fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8); > >> fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); > >> fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, > >> color: u8); > >> fn putc(&mut self, value: char); > >> fn puts(&mut self, s: &str); > >> > >> fn flush(&self); > >> fn clear(&mut self); > >> } > >> > >> which defined a LED screen. There are two structs implementing it: > >> C12832 and ILI9341 (two different lcd controllers). > >> > >> So I want my app to print hello world on lcd, I write the following > code: > >> > >> let mut lcd = lcd_c12832::C12832::new(spi); > >> let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; > >> l.puts("hello, world"); > >> > >> Which results in a runtime dispatch, a slower and bigger code than the > >> one I'd have without a trait. > > > > You can call methods defined on a trait without boxing the object as a > > trait object. The ability to perform dynamic dispatch via a trait object > > is totally optional. The methods can also be called directly, including > > inside a generic function by specifying the trait as a type parameter > > bound. You can simply call the `puts` method directly on the `lcd` > > object without a cast. > > > >> A second problem is there is no easy way to write unified code that > >> supports both the lcds based on passed in --cfg, as I can't > >> apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of > >> problematic to return a &LCD out from it given that there is no heap and > >> no analog of placement new from C++. > > > > Rust supports generic functions, and you can write code supporting both > > types by making it generic. The choice between static dispatch and > > dynamic dispatch is entirely up to you in the current system. > > > >> Proposed binding concept solves those two problems: > >> > >> #[cfg(lcd_c12832)] > >> let Binding: binding { > >> let lcd: &lcd_c12832::C12832; > >> let main: &Main; > >> > >> bind main.lcd = lcd; > >> } > >> > >> at this point of time compiler can be sure about what struct is > >> implementing LCD trait for main.lcd and can bind the function bodies as > >> compile time, inlining them if applicable. > >> > >> This also might be something that is already implemented, please advice. > >> The goal here is to minimise runtime code being executed and its size. > > > > > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Tue Apr 8 10:26:04 2014 From: corey at octayn.net (Corey Richardson) Date: Tue, 8 Apr 2014 13:26:04 -0400 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: References: <53397650.9000406@gmail.com> <533C036C.5070400@gmail.com> Message-ID: You don't use bounds in the struct, you put them in the impl. So you would instead say struct LCD { spi: S, ... } and then: impl LCD { ... } On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov wrote: > I might have found an unsupported case. > > Consider the following: > > trait SPI { ... } > > struct McuSPI; > impl SPI for McuSPI { ... } > > struct LCD { > spi: &SPI, > ... > } > > This code results in a dynamic dispatch to SPI, as "trait bounds are not > allowed in structure definitions". Is it in any way possible to use static > dispatch from LCD to SPI given the exact implementations are known at > compile time? > > > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: >> >> And just in case there is a confusion (as I have noticed others to >> have), it might help to see a specific example comparing static >> dispatch with dynamic. >> >> // This is a single function for all types implementing the LCD Trait. >> fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of >> the object being passed in >> x.line(....); // dynamic dispatch >> } >> >> // Like C++ templates, this generates a function for each type T that >> implements LCD. >> fn foo(x : &T) { // x's type is &T rather than &LCD >> x.line(....); // static dispatch based on type T known at compile-time >> } >> >> On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay >> wrote: >> > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: >> >> If I get it right, calls to traits are resolved in runtime (so, traits >> >> are kind of similar to C++ virtual methods). >> > >> > All method calls on regular types are resolved via static dispatch, >> > whether or not they come from a trait. For example, consider a generic >> > function like the following: >> > >> > fn min(a: T, b: T) -> T { >> > if a < b { a } else { b } >> > } >> > >> > This function performs a *static* call of the `lt` method defined on the >> > `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded >> > at compile-time just as C++ templates are. >> > >> > Rust also allows using traits as boxed objects, but this is an entirely >> > transparent choice. They're almost always used for static dispatch via >> > trait bounds on generics, or simply outside of generics. >> > >> >> What I'm proposing here is a compile-time approach. >> >> >> >> Let's say we have the following trait: >> >> >> >> pub trait LCD { >> >> fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: >> >> u8); >> >> fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); >> >> fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, >> >> color: u8); >> >> fn putc(&mut self, value: char); >> >> fn puts(&mut self, s: &str); >> >> >> >> fn flush(&self); >> >> fn clear(&mut self); >> >> } >> >> >> >> which defined a LED screen. There are two structs implementing it: >> >> C12832 and ILI9341 (two different lcd controllers). >> >> >> >> So I want my app to print hello world on lcd, I write the following >> >> code: >> >> >> >> let mut lcd = lcd_c12832::C12832::new(spi); >> >> let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; >> >> l.puts("hello, world"); >> >> >> >> Which results in a runtime dispatch, a slower and bigger code than the >> >> one I'd have without a trait. >> > >> > You can call methods defined on a trait without boxing the object as a >> > trait object. The ability to perform dynamic dispatch via a trait object >> > is totally optional. The methods can also be called directly, including >> > inside a generic function by specifying the trait as a type parameter >> > bound. You can simply call the `puts` method directly on the `lcd` >> > object without a cast. >> > >> >> A second problem is there is no easy way to write unified code that >> >> supports both the lcds based on passed in --cfg, as I can't >> >> apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of >> >> problematic to return a &LCD out from it given that there is no heap >> >> and >> >> no analog of placement new from C++. >> > >> > Rust supports generic functions, and you can write code supporting both >> > types by making it generic. The choice between static dispatch and >> > dynamic dispatch is entirely up to you in the current system. >> > >> >> Proposed binding concept solves those two problems: >> >> >> >> #[cfg(lcd_c12832)] >> >> let Binding: binding { >> >> let lcd: &lcd_c12832::C12832; >> >> let main: &Main; >> >> >> >> bind main.lcd = lcd; >> >> } >> >> >> >> at this point of time compiler can be sure about what struct is >> >> implementing LCD trait for main.lcd and can bind the function bodies as >> >> compile time, inlining them if applicable. >> >> >> >> This also might be something that is already implemented, please >> >> advice. >> >> The goal here is to minimise runtime code being executed and its size. >> > >> > >> > >> > _______________________________________________ >> > Rust-dev mailing list >> > Rust-dev at mozilla.org >> > https://mail.mozilla.org/listinfo/rust-dev >> > > > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- http://octayn.net/ From farcaller at gmail.com Tue Apr 8 11:08:57 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Tue, 8 Apr 2014 19:08:57 +0100 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: References: <53397650.9000406@gmail.com> <533C036C.5070400@gmail.com> Message-ID: That actually worked much better than I expected inlining everything and getting rid of vtables (I don't have support for .data section at the moment :-) ). I can't say the syntax is very clear to me, but I can get used to it. Still, one more question remains. I have a "debug output" concept, which means that debug::d("str") gets delivered to either LCD or UART, whatever is configured at runtime. I do it via static mut: pub trait Debugger { fn debugs(&mut self, s: &str); } pub static mut debug_output: *mut c12332::C12332<'static, &'static spi::SPI> = unsafe { init() }; pub fn d(s: &str) { let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; // failed to find an implementation of trait hal::spi::SPI for &'static hal::spi::SPI:'static debugger.debugs(s); } pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) { unsafe { debug_output = lcd; }; } I don't really support UART now, but I'd still like to access my LCD via a globally known static getter. How can I re-write that with typed struct? On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson wrote: > You don't use bounds in the struct, you put them in the impl. So you > would instead say > > > struct LCD { > spi: S, > ... > } > > > and then: > > impl LCD { > ... > } > > On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov > wrote: > > I might have found an unsupported case. > > > > Consider the following: > > > > trait SPI { ... } > > > > struct McuSPI; > > impl SPI for McuSPI { ... } > > > > struct LCD { > > spi: &SPI, > > ... > > } > > > > This code results in a dynamic dispatch to SPI, as "trait bounds are not > > allowed in structure definitions". Is it in any way possible to use > static > > dispatch from LCD to SPI given the exact implementations are known at > > compile time? > > > > > > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: > >> > >> And just in case there is a confusion (as I have noticed others to > >> have), it might help to see a specific example comparing static > >> dispatch with dynamic. > >> > >> // This is a single function for all types implementing the LCD Trait. > >> fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of > >> the object being passed in > >> x.line(....); // dynamic dispatch > >> } > >> > >> // Like C++ templates, this generates a function for each type T that > >> implements LCD. > >> fn foo(x : &T) { // x's type is &T rather than &LCD > >> x.line(....); // static dispatch based on type T known at > compile-time > >> } > >> > >> On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay > >> wrote: > >> > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: > >> >> If I get it right, calls to traits are resolved in runtime (so, > traits > >> >> are kind of similar to C++ virtual methods). > >> > > >> > All method calls on regular types are resolved via static dispatch, > >> > whether or not they come from a trait. For example, consider a generic > >> > function like the following: > >> > > >> > fn min(a: T, b: T) -> T { > >> > if a < b { a } else { b } > >> > } > >> > > >> > This function performs a *static* call of the `lt` method defined on > the > >> > `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded > >> > at compile-time just as C++ templates are. > >> > > >> > Rust also allows using traits as boxed objects, but this is an > entirely > >> > transparent choice. They're almost always used for static dispatch via > >> > trait bounds on generics, or simply outside of generics. > >> > > >> >> What I'm proposing here is a compile-time approach. > >> >> > >> >> Let's say we have the following trait: > >> >> > >> >> pub trait LCD { > >> >> fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: > >> >> u8); > >> >> fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); > >> >> fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, > >> >> color: u8); > >> >> fn putc(&mut self, value: char); > >> >> fn puts(&mut self, s: &str); > >> >> > >> >> fn flush(&self); > >> >> fn clear(&mut self); > >> >> } > >> >> > >> >> which defined a LED screen. There are two structs implementing it: > >> >> C12832 and ILI9341 (two different lcd controllers). > >> >> > >> >> So I want my app to print hello world on lcd, I write the following > >> >> code: > >> >> > >> >> let mut lcd = lcd_c12832::C12832::new(spi); > >> >> let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; > >> >> l.puts("hello, world"); > >> >> > >> >> Which results in a runtime dispatch, a slower and bigger code than > the > >> >> one I'd have without a trait. > >> > > >> > You can call methods defined on a trait without boxing the object as a > >> > trait object. The ability to perform dynamic dispatch via a trait > object > >> > is totally optional. The methods can also be called directly, > including > >> > inside a generic function by specifying the trait as a type parameter > >> > bound. You can simply call the `puts` method directly on the `lcd` > >> > object without a cast. > >> > > >> >> A second problem is there is no easy way to write unified code that > >> >> supports both the lcds based on passed in --cfg, as I can't > >> >> apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of > >> >> problematic to return a &LCD out from it given that there is no heap > >> >> and > >> >> no analog of placement new from C++. > >> > > >> > Rust supports generic functions, and you can write code supporting > both > >> > types by making it generic. The choice between static dispatch and > >> > dynamic dispatch is entirely up to you in the current system. > >> > > >> >> Proposed binding concept solves those two problems: > >> >> > >> >> #[cfg(lcd_c12832)] > >> >> let Binding: binding { > >> >> let lcd: &lcd_c12832::C12832; > >> >> let main: &Main; > >> >> > >> >> bind main.lcd = lcd; > >> >> } > >> >> > >> >> at this point of time compiler can be sure about what struct is > >> >> implementing LCD trait for main.lcd and can bind the function bodies > as > >> >> compile time, inlining them if applicable. > >> >> > >> >> This also might be something that is already implemented, please > >> >> advice. > >> >> The goal here is to minimise runtime code being executed and its > size. > >> > > >> > > >> > > >> > _______________________________________________ > >> > Rust-dev mailing list > >> > Rust-dev at mozilla.org > >> > https://mail.mozilla.org/listinfo/rust-dev > >> > > > > > > > > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > > > > -- > http://octayn.net/ > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Tue Apr 8 11:34:44 2014 From: corey at octayn.net (Corey Richardson) Date: Tue, 8 Apr 2014 14:34:44 -0400 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: References: <53397650.9000406@gmail.com> <533C036C.5070400@gmail.com> Message-ID: `&'static SPI` is going to be a trait object (with dynamic dispatch). The error it's giving is that `&SPI` (the trait object) doesn't implement `SPI` (the trait). You would have to explicitly implement `SPI` for `&SPI`. I'm not really sure how to solve this without using trait objects; you seem to want an inherently dynamically-dispatched system. On Tue, Apr 8, 2014 at 2:08 PM, Vladimir Pouzanov wrote: > That actually worked much better than I expected inlining everything and > getting rid of vtables (I don't have support for .data section at the moment > :-) ). > > I can't say the syntax is very clear to me, but I can get used to it. Still, > one more question remains. I have a "debug output" concept, which means that > debug::d("str") gets delivered to either LCD or UART, whatever is configured > at runtime. I do it via static mut: > > pub trait Debugger { > fn debugs(&mut self, s: &str); > } > > pub static mut debug_output: *mut c12332::C12332<'static, &'static spi::SPI> > = unsafe { init() }; > > pub fn d(s: &str) { > let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; // failed > to find an implementation of trait hal::spi::SPI for &'static > hal::spi::SPI:'static > debugger.debugs(s); > } > > pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) { > unsafe { debug_output = lcd; }; > } > > I don't really support UART now, but I'd still like to access my LCD via a > globally known static getter. How can I re-write that with typed struct? > > > On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson wrote: >> >> You don't use bounds in the struct, you put them in the impl. So you >> would instead say >> >> >> struct LCD { >> spi: S, >> ... >> } >> >> >> and then: >> >> impl LCD { >> ... >> } >> >> On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov >> wrote: >> > I might have found an unsupported case. >> > >> > Consider the following: >> > >> > trait SPI { ... } >> > >> > struct McuSPI; >> > impl SPI for McuSPI { ... } >> > >> > struct LCD { >> > spi: &SPI, >> > ... >> > } >> > >> > This code results in a dynamic dispatch to SPI, as "trait bounds are not >> > allowed in structure definitions". Is it in any way possible to use >> > static >> > dispatch from LCD to SPI given the exact implementations are known at >> > compile time? >> > >> > >> > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: >> >> >> >> And just in case there is a confusion (as I have noticed others to >> >> have), it might help to see a specific example comparing static >> >> dispatch with dynamic. >> >> >> >> // This is a single function for all types implementing the LCD Trait. >> >> fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of >> >> the object being passed in >> >> x.line(....); // dynamic dispatch >> >> } >> >> >> >> // Like C++ templates, this generates a function for each type T that >> >> implements LCD. >> >> fn foo(x : &T) { // x's type is &T rather than &LCD >> >> x.line(....); // static dispatch based on type T known at >> >> compile-time >> >> } >> >> >> >> On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay >> >> wrote: >> >> > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: >> >> >> If I get it right, calls to traits are resolved in runtime (so, >> >> >> traits >> >> >> are kind of similar to C++ virtual methods). >> >> > >> >> > All method calls on regular types are resolved via static dispatch, >> >> > whether or not they come from a trait. For example, consider a >> >> > generic >> >> > function like the following: >> >> > >> >> > fn min(a: T, b: T) -> T { >> >> > if a < b { a } else { b } >> >> > } >> >> > >> >> > This function performs a *static* call of the `lt` method defined on >> >> > the >> >> > `Ord` trait that `TotalOrd` inherits from. Generics are fully >> >> > expanded >> >> > at compile-time just as C++ templates are. >> >> > >> >> > Rust also allows using traits as boxed objects, but this is an >> >> > entirely >> >> > transparent choice. They're almost always used for static dispatch >> >> > via >> >> > trait bounds on generics, or simply outside of generics. >> >> > >> >> >> What I'm proposing here is a compile-time approach. >> >> >> >> >> >> Let's say we have the following trait: >> >> >> >> >> >> pub trait LCD { >> >> >> fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: >> >> >> u8); >> >> >> fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); >> >> >> fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, >> >> >> color: u8); >> >> >> fn putc(&mut self, value: char); >> >> >> fn puts(&mut self, s: &str); >> >> >> >> >> >> fn flush(&self); >> >> >> fn clear(&mut self); >> >> >> } >> >> >> >> >> >> which defined a LED screen. There are two structs implementing it: >> >> >> C12832 and ILI9341 (two different lcd controllers). >> >> >> >> >> >> So I want my app to print hello world on lcd, I write the following >> >> >> code: >> >> >> >> >> >> let mut lcd = lcd_c12832::C12832::new(spi); >> >> >> let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; >> >> >> l.puts("hello, world"); >> >> >> >> >> >> Which results in a runtime dispatch, a slower and bigger code than >> >> >> the >> >> >> one I'd have without a trait. >> >> > >> >> > You can call methods defined on a trait without boxing the object as >> >> > a >> >> > trait object. The ability to perform dynamic dispatch via a trait >> >> > object >> >> > is totally optional. The methods can also be called directly, >> >> > including >> >> > inside a generic function by specifying the trait as a type parameter >> >> > bound. You can simply call the `puts` method directly on the `lcd` >> >> > object without a cast. >> >> > >> >> >> A second problem is there is no easy way to write unified code that >> >> >> supports both the lcds based on passed in --cfg, as I can't >> >> >> apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of >> >> >> problematic to return a &LCD out from it given that there is no heap >> >> >> and >> >> >> no analog of placement new from C++. >> >> > >> >> > Rust supports generic functions, and you can write code supporting >> >> > both >> >> > types by making it generic. The choice between static dispatch and >> >> > dynamic dispatch is entirely up to you in the current system. >> >> > >> >> >> Proposed binding concept solves those two problems: >> >> >> >> >> >> #[cfg(lcd_c12832)] >> >> >> let Binding: binding { >> >> >> let lcd: &lcd_c12832::C12832; >> >> >> let main: &Main; >> >> >> >> >> >> bind main.lcd = lcd; >> >> >> } >> >> >> >> >> >> at this point of time compiler can be sure about what struct is >> >> >> implementing LCD trait for main.lcd and can bind the function bodies >> >> >> as >> >> >> compile time, inlining them if applicable. >> >> >> >> >> >> This also might be something that is already implemented, please >> >> >> advice. >> >> >> The goal here is to minimise runtime code being executed and its >> >> >> size. >> >> > >> >> > >> >> > >> >> > _______________________________________________ >> >> > Rust-dev mailing list >> >> > Rust-dev at mozilla.org >> >> > https://mail.mozilla.org/listinfo/rust-dev >> >> > >> > >> > >> > >> > >> > -- >> > Sincerely, >> > Vladimir "Farcaller" Pouzanov >> > http://farcaller.net/ >> > >> > _______________________________________________ >> > Rust-dev mailing list >> > Rust-dev at mozilla.org >> > https://mail.mozilla.org/listinfo/rust-dev >> > >> >> >> >> -- >> http://octayn.net/ > > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ -- http://octayn.net/ From farcaller at gmail.com Tue Apr 8 12:03:19 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Tue, 8 Apr 2014 20:03:19 +0100 Subject: [rust-dev] Porting some nesC features to rust? In-Reply-To: References: <53397650.9000406@gmail.com> <533C036C.5070400@gmail.com> Message-ID: Yes, in the end I decided to implement .data section copy over from flash to ram to get vtables :-) On Tue, Apr 8, 2014 at 7:34 PM, Corey Richardson wrote: > `&'static SPI` is going to be a trait object (with dynamic dispatch). > The error it's giving is that `&SPI` (the trait object) doesn't > implement `SPI` (the trait). You would have to explicitly implement > `SPI` for `&SPI`. I'm not really sure how to solve this without using > trait objects; you seem to want an inherently dynamically-dispatched > system. > > On Tue, Apr 8, 2014 at 2:08 PM, Vladimir Pouzanov > wrote: > > That actually worked much better than I expected inlining everything and > > getting rid of vtables (I don't have support for .data section at the > moment > > :-) ). > > > > I can't say the syntax is very clear to me, but I can get used to it. > Still, > > one more question remains. I have a "debug output" concept, which means > that > > debug::d("str") gets delivered to either LCD or UART, whatever is > configured > > at runtime. I do it via static mut: > > > > pub trait Debugger { > > fn debugs(&mut self, s: &str); > > } > > > > pub static mut debug_output: *mut c12332::C12332<'static, &'static > spi::SPI> > > = unsafe { init() }; > > > > pub fn d(s: &str) { > > let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; // > failed > > to find an implementation of trait hal::spi::SPI for &'static > > hal::spi::SPI:'static > > debugger.debugs(s); > > } > > > > pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) { > > unsafe { debug_output = lcd; }; > > } > > > > I don't really support UART now, but I'd still like to access my LCD via > a > > globally known static getter. How can I re-write that with typed struct? > > > > > > On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson > wrote: > >> > >> You don't use bounds in the struct, you put them in the impl. So you > >> would instead say > >> > >> > >> struct LCD { > >> spi: S, > >> ... > >> } > >> > >> > >> and then: > >> > >> impl LCD { > >> ... > >> } > >> > >> On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov > >> wrote: > >> > I might have found an unsupported case. > >> > > >> > Consider the following: > >> > > >> > trait SPI { ... } > >> > > >> > struct McuSPI; > >> > impl SPI for McuSPI { ... } > >> > > >> > struct LCD { > >> > spi: &SPI, > >> > ... > >> > } > >> > > >> > This code results in a dynamic dispatch to SPI, as "trait bounds are > not > >> > allowed in structure definitions". Is it in any way possible to use > >> > static > >> > dispatch from LCD to SPI given the exact implementations are known at > >> > compile time? > >> > > >> > > >> > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles > wrote: > >> >> > >> >> And just in case there is a confusion (as I have noticed others to > >> >> have), it might help to see a specific example comparing static > >> >> dispatch with dynamic. > >> >> > >> >> // This is a single function for all types implementing the LCD > Trait. > >> >> fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of > >> >> the object being passed in > >> >> x.line(....); // dynamic dispatch > >> >> } > >> >> > >> >> // Like C++ templates, this generates a function for each type T that > >> >> implements LCD. > >> >> fn foo(x : &T) { // x's type is &T rather than &LCD > >> >> x.line(....); // static dispatch based on type T known at > >> >> compile-time > >> >> } > >> >> > >> >> On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay > >> >> wrote: > >> >> > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: > >> >> >> If I get it right, calls to traits are resolved in runtime (so, > >> >> >> traits > >> >> >> are kind of similar to C++ virtual methods). > >> >> > > >> >> > All method calls on regular types are resolved via static dispatch, > >> >> > whether or not they come from a trait. For example, consider a > >> >> > generic > >> >> > function like the following: > >> >> > > >> >> > fn min(a: T, b: T) -> T { > >> >> > if a < b { a } else { b } > >> >> > } > >> >> > > >> >> > This function performs a *static* call of the `lt` method defined > on > >> >> > the > >> >> > `Ord` trait that `TotalOrd` inherits from. Generics are fully > >> >> > expanded > >> >> > at compile-time just as C++ templates are. > >> >> > > >> >> > Rust also allows using traits as boxed objects, but this is an > >> >> > entirely > >> >> > transparent choice. They're almost always used for static dispatch > >> >> > via > >> >> > trait bounds on generics, or simply outside of generics. > >> >> > > >> >> >> What I'm proposing here is a compile-time approach. > >> >> >> > >> >> >> Let's say we have the following trait: > >> >> >> > >> >> >> pub trait LCD { > >> >> >> fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, > color: > >> >> >> u8); > >> >> >> fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: > u8); > >> >> >> fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: > i32, > >> >> >> color: u8); > >> >> >> fn putc(&mut self, value: char); > >> >> >> fn puts(&mut self, s: &str); > >> >> >> > >> >> >> fn flush(&self); > >> >> >> fn clear(&mut self); > >> >> >> } > >> >> >> > >> >> >> which defined a LED screen. There are two structs implementing it: > >> >> >> C12832 and ILI9341 (two different lcd controllers). > >> >> >> > >> >> >> So I want my app to print hello world on lcd, I write the > following > >> >> >> code: > >> >> >> > >> >> >> let mut lcd = lcd_c12832::C12832::new(spi); > >> >> >> let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD; > >> >> >> l.puts("hello, world"); > >> >> >> > >> >> >> Which results in a runtime dispatch, a slower and bigger code than > >> >> >> the > >> >> >> one I'd have without a trait. > >> >> > > >> >> > You can call methods defined on a trait without boxing the object > as > >> >> > a > >> >> > trait object. The ability to perform dynamic dispatch via a trait > >> >> > object > >> >> > is totally optional. The methods can also be called directly, > >> >> > including > >> >> > inside a generic function by specifying the trait as a type > parameter > >> >> > bound. You can simply call the `puts` method directly on the `lcd` > >> >> > object without a cast. > >> >> > > >> >> >> A second problem is there is no easy way to write unified code > that > >> >> >> supports both the lcds based on passed in --cfg, as I can't > >> >> >> apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind > of > >> >> >> problematic to return a &LCD out from it given that there is no > heap > >> >> >> and > >> >> >> no analog of placement new from C++. > >> >> > > >> >> > Rust supports generic functions, and you can write code supporting > >> >> > both > >> >> > types by making it generic. The choice between static dispatch and > >> >> > dynamic dispatch is entirely up to you in the current system. > >> >> > > >> >> >> Proposed binding concept solves those two problems: > >> >> >> > >> >> >> #[cfg(lcd_c12832)] > >> >> >> let Binding: binding { > >> >> >> let lcd: &lcd_c12832::C12832; > >> >> >> let main: &Main; > >> >> >> > >> >> >> bind main.lcd = lcd; > >> >> >> } > >> >> >> > >> >> >> at this point of time compiler can be sure about what struct is > >> >> >> implementing LCD trait for main.lcd and can bind the function > bodies > >> >> >> as > >> >> >> compile time, inlining them if applicable. > >> >> >> > >> >> >> This also might be something that is already implemented, please > >> >> >> advice. > >> >> >> The goal here is to minimise runtime code being executed and its > >> >> >> size. > >> >> > > >> >> > > >> >> > > >> >> > _______________________________________________ > >> >> > Rust-dev mailing list > >> >> > Rust-dev at mozilla.org > >> >> > https://mail.mozilla.org/listinfo/rust-dev > >> >> > > >> > > >> > > >> > > >> > > >> > -- > >> > Sincerely, > >> > Vladimir "Farcaller" Pouzanov > >> > http://farcaller.net/ > >> > > >> > _______________________________________________ > >> > Rust-dev mailing list > >> > Rust-dev at mozilla.org > >> > https://mail.mozilla.org/listinfo/rust-dev > >> > > >> > >> > >> > >> -- > >> http://octayn.net/ > > > > > > > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > > > > -- > http://octayn.net/ > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From remifontan at yahoo.fr Wed Apr 9 01:18:48 2014 From: remifontan at yahoo.fr (=?UTF-8?B?UsOpbWkgRm9udGFu?=) Date: Wed, 9 Apr 2014 20:18:48 +1200 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> Message-ID: thanks for all your replies. I understand that zero has a specific meaning to addition, and as well as multiplication, but for some reason does not require the mul trait. implementing default sounds like a reasonable solution for my case. I initially wanted to implement zero for my matrix4x4. I haven't implemented add as I don't think I'm going to be adding matrix so I did not bother. making default return [0...0] would work as well. cheers, R?mi On Wed, Apr 9, 2014 at 5:20 AM, Kevin Ballard wrote: > On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > > On 07 Apr 2014, at 08:44, Nicholas Radford > wrote: > > I think the original question was, why does the zero trait require the add > trait. > > If that was the original question, then my answer would be that > std::num::Zero requires the Add trait because of the way it is specified: > "Defines an additive identity element for Self". Then the question > becomes: "why is Zero specified like that?", and I would answer: because > then you can use it in generic algorithms which require their argument(s) > to have an additional identity. > > > If you want a zero value for a type that doesn't support addition, > std::default::Default may be a good choice to use. Semantically, that > actually returns the "default value" for a type instead of the "zero > value", but in a type without addition, how do you define "zero value"? > > -Kevin > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- R?mi Fontan : remifontan at yahoo.fr mobile: +64 21 855 351 93 Otaki Street, Miramar 6022 Wellington, New Zealand -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Wed Apr 9 02:19:54 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Wed, 09 Apr 2014 12:19:54 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> Message-ID: <0C25A6A8-3587-465E-A515-85B1DDCCAA0F@icloud.com> The problem and a potential source of confusion is that the trait is named 'Zero' when a more proper name would be 'AdditiveIdentity'. There could be separate trait to indicate zero, but I don't know how much value such a trait would have. Here's the formal definition of additive identity from wikipedia: Let N be a set which is closed under the operation of addition, denoted +. An additive identity for N is any element e such that for any element n in N, e + n = n = n + e Example: The formula is n + 0 = n = 0 + n. That's the reason it doesn't require the Mult trait. > On 09 Apr 2014, at 11:18, R?mi Fontan wrote: > > thanks for all your replies. I understand that zero has a specific meaning to addition, and as well as multiplication, but for some reason does not require the mul trait. > > implementing default sounds like a reasonable solution for my case. I initially wanted to implement zero for my matrix4x4. I haven't implemented add as I don't think I'm going to be adding matrix so I did not bother. making default return [0...0] would work as well. > > cheers, > > R?mi > > > >> On Wed, Apr 9, 2014 at 5:20 AM, Kevin Ballard wrote: >>> On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: >>> >>>> On 07 Apr 2014, at 08:44, Nicholas Radford wrote: >>>> >>>> I think the original question was, why does the zero trait require the add trait. >>>> >>> If that was the original question, then my answer would be that std::num::Zero requires the Add trait because of the way it is specified: "Defines an additive identity element for Self". Then the question becomes: "why is Zero specified like that?", and I would answer: because then you can use it in generic algorithms which require their argument(s) to have an additional identity. >> >> If you want a zero value for a type that doesn't support addition, std::default::Default may be a good choice to use. Semantically, that actually returns the "default value" for a type instead of the "zero value", but in a type without addition, how do you define "zero value"? >> >> -Kevin >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > > -- > R?mi Fontan : remifontan at yahoo.fr > mobile: +64 21 855 351 > 93 Otaki Street, Miramar 6022 > Wellington, New Zealand -------------- next part -------------- An HTML attachment was scrubbed... URL: From com.liigo at gmail.com Wed Apr 9 06:29:33 2014 From: com.liigo at gmail.com (Liigo Zhuang) Date: Wed, 9 Apr 2014 21:29:33 +0800 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> Message-ID: Zero is a bad name here, it should be renamed or removed 2014?4?9? ??1:20? "Kevin Ballard" ??? > On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > > On 07 Apr 2014, at 08:44, Nicholas Radford > wrote: > > I think the original question was, why does the zero trait require the add > trait. > > If that was the original question, then my answer would be that > std::num::Zero requires the Add trait because of the way it is specified: > "Defines an additive identity element for Self". Then the question > becomes: "why is Zero specified like that?", and I would answer: because > then you can use it in generic algorithms which require their argument(s) > to have an additional identity. > > > If you want a zero value for a type that doesn't support addition, > std::default::Default may be a good choice to use. Semantically, that > actually returns the "default value" for a type instead of the "zero > value", but in a type without addition, how do you define "zero value"? > > -Kevin > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Wed Apr 9 10:46:58 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 9 Apr 2014 10:46:58 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> Message-ID: <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> Why? Zero is the additive identity. It's only bad if you want to denote a value that contains zeros that doesn't support addition, but that's only bad because of a misconception that Zero should mean "a default value" when we have Default for that. For reference, the Zero trait lives in std::num, which should be a good indication that this is a property of numeric types. AdditiveIdentity is the only reasonable alternative, but that's a mouthful of a name and I think changing the name to this would be more confusing. Someone who needs a numeric zero isn't going to go looking for AdditiveIdentity, they're going to look for Zero. -Kevin On Apr 9, 2014, at 6:29 AM, Liigo Zhuang wrote: > Zero is a bad name here, it should be renamed or removed > > 2014?4?9? ??1:20? "Kevin Ballard" ??? > On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > >> On 07 Apr 2014, at 08:44, Nicholas Radford wrote: >> >>> I think the original question was, why does the zero trait require the add trait. >>> >> If that was the original question, then my answer would be that std::num::Zero requires the Add trait because of the way it is specified: "Defines an additive identity element for Self". Then the question becomes: "why is Zero specified like that?", and I would answer: because then you can use it in generic algorithms which require their argument(s) to have an additional identity. > > If you want a zero value for a type that doesn't support addition, std::default::Default may be a good choice to use. Semantically, that actually returns the "default value" for a type instead of the "zero value", but in a type without addition, how do you define "zero value"? > > -Kevin > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ecreed at cs.washington.edu Wed Apr 9 10:52:46 2014 From: ecreed at cs.washington.edu (Eric Reed) Date: Wed, 9 Apr 2014 10:52:46 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> Message-ID: In addition, mathematicians typically use the symbol '0' to refer to the additive identity of a ring anyway. On Apr 9, 2014 10:47 AM, "Kevin Ballard" wrote: > Why? Zero is the additive identity. It's only bad if you want to denote a > value that contains zeros that doesn't support addition, but that's only > bad because of a misconception that Zero should mean "a default value" when > we have Default for that. For reference, the Zero trait lives in std::num, > which should be a good indication that this is a property of numeric types. > > AdditiveIdentity is the only reasonable alternative, but that's a mouthful > of a name and I think changing the name to this would be more confusing. > Someone who needs a numeric zero isn't going to go looking for > AdditiveIdentity, they're going to look for Zero. > > -Kevin > > On Apr 9, 2014, at 6:29 AM, Liigo Zhuang wrote: > > Zero is a bad name here, it should be renamed or removed > 2014?4?9? ??1:20? "Kevin Ballard" ??? > >> On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: >> >> On 07 Apr 2014, at 08:44, Nicholas Radford >> wrote: >> >> I think the original question was, why does the zero trait require the >> add trait. >> >> If that was the original question, then my answer would be that >> std::num::Zero requires the Add trait because of the way it is >> specified: "Defines an additive identity element for Self". Then the >> question becomes: "why is Zero specified like that?", and I would answer: >> because then you can use it in generic algorithms which require their >> argument(s) to have an additional identity. >> >> >> If you want a zero value for a type that doesn't support addition, >> std::default::Default may be a good choice to use. Semantically, that >> actually returns the "default value" for a type instead of the "zero >> value", but in a type without addition, how do you define "zero value"? >> >> -Kevin >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Wed Apr 9 11:24:59 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Wed, 09 Apr 2014 21:24:59 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> Message-ID: <36C78A4F-E211-476E-BB8F-A4504AF517AA@icloud.com> > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > For reference, the Zero trait lives in std::num, which should be a good indication that this is a property of numeric types. Am I not supposed to use std::num::Zero for defining things like zero vector or zero matrix? Those are neither numbers nor zeroes. From ecreed at cs.washington.edu Wed Apr 9 11:37:33 2014 From: ecreed at cs.washington.edu (Eric Reed) Date: Wed, 9 Apr 2014 11:37:33 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <36C78A4F-E211-476E-BB8F-A4504AF517AA@icloud.com> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <36C78A4F-E211-476E-BB8F-A4504AF517AA@icloud.com> Message-ID: If you implement Add on a type, then you should implement Zero to specify the identity of the + operation on that type. If you simply want to specify a default value, then you should implement Default. On Apr 9, 2014 11:25 AM, "Tommi Tissari" wrote: > > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > > > For reference, the Zero trait lives in std::num, which should be a good > indication that this is a property of numeric types. > > Am I not supposed to use std::num::Zero for defining things like zero > vector or zero matrix? Those are neither numbers nor zeroes. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From philippe.delrieu at free.fr Wed Apr 9 12:53:51 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Wed, 09 Apr 2014 21:53:51 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: <53428957.2080500@free.fr> References: <533F18DD.5040803@free.fr> <534193E4.5080800@free.fr> <53428957.2080500@free.fr> Message-ID: <5345A54F.6080704@free.fr> I find a solution by removing the ~ to Base trait. The code //(First and Second think as defined earlier) enum BaseImpl { FirstThinkImpl(FirstThink), SecondThinkImpl(SecondThink), } struct Container { nodeList: Vec<~BaseImpl>, } impl<'a> Container { fn iter_base(&'a self) -> BaseItems<'a> { let iter = self.nodeList.iter(); BaseItems{ iter : iter } } } struct BaseItems<'a> { iter : Items<'a, ~BaseImpl> } impl<'a> Iterator<&'a Base> for BaseItems<'a> { fn next(&mut self) -> Option<&'a Base> { match self.iter.next() { Some(ref baseimpl) => { Some(match ***baseimpl{ FirstThinkImpl(ref first) => first as &'a Base, SecondThinkImpl(ref second)=> second as &'a Base, }) }, None => None, } } } Now it compile. So I try to define a mutable iterator like the immuable and with similar code I have again the lifetime compile error : struct BaseMutItems<'a> { iter : MutItems<'a, ~BaseImpl> } impl<'a> Iterator<&'a mut Base> for BaseMutItems<'a> { fn next(&mut self) -> Option<&'a mut Base> { match self.iter.next() { Some(ref mut baseimpl) => { Some(match ***baseimpl{ FirstThinkImpl(ref mut first) => first as &'a mut Base, SecondThinkImpl(ref mut second)=> second as &'a mut Base, }) }, None => None, } } } error : test_enum.rs:125:36: 125:49 error: lifetime of `baseimpl` is too short to guarantee its contents can be safely reborrowed test_enum.rs:125 FirstThinkImpl(ref mut first) => first as &'a mut Base, I can't see what's going wrong. I put all the code if someone want to test : use std::iter::Iterator; use std::slice::{Items, MutItems}; trait Base { fn set_something(&mut self); fn isSecondThink(&self) -> bool; } struct FirstThink{ count1: int, } impl Base for FirstThink { fn set_something(&mut self) {println!("ici First count:{:?}", self.count1); self.count1+=1;} fn isSecondThink(&self) -> bool {false} } struct SecondThink{ count2: int, } impl Base for SecondThink { fn set_something(&mut self) {println!("ici Second count:{:?}", self.count2); self.count2+=1;} fn isSecondThink(&self) -> bool {true} } enum BaseImpl { FirstThinkImpl(FirstThink), SecondThinkImpl(SecondThink), } fn some_second_process(think: &mut SecondThink) { think.set_something(); } struct Container { nodeList: Vec<~BaseImpl>, } impl<'a> Container { fn add_FirstThink(&mut self, think: FirstThink) { self.nodeList.push(~FirstThinkImpl(think)); } fn add_SecondThink(&mut self, think: SecondThink) { self.nodeList.push(~SecondThinkImpl(think)); } fn iter_base(&'a self) -> BaseItems<'a> { let iter = self.nodeList.iter(); BaseItems{ iter : iter } } fn iter_second(&'a self) -> SecondItems<'a> { let iter = self.nodeList.iter(); SecondItems{ iter : iter } } fn mut_iter_base(&'a mut self) -> BaseMutItems<'a> { let iter = self.nodeList.mut_iter(); BaseMutItems{ iter : iter } } fn appli_secondthink_someprocess(&mut self, fct : fn (&mut SecondThink)) { for think in self.nodeList.mut_iter() { match **think { FirstThinkImpl(first) => println!(""), SecondThinkImpl(ref mut second)=> fct(second), } } } } struct BaseItems<'a> { iter : Items<'a, ~BaseImpl> } impl<'a> Iterator<&'a Base> for BaseItems<'a> { fn next(&mut self) -> Option<&'a Base> { match self.iter.next() { Some(ref baseimpl) => { Some(match ***baseimpl{ FirstThinkImpl(ref first) => first as &'a Base, SecondThinkImpl(ref second)=> second as &'a Base, }) }, None => None, } } } struct SecondItems<'a> { iter : Items<'a, ~BaseImpl> } impl<'a> Iterator<&'a SecondThink> for SecondItems<'a> { fn next(&mut self) -> Option<&'a SecondThink> { match self.iter.next() { Some(ref baseimpl) => { match ***baseimpl{ FirstThinkImpl(ref first) => self.next(), SecondThinkImpl(ref second)=> Some(second), } }, None => None, } } } struct BaseMutItems<'a> { iter : MutItems<'a, ~BaseImpl> } impl<'a> Iterator<&'a mut Base> for BaseMutItems<'a> { fn next(&mut self) -> Option<&'a mut Base> { match self.iter.next() { Some(ref mut baseimpl) => { Some(match ***baseimpl{ FirstThinkImpl(ref mut first) => first as &'a mut Base, SecondThinkImpl(ref mut second)=> second as &'a mut Base, }) }, None => None, } } } #[main] fn main() { let first = FirstThink{count1:0}; let second = SecondThink{count2:0}; let mut container = Container{nodeList: Vec::new()}; container.add_FirstThink(first); container.add_SecondThink(second); container.appli_secondthink_someprocess(some_second_process); container.appli_secondthink_someprocess(some_second_process); for think in container.iter_base() { println!("ici Second count:{:?}", think.isSecondThink()); } for think in container.iter_second() { println!("ici Second count:{:?}", think.isSecondThink()); } container.appli_secondthink_someprocess(some_second_process); } Le 07/04/2014 13:17, Philippe Delrieu a ?crit : > I try to implement the iterator like that: > > > struct BaseItems<'a> { > iter : Items<'a, ~BaseImpl> > } > > impl<'a> Iterator<&'a ~Base> for BaseItems<'a> { > fn next(&mut self) -> Option<&'a ~Base> { > match self.iter.next() { > Some(ref baseimpl) => { > Some(&'a match ***baseimpl{ > FirstThinkImpl(ref first) => *first as ~Base, > SecondThinkImpl(ref second)=> *second as ~Base, > }) > }, > None => None, > } > } > } > > But I have a lifetime problem. The error is : borrowed value does not > live long enough and reference must be valid for the lifetime &'a as > defined on the block > and : > cannot move out of dereference of `&`-pointer SecondThinkImpl(ref > second)=> *second as ~Base, > > Another possibility: > fn next(&mut self) -> Option<&'a ~Base> { > match self.iter.next() { > Some(ref baseimpl) => { > Some(match ***baseimpl{ > FirstThinkImpl(ref first) => first as &'a ~Base, > SecondThinkImpl(ref second)=> second as &'a > ~Base, > }) > }, > None => None, > } > } > generate the error: non-scalar cast: `&~FirstThink` as `&'a > ~Base` > > I try different possibility but I didn't find how to return a <'a> > lifetime ~Base or Base > > I remove the mut to simplify the test of the different lifetime > possibilities. > > Philippe > > Le 07/04/2014 10:27, Rodrigo Rivas a ?crit : >> On Sun, Apr 6, 2014 at 7:50 PM, Philippe Delrieu >> wrote: >>> I need some more help. >>> >>> The impl Iterator<&mut ~Base> for Container declaration generate >>> the error: >>> error: missing lifetime specifier >>> So I had it but I can't manage to return the next value with the >>> specified >>> life time. >>> The code : >>> impl<'a> Iterator<&'a mut ~Base> for Container { >>> /// Advance the iterator and return the next value. Return >>> `None` when >>> the end is reached. >>> fn next(&mut self) -> Option<&'a mut ~Base> { >>> if self.iter_counter == self.nodeList.len() { >>> None >>> } else { >>> self.iter_counter += 1; >>> Some(&'a mut match **self.nodeList.get(self.iter_counter){ >>> FirstThinkImpl(first) => first as ~Base, >>> SecondThinkImpl(second)=> second as ~Base, >>> }) >>> } >>> } >>> } >>> >>> Generate these errors : >>> test_enum.rs:58:18: 61:14 error: borrowed value does not live long >>> enough >>> test/test_enum.rs:58 Some(&'a mut match >> Oh, I think I may have misleaded you... You cannot implement the >> iterator directly in Container, because the iterator must handle the >> current position, while the Container just holds the values. You need >> a intermediate struct that implements the Iterator traits. That's what >> the `iter()` and ' move_iter()` functions do for vectors and other >> standard containers. So you'll need something along the lines of this >> (disclaimer: totally untested!!): >> >> struct Container { >> //.... >> fn iter(&'a self) -> BaseItems<'a> { >> let iter = nodeList.iter(); >> BaseItems{ iter : iter } >> } >> } >> >> struct BaseItems<'a> { >> iter : Items<'a, ~Base> >> } >> >> impl<'a> Iterator<&'a mut ~Base> for BaseItems<'a> { >> //.... >> } >> >> BTW, why all the double pointer in all the "&mut ~Base" instead of >> just "&mut Base"? >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > From rusty.gates at icloud.com Wed Apr 9 13:25:53 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Wed, 09 Apr 2014 23:25:53 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> Message-ID: > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > Why? Zero is the additive identity. Zero is _an_ additive identity for numbers, but not for vectors or matrices. use std::slice::Items; use std::iter::RandomAccessIterator; use std::num::Zero; Items is a RandomAccessIterator, but a RandomAccessIterator is not an Items. 0 is an additive identity, but an additive identity is not 0. You can't assign a zero to a 2x2 matrix, and therefore this trait is incorrectly named. The following just looks wrong: let m: Matrix = Zero::zero(); > AdditiveIdentity is the only reasonable alternative, but that's a mouthful of a name and I think changing the name to this would be more confusing. Naming a trait something that it's not is even more confusing. I don't think we should give an incorrect name to this trait on the grounds of the correct name being longer. Just look at RandomAccessIterator. From ward.nickjames at gmail.com Wed Apr 9 13:31:18 2014 From: ward.nickjames at gmail.com (Nick Ward) Date: Wed, 9 Apr 2014 21:31:18 +0100 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> Message-ID: http://en.wikipedia.org/wiki/Zero_matrix On 9 Apr 2014 21:26, "Tommi Tissari" wrote: > > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > > > > Why? Zero is the additive identity. > > Zero is _an_ additive identity for numbers, but not for vectors or > matrices. > > use std::slice::Items; > use std::iter::RandomAccessIterator; > use std::num::Zero; > > Items is a RandomAccessIterator, but a RandomAccessIterator is not an > Items. 0 is an additive identity, but an additive identity is not 0. You > can't assign a zero to a 2x2 matrix, and therefore this trait is > incorrectly named. The following just looks wrong: > > let m: Matrix = Zero::zero(); > > > AdditiveIdentity is the only reasonable alternative, but that's a > mouthful of a name and I think changing the name to this would be more > confusing. > > Naming a trait something that it's not is even more confusing. I don't > think we should give an incorrect name to this trait on the grounds of the > correct name being longer. Just look at RandomAccessIterator. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tupshin at tupshin.com Wed Apr 9 13:35:23 2014 From: tupshin at tupshin.com (Tupshin Harper) Date: Wed, 9 Apr 2014 16:35:23 -0400 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> Message-ID: Which is distinct from http://en.wikipedia.org/wiki/Identity_matrix On Apr 9, 2014 4:31 PM, "Nick Ward" wrote: > http://en.wikipedia.org/wiki/Zero_matrix > On 9 Apr 2014 21:26, "Tommi Tissari" wrote: > >> > On 09 Apr 2014, at 20:46, Kevin Ballard wrote: >> > >> > Why? Zero is the additive identity. >> >> Zero is _an_ additive identity for numbers, but not for vectors or >> matrices. >> >> use std::slice::Items; >> use std::iter::RandomAccessIterator; >> use std::num::Zero; >> >> Items is a RandomAccessIterator, but a RandomAccessIterator is not an >> Items. 0 is an additive identity, but an additive identity is not 0. You >> can't assign a zero to a 2x2 matrix, and therefore this trait is >> incorrectly named. The following just looks wrong: >> >> let m: Matrix = Zero::zero(); >> >> > AdditiveIdentity is the only reasonable alternative, but that's a >> mouthful of a name and I think changing the name to this would be more >> confusing. >> >> Naming a trait something that it's not is even more confusing. I don't >> think we should give an incorrect name to this trait on the grounds of the >> correct name being longer. Just look at RandomAccessIterator. >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Wed Apr 9 13:42:27 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 9 Apr 2014 13:42:27 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> Message-ID: <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> The number 0 is the additive identity for numbers. But informally, the additive identity for other things can be called "zero" without problem. Heck, even the wikipedia page on Additive Identity uses this example for groups: > Let (G, +) be a group and let 0 and 0' in G both denote additive identities, so for any g in G, > > 0 + g = g = g + 0 and 0' + g = g = g + 0' > It follows from the above that > > (0') = (0') + 0 = 0' + (0) = (0) Look at that, an additive identity for something other than a number, and zero (0) is used to denote this additive identity. The only issue comes in when you define addition in multiple different ways for a single type. Of course, right now I believe compiler bugs prevent you from actually using multiple implementations of Add<> with different type parameters for a given type, so this isn't actually a problem right now. And when that bug is fixed, it's still reasonable to consider Zero to be the additive identity for any addition where the receiver type is the right-hand side of the addition. In other words, if you define Add for Matrix, then the additive identity here is Zero::, not Zero::. Regarding "You can't assign a zero to a 2x2 matrix", additive identity does not require the ability to assign. And this is only a problem when considering addition between disparate types. If you consider matrix addition (e.g. 2x2 matrix + 2x2 matrix) then you certainly can assign the additive identity back to one of the matrix values. let m: Matrix = Zero::zero(); looks fine to me. It produces a matrix m that, when added to any other Matrix m', produces the same matrix m'. This is presumably a Matrix where every element is 0. But again, this only makes sense if you've actually defined Add for Matrix. Regardless, we've already made the decision not to go down numeric type hierarchy hell. We're trying to keep a reasonable simple numeric hierarchy. And part of that means using straightforward "lay-person" terms instead of perhaps more precise mathematical names. As such, we have std::num::Zero as the additive identity and std::num::One as the multiplicative identity. If you really want to complain about something, complain about std::num::One being used for things other than multiplicative identity, e.g. std::iter::range() uses Add and One to produce the next value in the range. -Kevin On Apr 9, 2014, at 1:25 PM, Tommi Tissari wrote: >> On 09 Apr 2014, at 20:46, Kevin Ballard wrote: >> >> Why? Zero is the additive identity. > > Zero is _an_ additive identity for numbers, but not for vectors or matrices. > > use std::slice::Items; > use std::iter::RandomAccessIterator; > use std::num::Zero; > > Items is a RandomAccessIterator, but a RandomAccessIterator is not an Items. 0 is an additive identity, but an additive identity is not 0. You can't assign a zero to a 2x2 matrix, and therefore this trait is incorrectly named. The following just looks wrong: > > let m: Matrix = Zero::zero(); > >> AdditiveIdentity is the only reasonable alternative, but that's a mouthful of a name and I think changing the name to this would be more confusing. > > Naming a trait something that it's not is even more confusing. I don't think we should give an incorrect name to this trait on the grounds of the correct name being longer. Just look at RandomAccessIterator. > From rusty.gates at icloud.com Wed Apr 9 14:06:34 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Thu, 10 Apr 2014 00:06:34 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> Message-ID: <5EE41BA2-ABB8-4CA9-B140-71E1AD06A672@icloud.com> > On 09 Apr 2014, at 23:42, Kevin Ballard wrote: > > The number 0 is the additive identity for numbers. But informally, the additive identity for other things can be called "zero" without problem. Ok, so it seems. From http://en.m.wikipedia.org/wiki/Identity_(mathematics) The number 0 is the additive identity (identity element for the binary operation of addition) for integers, real numbers, and complex numbers. For every number a, including 0 itself, In a more general context, when a binary operation is denoted with + and has an identity, this identity is commonly denoted by the symbol 0 (zero) and called an additive identity. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ecreed at cs.washington.edu Wed Apr 9 14:10:18 2014 From: ecreed at cs.washington.edu (Eric Reed) Date: Wed, 9 Apr 2014 14:10:18 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> Message-ID: I think part of the confusion here is that "matrix addition" isn't actually a binary operator, but rather a family of binary operators parametrized over the matrix dimensions. There's +<2,2> for 2 x 2 matrices, +<2,3> for 2 x 3 matrices, etc. Similarly, the "zero matrix" is actually parametrized over dimensions. 0<2,2> is different from 0<2,3>. For any n,m: + has the identity 0. If we wanted to properly represent that in Rust, we would need type level naturals that we could parametrize Matrix over. Regarding the range thing, I thought for a minute that it might make sense if we required Mul+One+Add+Zero to be a ring (which is the intention I think), but I don't think that's actually true in general for rings (i.e. that 1 is a generating set of the underlying group). On Wed, Apr 9, 2014 at 1:42 PM, Kevin Ballard wrote: > The number 0 is the additive identity for numbers. But informally, the > additive identity for other things can be called "zero" without problem. > Heck, even the wikipedia page on Additive Identity uses this example for > groups: > > > Let (G, +) be a group and let 0 and 0' in G both denote additive > identities, so for any g in G, > > > > 0 + g = g = g + 0 and 0' + g = g = g + 0' > > It follows from the above that > > > > (0') = (0') + 0 = 0' + (0) = (0) > > Look at that, an additive identity for something other than a number, and > zero (0) is used to denote this additive identity. > > The only issue comes in when you define addition in multiple different > ways for a single type. Of course, right now I believe compiler bugs > prevent you from actually using multiple implementations of Add<> with > different type parameters for a given type, so this isn't actually a > problem right now. And when that bug is fixed, it's still reasonable to > consider Zero to be the additive identity for any addition where the > receiver type is the right-hand side of the addition. In other words, if > you define Add for Matrix, then the additive identity here is > Zero::, not Zero::. > > Regarding "You can't assign a zero to a 2x2 matrix", additive identity > does not require the ability to assign. And this is only a problem when > considering addition between disparate types. If you consider matrix > addition (e.g. 2x2 matrix + 2x2 matrix) then you certainly can assign the > additive identity back to one of the matrix values. > > let m: Matrix = Zero::zero(); > > looks fine to me. It produces a matrix m that, when added to any other > Matrix m', produces the same matrix m'. This is presumably a Matrix where > every element is 0. But again, this only makes sense if you've actually > defined Add for Matrix. > > Regardless, we've already made the decision not to go down numeric type > hierarchy hell. We're trying to keep a reasonable simple numeric hierarchy. > And part of that means using straightforward "lay-person" terms instead of > perhaps more precise mathematical names. As such, we have std::num::Zero as > the additive identity and std::num::One as the multiplicative identity. > > If you really want to complain about something, complain about > std::num::One being used for things other than multiplicative identity, > e.g. std::iter::range() uses Add and One to produce the next value in the > range. > > -Kevin > > On Apr 9, 2014, at 1:25 PM, Tommi Tissari wrote: > > >> On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > >> > >> Why? Zero is the additive identity. > > > > Zero is _an_ additive identity for numbers, but not for vectors or > matrices. > > > > use std::slice::Items; > > use std::iter::RandomAccessIterator; > > use std::num::Zero; > > > > Items is a RandomAccessIterator, but a RandomAccessIterator is not an > Items. 0 is an additive identity, but an additive identity is not 0. You > can't assign a zero to a 2x2 matrix, and therefore this trait is > incorrectly named. The following just looks wrong: > > > > let m: Matrix = Zero::zero(); > > > >> AdditiveIdentity is the only reasonable alternative, but that's a > mouthful of a name and I think changing the name to this would be more > confusing. > > > > Naming a trait something that it's not is even more confusing. I don't > think we should give an incorrect name to this trait on the grounds of the > correct name being longer. Just look at RandomAccessIterator. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Wed Apr 9 14:22:10 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 9 Apr 2014 14:22:10 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> Message-ID: <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> FWIW, my point about range is it relies on One being the number 1, rather than being the multiplicative identity. AFAIK there's nothing special about 1 in a ring outside of its status as a multiplicative identity. Certainly it's not considered some special value for addition. As an example as to why this usage is weird, range(0f32, 10f32) actually is defined, and will produce [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. Similarly, range(0.5f32, 10f32) is defined and will produce [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]. This is technically a mis-use of One, but it just happens to produce reasonable values. Of course, if you use it on, say, a 2x2 matrix that defines Add, defines One as {{1,0},{0,1}} (the multiplicative identity), and also has some arbitrary definition of Ord, then range() would operate over this matrix and produce very weird results. For example, range(matrix![[1,2],[3,4]], matrix![10,10],[10,10]]) might, depending on the Ord definition, produce [matrix![[1,2],[3,4]], matrix![[2,2],[3,5]], matrix![[3,2],[3,6]], ...]. You can see that this is a nonsensical range (not that I think there is a way to define range for matrices that makes any sense). In any case, my overall point is Zero and One are more practical names than AdditiveIdentity and MultiplicativeIdentity. If we wanted a proper, accurate numeric hierarchy, we'd use the latter. But libstd wants a practical, shallow hierarchy. And there's certainly nothing stopping you from defining a separate libnumerics that provides an accurate mathematica numeric hierarchy (this is probably something that would be useful to have, but libstd doesn't want it because it's really easy to get wrong, e.g. I believe Haskell thinks their numeric hierarchy was a mistake). -Kevin On Apr 9, 2014, at 2:10 PM, Eric Reed wrote: > I think part of the confusion here is that "matrix addition" isn't actually a binary operator, but rather a family of binary operators parametrized over the matrix dimensions. There's +<2,2> for 2 x 2 matrices, +<2,3> for 2 x 3 matrices, etc. Similarly, the "zero matrix" is actually parametrized over dimensions. 0<2,2> is different from 0<2,3>. For any n,m: + has the identity 0. If we wanted to properly represent that in Rust, we would need type level naturals that we could parametrize Matrix over. > > Regarding the range thing, I thought for a minute that it might make sense if we required Mul+One+Add+Zero to be a ring (which is the intention I think), but I don't think that's actually true in general for rings (i.e. that 1 is a generating set of the underlying group). > > > On Wed, Apr 9, 2014 at 1:42 PM, Kevin Ballard wrote: > The number 0 is the additive identity for numbers. But informally, the additive identity for other things can be called "zero" without problem. Heck, even the wikipedia page on Additive Identity uses this example for groups: > > > Let (G, +) be a group and let 0 and 0' in G both denote additive identities, so for any g in G, > > > > 0 + g = g = g + 0 and 0' + g = g = g + 0' > > It follows from the above that > > > > (0') = (0') + 0 = 0' + (0) = (0) > > Look at that, an additive identity for something other than a number, and zero (0) is used to denote this additive identity. > > The only issue comes in when you define addition in multiple different ways for a single type. Of course, right now I believe compiler bugs prevent you from actually using multiple implementations of Add<> with different type parameters for a given type, so this isn't actually a problem right now. And when that bug is fixed, it's still reasonable to consider Zero to be the additive identity for any addition where the receiver type is the right-hand side of the addition. In other words, if you define Add for Matrix, then the additive identity here is Zero::, not Zero::. > > Regarding "You can't assign a zero to a 2x2 matrix", additive identity does not require the ability to assign. And this is only a problem when considering addition between disparate types. If you consider matrix addition (e.g. 2x2 matrix + 2x2 matrix) then you certainly can assign the additive identity back to one of the matrix values. > > let m: Matrix = Zero::zero(); > > looks fine to me. It produces a matrix m that, when added to any other Matrix m', produces the same matrix m'. This is presumably a Matrix where every element is 0. But again, this only makes sense if you've actually defined Add for Matrix. > > Regardless, we've already made the decision not to go down numeric type hierarchy hell. We're trying to keep a reasonable simple numeric hierarchy. And part of that means using straightforward "lay-person" terms instead of perhaps more precise mathematical names. As such, we have std::num::Zero as the additive identity and std::num::One as the multiplicative identity. > > If you really want to complain about something, complain about std::num::One being used for things other than multiplicative identity, e.g. std::iter::range() uses Add and One to produce the next value in the range. > > -Kevin > > On Apr 9, 2014, at 1:25 PM, Tommi Tissari wrote: > > >> On 09 Apr 2014, at 20:46, Kevin Ballard wrote: > >> > >> Why? Zero is the additive identity. > > > > Zero is _an_ additive identity for numbers, but not for vectors or matrices. > > > > use std::slice::Items; > > use std::iter::RandomAccessIterator; > > use std::num::Zero; > > > > Items is a RandomAccessIterator, but a RandomAccessIterator is not an Items. 0 is an additive identity, but an additive identity is not 0. You can't assign a zero to a 2x2 matrix, and therefore this trait is incorrectly named. The following just looks wrong: > > > > let m: Matrix = Zero::zero(); > > > >> AdditiveIdentity is the only reasonable alternative, but that's a mouthful of a name and I think changing the name to this would be more confusing. > > > > Naming a trait something that it's not is even more confusing. I don't think we should give an incorrect name to this trait on the grounds of the correct name being longer. Just look at RandomAccessIterator. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Wed Apr 9 21:50:07 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Thu, 10 Apr 2014 07:50:07 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> Message-ID: <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> > On 10 Apr 2014, at 00:22, Kevin Ballard wrote: > > FWIW, my point about range is it relies on One being the number 1, rather than being the multiplicative identity. AFAIK there's nothing special about 1 in a ring outside of its status as a multiplicative identity. Certainly it's not considered some special value for addition. Another problem with std::iter::range is that it requires too much from its argument type A by saying A must implement Add while it only returns a forward iterator. Perhaps, in order to make a more sensible implementation of iter::range, a new concept, a trait, is needed to be able to specify that a certain type T implements a method 'increment' that modifies a variable of type T from value x to value y such that: 1) x < y 2) there is no valid value z of type T satisfying x < z < y For integral types there would an implementation of this trait in stdlib with 'increment' doing x += 1; Then, a natural extension to this trait would be a trait that has a method 'advance(n: uint)' that would, at constant time, conceptually call the 'increment' method n times. Then there would also be a 'decrement' method for going the other direction. There probably needs to be some other use cases for this new trait to carry its weight though. From kevin at sb.org Wed Apr 9 21:53:42 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 9 Apr 2014 21:53:42 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> Message-ID: <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> On Apr 9, 2014, at 9:50 PM, Tommi Tissari wrote: >> On 10 Apr 2014, at 00:22, Kevin Ballard wrote: >> >> FWIW, my point about range is it relies on One being the number 1, rather than being the multiplicative identity. AFAIK there's nothing special about 1 in a ring outside of its status as a multiplicative identity. Certainly it's not considered some special value for addition. > > Another problem with std::iter::range is that it requires too much from its argument type A by saying A must implement Add while it only returns a forward iterator. > > Perhaps, in order to make a more sensible implementation of iter::range, a new concept, a trait, is needed to be able to specify that a certain type T implements a method 'increment' that modifies a variable of type T from value x to value y such that: > 1) x < y > 2) there is no valid value z of type T satisfying x < z < y > > For integral types there would an implementation of this trait in stdlib with 'increment' doing x += 1; > > Then, a natural extension to this trait would be a trait that has a method 'advance(n: uint)' that would, at constant time, conceptually call the 'increment' method n times. > > Then there would also be a 'decrement' method for going the other direction. > > There probably needs to be some other use cases for this new trait to carry its weight though. This trait would disallow range(0f32, 10f32) because there are quite a lot of valid values z of type f32 satisfying 0f32 < z < 1f32. -Kevin From corey at octayn.net Wed Apr 9 21:55:53 2014 From: corey at octayn.net (Corey Richardson) Date: Thu, 10 Apr 2014 00:55:53 -0400 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> Message-ID: range doesn't return a forward iterator. Range also implements DoubleEndedIterator. On Thu, Apr 10, 2014 at 12:53 AM, Kevin Ballard wrote: > On Apr 9, 2014, at 9:50 PM, Tommi Tissari wrote: > >>> On 10 Apr 2014, at 00:22, Kevin Ballard wrote: >>> >>> FWIW, my point about range is it relies on One being the number 1, rather than being the multiplicative identity. AFAIK there's nothing special about 1 in a ring outside of its status as a multiplicative identity. Certainly it's not considered some special value for addition. >> >> Another problem with std::iter::range is that it requires too much from its argument type A by saying A must implement Add while it only returns a forward iterator. >> >> Perhaps, in order to make a more sensible implementation of iter::range, a new concept, a trait, is needed to be able to specify that a certain type T implements a method 'increment' that modifies a variable of type T from value x to value y such that: >> 1) x < y >> 2) there is no valid value z of type T satisfying x < z < y >> >> For integral types there would an implementation of this trait in stdlib with 'increment' doing x += 1; >> >> Then, a natural extension to this trait would be a trait that has a method 'advance(n: uint)' that would, at constant time, conceptually call the 'increment' method n times. >> >> Then there would also be a 'decrement' method for going the other direction. >> >> There probably needs to be some other use cases for this new trait to carry its weight though. > > This trait would disallow range(0f32, 10f32) because there are quite a lot of valid values z of type f32 satisfying 0f32 < z < 1f32. > > -Kevin > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ From rusty.gates at icloud.com Wed Apr 9 23:20:24 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Thu, 10 Apr 2014 09:20:24 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> Message-ID: <5DE1B0BB-6A70-426B-A8D6-BC2D175D9056@icloud.com> > On 10 Apr 2014, at 07:53, Kevin Ballard wrote: > > On Apr 9, 2014, at 9:50 PM, Tommi Tissari wrote: > >>> On 10 Apr 2014, at 00:22, Kevin Ballard wrote: >>> >>> FWIW, my point about range is it relies on One being the number 1, rather than being the multiplicative identity. AFAIK there's nothing special about 1 in a ring outside of its status as a multiplicative identity. Certainly it's not considered some special value for addition. >> >> Another problem with std::iter::range is that it requires too much from its argument type A by saying A must implement Add while it only returns a forward iterator. >> >> Perhaps, in order to make a more sensible implementation of iter::range, a new concept, a trait, is needed to be able to specify that a certain type T implements a method 'increment' that modifies a variable of type T from value x to value y such that: >> 1) x < y >> 2) there is no valid value z of type T satisfying x < z < y >> >> For integral types there would an implementation of this trait in stdlib with 'increment' doing x += 1; >> >> Then, a natural extension to this trait would be a trait that has a method 'advance(n: uint)' that would, at constant time, conceptually call the 'increment' method n times. >> >> Then there would also be a 'decrement' method for going the other direction. >> >> There probably needs to be some other use cases for this new trait to carry its weight though. > > This trait would disallow range(0f32, 10f32) because there are quite a lot of valid values z of type f32 satisfying 0f32 < z < 1f32. > > -Kevin The trait wouldn't disallow, but it would change the meaning of such range. From rusty.gates at icloud.com Wed Apr 9 23:25:16 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Thu, 10 Apr 2014 09:25:16 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> Message-ID: <8D92DC85-8C0D-4DFF-9DB9-127DB495C69E@icloud.com> > On 10 Apr 2014, at 07:55, Corey Richardson wrote: > > range doesn't return a forward iterator. Range also implements > DoubleEndedIterator. Ok, I didn't realize that. But it still should't require Add when all it needs is a way to get to the next and previous values. From kevin at sb.org Wed Apr 9 23:27:58 2014 From: kevin at sb.org (Kevin Ballard) Date: Wed, 9 Apr 2014 23:27:58 -0700 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <8D92DC85-8C0D-4DFF-9DB9-127DB495C69E@icloud.com> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> <8D92DC85-8C0D-4DFF-9DB9-127DB495C69E@icloud.com> Message-ID: <26D4A795-2523-49BB-AAF4-8D2ADC7AC434@sb.org> On Apr 9, 2014, at 11:25 PM, Tommi Tissari wrote: >> On 10 Apr 2014, at 07:55, Corey Richardson wrote: >> >> range doesn't return a forward iterator. Range also implements >> DoubleEndedIterator. > > Ok, I didn't realize that. But it still should't require Add when all it needs is a way to get to the next and previous values. Any such trait for this would really need to be designed expressly for Range, and then reimplemented for every single numeric type. -Kevin -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4118 bytes Desc: not available URL: From rusty.gates at icloud.com Thu Apr 10 00:54:09 2014 From: rusty.gates at icloud.com (Tommi Tissari) Date: Thu, 10 Apr 2014 10:54:09 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <26D4A795-2523-49BB-AAF4-8D2ADC7AC434@sb.org> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <3CC52697-D0D8-4207-8655-6F372AE9DFEB@sb.org> <0820521E-A850-4EC5-8A85-0C974E5F7EBE@icloud.com> <180AA793-062C-4E6A-9AB4-81B7CD0D2736@sb.org> <8D92DC85-8C0D-4DFF-9DB9-127DB495C69E@icloud.com> <26D4A795-2523-49BB-AAF4-8D2ADC7AC434@sb.org> Message-ID: <081E43FF-7F59-41ED-9B14-D8AB0A0F8062@icloud.com> A nice side-effect of using such a trait as a bound to the range argument type A is that the meaning of iter::range(a, b) would become coherent (same regardless of A) and more intuitive: returns a DoubleEndedIterator to all the possible (and valid) values of type A in [a, b) in ascending order. > On 10 Apr 2014, at 09:27, Kevin Ballard wrote: > > On Apr 9, 2014, at 11:25 PM, Tommi Tissari wrote: > >>> On 10 Apr 2014, at 07:55, Corey Richardson wrote: >>> >>> range doesn't return a forward iterator. Range also implements >>> DoubleEndedIterator. >> >> Ok, I didn't realize that. But it still should't require Add when all it needs is a way to get to the next and previous values. > > Any such trait for this would really need to be designed expressly for Range, and then reimplemented for every single numeric type. > > -Kevin From philippe.delrieu at free.fr Thu Apr 10 01:40:07 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Thu, 10 Apr 2014 10:40:07 +0200 Subject: [rust-dev] Some help needed in Vector of enum conversion In-Reply-To: <5345A54F.6080704@free.fr> References: <533F18DD.5040803@free.fr> <534193E4.5080800@free.fr> <53428957.2080500@free.fr> <5345A54F.6080704@free.fr> Message-ID: <534658E7.2020607@free.fr> I trying to do some polymorphism with trait and object and I have some problems. At the beginning I want to store different types of object that implement the same trait (Base) in a Vec. To do this I use the enum pattern. If the enum contains only struct, I manage to iter the Vec for the different types. code: enum BaseImpl { FirstThinkImpl(FirstThink), SecondThinkImpl(SecondThink), } What I would like to do is to have a generic method to add like addMyBaseTrait( ~Base) to add all the struct that implement Base to the vector and to have a specific method that add a specific struct addSecondStruct(~SecondStruct). The enum is changed to: enum BaseImpl { FirstThinkImpl(~Base), SecondThinkImpl(~SecondThink), } With this enum has have problem to iter the vector. I didn't find a way to iter all the vector and return &Base or &~Base: this code impl<'a> Iterator<&'a ~Base> for BaseItems<'a> { fn next(&mut self) -> Option<&'a ~Base> { match self.iter.next() { Some(ref baseimpl) => { Some(match ***baseimpl{ FirstThinkImpl(ref first) => first, SecondThinkImpl(ref second)=> &'a (*second as ~Base), }) }, None => None, } } } generate an error borrowed value does not live long enough SecondThinkImpl(ref second)=> &'a (*second as ~Base), which is logic so I try not to borrow with this code: SecondThinkImpl(ref second)=> second as &'a ~Base, and I have the error non-scalar cast: `&~SecondThink` as `&'a ~Base` Perhaps there is no way. I didn't find any. What I see with all my test is that a trait must be use as a reference to be stored but object reference can't be cast to a reference trait and trait can't be cast to an object. So it seems that tray is useful to pass or return parameters to method but not to store data. Philippe Le 09/04/2014 21:53, Philippe Delrieu a ?crit : > I find a solution by removing the ~ to Base trait. > The code > > //(First and Second think as defined earlier) > > > enum BaseImpl { > FirstThinkImpl(FirstThink), > SecondThinkImpl(SecondThink), > } > > > struct Container { > nodeList: Vec<~BaseImpl>, > } > > impl<'a> Container { > > fn iter_base(&'a self) -> BaseItems<'a> { > let iter = self.nodeList.iter(); > BaseItems{ iter : iter } > } > > } > > > struct BaseItems<'a> { > iter : Items<'a, ~BaseImpl> > } > > impl<'a> Iterator<&'a Base> for BaseItems<'a> { > fn next(&mut self) -> Option<&'a Base> { > match self.iter.next() { > Some(ref baseimpl) => { > Some(match ***baseimpl{ > FirstThinkImpl(ref first) => first as &'a Base, > SecondThinkImpl(ref second)=> second as &'a Base, > }) > }, > None => None, > } > } > } > > Now it compile. > > So I try to define a mutable iterator like the immuable and with > similar code I have again the lifetime compile error : > > > struct BaseMutItems<'a> { > iter : MutItems<'a, ~BaseImpl> > } > > impl<'a> Iterator<&'a mut Base> for BaseMutItems<'a> { > fn next(&mut self) -> Option<&'a mut Base> { > match self.iter.next() { > Some(ref mut baseimpl) => { > Some(match ***baseimpl{ > FirstThinkImpl(ref mut first) => first as &'a mut > Base, > SecondThinkImpl(ref mut second)=> second as &'a > mut Base, > }) > }, > None => None, > } > } > } > > error : > test_enum.rs:125:36: 125:49 error: lifetime of `baseimpl` is too short > to guarantee its contents can be safely reborrowed > test_enum.rs:125 FirstThinkImpl(ref mut first) => > first as &'a mut Base, > > I can't see what's going wrong. > > > I put all the code if someone want to test : > > use std::iter::Iterator; > use std::slice::{Items, MutItems}; > > trait Base { > fn set_something(&mut self); > fn isSecondThink(&self) -> bool; > } > > struct FirstThink{ > count1: int, > } > > impl Base for FirstThink { > fn set_something(&mut self) {println!("ici First count:{:?}", > self.count1); self.count1+=1;} > fn isSecondThink(&self) -> bool {false} > } > > struct SecondThink{ > count2: int, > } > > impl Base for SecondThink { > fn set_something(&mut self) {println!("ici Second count:{:?}", > self.count2); self.count2+=1;} > fn isSecondThink(&self) -> bool {true} > } > > enum BaseImpl { > FirstThinkImpl(FirstThink), > SecondThinkImpl(SecondThink), > } > > fn some_second_process(think: &mut SecondThink) { > think.set_something(); > } > > struct Container { > nodeList: Vec<~BaseImpl>, > } > > impl<'a> Container { > fn add_FirstThink(&mut self, think: FirstThink) { > self.nodeList.push(~FirstThinkImpl(think)); > } > fn add_SecondThink(&mut self, think: SecondThink) { > self.nodeList.push(~SecondThinkImpl(think)); > } > > > fn iter_base(&'a self) -> BaseItems<'a> { > let iter = self.nodeList.iter(); > BaseItems{ iter : iter } > } > > fn iter_second(&'a self) -> SecondItems<'a> { > let iter = self.nodeList.iter(); > SecondItems{ iter : iter } > } > > fn mut_iter_base(&'a mut self) -> BaseMutItems<'a> { > let iter = self.nodeList.mut_iter(); > BaseMutItems{ iter : iter } > } > > fn appli_secondthink_someprocess(&mut self, fct : fn (&mut > SecondThink)) { > for think in self.nodeList.mut_iter() { > match **think { > FirstThinkImpl(first) => println!(""), > SecondThinkImpl(ref mut second)=> fct(second), > } > } > > } > > } > > struct BaseItems<'a> { > iter : Items<'a, ~BaseImpl> > } > > impl<'a> Iterator<&'a Base> for BaseItems<'a> { > fn next(&mut self) -> Option<&'a Base> { > match self.iter.next() { > Some(ref baseimpl) => { > Some(match ***baseimpl{ > FirstThinkImpl(ref first) => first as &'a Base, > SecondThinkImpl(ref second)=> second as &'a Base, > }) > }, > None => None, > } > } > } > > > struct SecondItems<'a> { > iter : Items<'a, ~BaseImpl> > } > > impl<'a> Iterator<&'a SecondThink> for SecondItems<'a> { > fn next(&mut self) -> Option<&'a SecondThink> { > match self.iter.next() { > Some(ref baseimpl) => { > match ***baseimpl{ > FirstThinkImpl(ref first) => self.next(), > SecondThinkImpl(ref second)=> Some(second), > } > }, > None => None, > } > } > } > > > struct BaseMutItems<'a> { > iter : MutItems<'a, ~BaseImpl> > } > > impl<'a> Iterator<&'a mut Base> for BaseMutItems<'a> { > fn next(&mut self) -> Option<&'a mut Base> { > match self.iter.next() { > Some(ref mut baseimpl) => { > Some(match ***baseimpl{ > FirstThinkImpl(ref mut first) => first as &'a mut > Base, > SecondThinkImpl(ref mut second)=> second as &'a > mut Base, > }) > }, > None => None, > } > } > } > > > > #[main] > fn main() { > let first = FirstThink{count1:0}; > let second = SecondThink{count2:0}; > > let mut container = Container{nodeList: Vec::new()}; > container.add_FirstThink(first); > container.add_SecondThink(second); > container.appli_secondthink_someprocess(some_second_process); > container.appli_secondthink_someprocess(some_second_process); > for think in container.iter_base() { > println!("ici Second count:{:?}", think.isSecondThink()); > } > > for think in container.iter_second() { > println!("ici Second count:{:?}", think.isSecondThink()); > } > container.appli_secondthink_someprocess(some_second_process); > } > > Le 07/04/2014 13:17, Philippe Delrieu a ?crit : >> I try to implement the iterator like that: >> >> >> struct BaseItems<'a> { >> iter : Items<'a, ~BaseImpl> >> } >> >> impl<'a> Iterator<&'a ~Base> for BaseItems<'a> { >> fn next(&mut self) -> Option<&'a ~Base> { >> match self.iter.next() { >> Some(ref baseimpl) => { >> Some(&'a match ***baseimpl{ >> FirstThinkImpl(ref first) => *first as ~Base, >> SecondThinkImpl(ref second)=> *second as ~Base, >> }) >> }, >> None => None, >> } >> } >> } >> >> But I have a lifetime problem. The error is : borrowed value does not >> live long enough and reference must be valid for the lifetime &'a as >> defined on the block >> and : >> cannot move out of dereference of `&`-pointer SecondThinkImpl(ref >> second)=> *second as ~Base, >> >> Another possibility: >> fn next(&mut self) -> Option<&'a ~Base> { >> match self.iter.next() { >> Some(ref baseimpl) => { >> Some(match ***baseimpl{ >> FirstThinkImpl(ref first) => first as &'a ~Base, >> SecondThinkImpl(ref second)=> second as &'a >> ~Base, >> }) >> }, >> None => None, >> } >> } >> generate the error: non-scalar cast: `&~FirstThink` as `&'a >> ~Base` >> >> I try different possibility but I didn't find how to return a <'a> >> lifetime ~Base or Base >> >> I remove the mut to simplify the test of the different lifetime >> possibilities. >> >> Philippe >> >> Le 07/04/2014 10:27, Rodrigo Rivas a ?crit : >>> On Sun, Apr 6, 2014 at 7:50 PM, Philippe Delrieu >>> wrote: >>>> I need some more help. >>>> >>>> The impl Iterator<&mut ~Base> for Container declaration generate >>>> the error: >>>> error: missing lifetime specifier >>>> So I had it but I can't manage to return the next value with the >>>> specified >>>> life time. >>>> The code : >>>> impl<'a> Iterator<&'a mut ~Base> for Container { >>>> /// Advance the iterator and return the next value. Return >>>> `None` when >>>> the end is reached. >>>> fn next(&mut self) -> Option<&'a mut ~Base> { >>>> if self.iter_counter == self.nodeList.len() { >>>> None >>>> } else { >>>> self.iter_counter += 1; >>>> Some(&'a mut match >>>> **self.nodeList.get(self.iter_counter){ >>>> FirstThinkImpl(first) => first as ~Base, >>>> SecondThinkImpl(second)=> second as ~Base, >>>> }) >>>> } >>>> } >>>> } >>>> >>>> Generate these errors : >>>> test_enum.rs:58:18: 61:14 error: borrowed value does not live long >>>> enough >>>> test/test_enum.rs:58 Some(&'a mut match >>> Oh, I think I may have misleaded you... You cannot implement the >>> iterator directly in Container, because the iterator must handle the >>> current position, while the Container just holds the values. You need >>> a intermediate struct that implements the Iterator traits. That's what >>> the `iter()` and ' move_iter()` functions do for vectors and other >>> standard containers. So you'll need something along the lines of this >>> (disclaimer: totally untested!!): >>> >>> struct Container { >>> //.... >>> fn iter(&'a self) -> BaseItems<'a> { >>> let iter = nodeList.iter(); >>> BaseItems{ iter : iter } >>> } >>> } >>> >>> struct BaseItems<'a> { >>> iter : Items<'a, ~Base> >>> } >>> >>> impl<'a> Iterator<&'a mut ~Base> for BaseItems<'a> { >>> //.... >>> } >>> >>> BTW, why all the double pointer in all the "&mut ~Base" instead of >>> just "&mut Base"? >>> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > From rusty.gates at icloud.com Thu Apr 10 06:07:35 2014 From: rusty.gates at icloud.com (Tommi) Date: Thu, 10 Apr 2014 16:07:35 +0300 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <5EE41BA2-ABB8-4CA9-B140-71E1AD06A672@icloud.com> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <5EE41BA2-ABB8-4CA9-B140-71E1AD06A672@icloud.com> Message-ID: <93C7C2A5-497D-491F-B726-A69B34B703FE@icloud.com> Actually, I'd like to reiterate my original view that num::Zero should be renamed to AdditiveIdentity (bear with me) based on the fact that when mathematicians use the symbol 0 to denote additive identity, the symbol 0 is not read "zero", but as "additive identity". All the reasoning above applies to renaming num::One to MultiplicativeIdentity as well (as it pertains to symbol 1 denoting multiplicative identity). If those names are too long, the shortened AddIdentity and MulIdentity could be used instead. > On 10 Apr 2014, at 00:06, Tommi Tissari wrote: > >> On 09 Apr 2014, at 23:42, Kevin Ballard wrote: >> >> The number 0 is the additive identity for numbers. But informally, the additive identity for other things can be called "zero" without problem. > > Ok, so it seems. From > http://en.m.wikipedia.org/wiki/Identity_(mathematics) > > The number 0 is the additive identity (identity element for the binary operation of addition) for integers, real numbers, and complex numbers. For every number a, including 0 itself, > > > In a more general context, when a binary operation is denoted with + and has an identity, this identity is commonly denoted by the symbol 0 (zero) and called an additive identity. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From philippe.delrieu at free.fr Thu Apr 10 11:23:08 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Thu, 10 Apr 2014 20:23:08 +0200 Subject: [rust-dev] does not fulfill `Send` error since last pull request Message-ID: <5346E18C.8020607@free.fr> Since my last today gill fetch I have this error: error: instantiating a type parameter with an incompatible type `~BaseImpl`, which does not fulfill `Send` for this code : trait Base{} struct SecondThink{ count2: int, } enum BaseImpl { FirstThinkImpl(~Base), SecondThinkImpl(~SecondThink), } let (newchan, newport): (Sender, Receiver) = channel(); <-- error here ^~~~~~~ The Send behavior has changed? Is it permanent and if yes is there a work around? Philippe From alex at crichton.co Thu Apr 10 11:28:46 2014 From: alex at crichton.co (Alex Crichton) Date: Thu, 10 Apr 2014 11:28:46 -0700 Subject: [rust-dev] does not fulfill `Send` error since last pull request In-Reply-To: <5346E18C.8020607@free.fr> References: <5346E18C.8020607@free.fr> Message-ID: Your BaseImpl enum isn't necessarily Send because it contains a trait object (~Base). The typechecker doesn't know what type is behind this trait object, so it doesn't know whether it's send or not. To make the BaseImpl type Send again, you can change the definition to: enum BaseImpl { FirstThinkImpl(~Base:Send), // note the ":Send" SecondThinkImpl(~SecondThink), } This error message should get much better with opt-in bounds [1] as it will point exactly at what's not Send. [1] - https://github.com/rust-lang/rfcs/blob/master/active/0003-opt-in-builtin-traits.md as On Thu, Apr 10, 2014 at 11:23 AM, Philippe Delrieu wrote: > Since my last today gill fetch I have this error: > > error: instantiating a type parameter with an incompatible type `~BaseImpl`, > which does not fulfill `Send` > > for this code : > trait Base{} > > struct SecondThink{ > count2: int, > } > > enum BaseImpl { > FirstThinkImpl(~Base), > SecondThinkImpl(~SecondThink), > } > > let (newchan, newport): (Sender, Receiver) = channel(); > <-- error here > ^~~~~~~ > The Send behavior has changed? Is it permanent and if yes is there a work > around? > > Philippe > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From hack3rcon at yahoo.com Thu Apr 10 11:35:30 2014 From: hack3rcon at yahoo.com (Jason Long) Date: Thu, 10 Apr 2014 11:35:30 -0700 (PDT) Subject: [rust-dev] About Rust programming language. Message-ID: <1397154930.11401.YahooMailNeo@web120404.mail.ne1.yahoo.com> Hello Folks. How are you? I want to know something about Rust language and Is it C killer? I mean is that in the future is it a replacement for C? Cheers. -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Thu Apr 10 05:13:26 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Thu, 10 Apr 2014 13:13:26 +0100 Subject: [rust-dev] Debugging with Rust 0.11 nightly Message-ID: Previously I would have debugged using the command "rustc -Z debug-info example.rs". However with Rust 0.11 nightly it does not work. What do I replace the above command with? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Apr 10 11:58:31 2014 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 10 Apr 2014 11:58:31 -0700 Subject: [rust-dev] About Rust programming language. In-Reply-To: <1397154930.11401.YahooMailNeo@web120404.mail.ne1.yahoo.com> References: <1397154930.11401.YahooMailNeo@web120404.mail.ne1.yahoo.com> Message-ID: <5346E9D7.5020908@mozilla.com> Thank you for your interest, but this is not a constructive topic for this venue. On 04/10/2014 11:35 AM, Jason Long wrote: > Hello Folks. > How are you? > I want to know something about Rust language and Is it C killer? I mean > is that in the future is it a replacement for C? > > Cheers. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From corey at octayn.net Thu Apr 10 11:59:42 2014 From: corey at octayn.net (Corey Richardson) Date: Thu, 10 Apr 2014 14:59:42 -0400 Subject: [rust-dev] Debugging with Rust 0.11 nightly In-Reply-To: References: Message-ID: -g, or --debuginfo (0|1|2) will generate debuginfo. -g means --debuginfo 2. see rustc --help for more details. On Thu, Apr 10, 2014 at 8:13 AM, Artella Coding wrote: > Previously I would have debugged using the command "rustc -Z debug-info > example.rs". However with Rust 0.11 nightly it does not work. What do I > replace the above command with? Thanks. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- http://octayn.net/ From banderson at mozilla.com Thu Apr 10 12:01:46 2014 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 10 Apr 2014 12:01:46 -0700 Subject: [rust-dev] About Rust programming language. In-Reply-To: <5346E9D7.5020908@mozilla.com> References: <1397154930.11401.YahooMailNeo@web120404.mail.ne1.yahoo.com> <5346E9D7.5020908@mozilla.com> Message-ID: <5346EA9A.2010808@mozilla.com> Sorry for the curt response. The answer is that Rust is suitable for many of the same tasks as C. Thank you. Please do not have this discussion here. On 04/10/2014 11:58 AM, Brian Anderson wrote: > Thank you for your interest, but this is not a constructive topic for > this venue. > > On 04/10/2014 11:35 AM, Jason Long wrote: >> Hello Folks. >> How are you? >> I want to know something about Rust language and Is it C killer? I mean >> is that in the future is it a replacement for C? >> >> Cheers. >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From thadguidry at gmail.com Thu Apr 10 12:28:06 2014 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 10 Apr 2014 14:28:06 -0500 Subject: [rust-dev] About Rust programming language. In-Reply-To: <5346EA9A.2010808@mozilla.com> References: <1397154930.11401.YahooMailNeo@web120404.mail.ne1.yahoo.com> <5346E9D7.5020908@mozilla.com> <5346EA9A.2010808@mozilla.com> Message-ID: Much better 2nd response, Brian. More like a salesman. You want to pull them in ... not push them away :-) On Thu, Apr 10, 2014 at 2:01 PM, Brian Anderson wrote: > Sorry for the curt response. The answer is that Rust is suitable for many > of the same tasks as C. Thank you. > > Please do not have this discussion here. > > > On 04/10/2014 11:58 AM, Brian Anderson wrote: > >> Thank you for your interest, but this is not a constructive topic for >> this venue. >> >> On 04/10/2014 11:35 AM, Jason Long wrote: >> >>> Hello Folks. >>> How are you? >>> I want to know something about Rust language and Is it C killer? I mean >>> is that in the future is it a replacement for C? >>> >>> Cheers. >>> >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad +ThadGuidry Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Apr 10 17:05:58 2014 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 10 Apr 2014 17:05:58 -0700 Subject: [rust-dev] Rust windows bots have transitioned to mingw-w64 Message-ID: <534731E6.7090006@mozilla.com> After a long time coming, the Rust windows bots are now running an up-to-date mingw-w64 toolchain. This was a very easy transition thanks to the efforts of our windows devs, including Vadim, Thad, and klutzy. The practical impact of this is that windows developers should prefer the mingw-w64 toolchain to the old mingw toolchain. This is the toolchain we will be supporting on Windows for the immediate future. I've updated the [windows instructions] and the [getting started] page slightly, but there's a lot of information there that I don't fully understand. I'd appreciate if some of the more experienced windows devs could go over them and make sure they are accurate. The next step will be to add 64-bit windows bots and snapshots. [windows instructions]: https://github.com/mozilla/rust/wiki/Using-Rust-on-Windows [getting started]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust From cg.wowus.cg at gmail.com Thu Apr 10 17:36:45 2014 From: cg.wowus.cg at gmail.com (Clark Gaebel) Date: Thu, 10 Apr 2014 20:36:45 -0400 Subject: [rust-dev] Anyone in NYC? In-Reply-To: References: <5328C94A.7070407@mozilla.com> <4B2102CC-D884-48D9-B283-8E7EC40EA1C3@gmail.com> Message-ID: So this is happening now: http://www.meetup.com/nyccpp/events/168545012/ It's the C++ meetup, but I'll be giving a short talk on rust. Please RSVP before it fills up! - Clark On Wed, Mar 26, 2014 at 10:30 PM, Carter Schonwald < carter.schonwald at gmail.com> wrote: > I'm in NYC. > > ya'll should come to the nyc haskell hackathon, there'll be lots of folks > there who enjoy strongly typed systemsy code, tis april 4-6, all welcome! > www.haskell.org/haskellwiki/Hac_NYC > > > > On Wed, Mar 19, 2014 at 9:40 PM, Andrew Morrow wrote: > >> >> >> On Mar 18, 2014, at 8:27 PM, Clark Gaebel wrote: >> >> I'm not sure if we have enough people for a reasonable-sized meetup, but >> I wouldn't mind having a rust-themed meetup with nyccpp! I'll volunteer to >> give a short "sales pitch" presentation if you make this happen. >> >> - Clark >> >> >> Hi Clark - >> >> I'm sure we can find a way to make that work. The nyccpp meetup has three >> upcoming talks, but I think those are best left as single topic given the >> content. But I'd like to get a fourth talk on the calendar and I think a >> short rust sales pitch would be well received. >> >> Let's take this off list and see what we can put together. >> >> Thanks, >> Andrew >> >> >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > -- Clark. Key ID : 0x78099922 Fingerprint: B292 493C 51AE F3AB D016 DD04 E5E3 C36F 5534 F907 -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Thu Apr 10 18:46:44 2014 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 10 Apr 2014 20:46:44 -0500 Subject: [rust-dev] Rust windows bots have transitioned to mingw-w64 In-Reply-To: <534731E6.7090006@mozilla.com> References: <534731E6.7090006@mozilla.com> Message-ID: Ra Ra Ooo La La ! Good work team ! (looking forward to the 64-bit snapshots) On Thu, Apr 10, 2014 at 7:05 PM, Brian Anderson wrote: > After a long time coming, the Rust windows bots are now running an > up-to-date mingw-w64 toolchain. This was a very easy transition thanks to > the efforts of our windows devs, including Vadim, Thad, and klutzy. > > The practical impact of this is that windows developers should prefer the > mingw-w64 toolchain to the old mingw toolchain. This is the toolchain we > will be supporting on Windows for the immediate future. > > I've updated the [windows instructions] and the [getting started] page > slightly, but there's a lot of information there that I don't fully > understand. I'd appreciate if some of the more experienced windows devs > could go over them and make sure they are accurate. > > The next step will be to add 64-bit windows bots and snapshots. > > [windows instructions]: https://github.com/mozilla/ > rust/wiki/Using-Rust-on-Windows > [getting started]: https://github.com/mozilla/rust/wiki/Note-getting- > started-developing-Rust > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad +ThadGuidry Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From comexk at gmail.com Thu Apr 10 22:17:47 2014 From: comexk at gmail.com (comex) Date: Fri, 11 Apr 2014 01:17:47 -0400 Subject: [rust-dev] does not fulfill `Send` error since last pull request In-Reply-To: References: <5346E18C.8020607@free.fr> Message-ID: On Thu, Apr 10, 2014 at 2:28 PM, Alex Crichton wrote: > [1] - https://github.com/rust-lang/rfcs/blob/master/active/0003-opt-in-builtin-traits.md Off topic, but sigh... first private fields, now this to add even more verbosity to declaring a struct, which really should be a very low friction thing. Not the end of the world but I don't like it. From pcwalton at mozilla.com Fri Apr 11 09:57:41 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Fri, 11 Apr 2014 09:57:41 -0700 Subject: [rust-dev] does not fulfill `Send` error since last pull request In-Reply-To: References: <5346E18C.8020607@free.fr> Message-ID: <53481F05.9040508@mozilla.com> On 4/10/14 10:17 PM, comex wrote: > On Thu, Apr 10, 2014 at 2:28 PM, Alex Crichton wrote: >> [1] - https://github.com/rust-lang/rfcs/blob/master/active/0003-opt-in-builtin-traits.md > > Off topic, but sigh... first private fields, now this to add even more > verbosity to declaring a struct, which really should be a very low > friction thing. Not the end of the world but I don't like it. The API stability problem and the inability for us to add more bounds later are real issues though. (Not to mention the fact that I've spent a lot of time in Servo hunting down the one field that caused a big complex structure not to become `Send`. I've also had issues whereby commits in a large project sneak in that make structures that I wanted to remain sendable suddenly become not sendable, requiring awkward useless "assertion" functions that ensure that it doesn't happen in the future. These are potentially fixable in other ways, but it just seems cleaner to require structures opt in to the built-in traits.) Patrick From artella.coding at googlemail.com Fri Apr 11 07:05:23 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Fri, 11 Apr 2014 15:05:23 +0100 Subject: [rust-dev] Debugging : traversing code in libraries (rust 0.10 release) Message-ID: Suppose I have the following code : **************************************** extern crate rand; use rand::{task_rng, Rng}; fn main() { let names = ["Alice", "Bob", "Carol"]; for name in names.iter() { let v = task_rng().shuffle(~[1,2,3]); for num in v.iter() { println!("{:s} says: {:d}", *name, *num); } } } **************************************** Then I can put a breakpoint at shuffle by doing : rustc -g prog1.rs gdb ./prog1 rbreak shuffle run However at this point if I try to step into the shuffle function and list the code I get something like : **************************************** (gdb) where #0 0x0000000000404fe0 in Rng::shuffle_mut::h20bb47036b05fab8lja::v0.0 () #1 0x0000000000404f58 in Rng::shuffle::h5fded7dc864fa562Uia::v0.0 () #2 0x0000000000404634 in prog1::main () at prog1.rs:7 #3 0x000000000043e453 in start::closure.7865 () #4 0x00000000004d9263 in rt::task::Task::run::closure.41627 () #5 0x00000000004e47dc in rust_try () #6 0x00000000004d90c2 in rt::task::Task::run::h50a26072019a80d2fs9::v0.10 () #7 0x000000000043e244 in start::h4be0315ccbf00887zvd::v0.10 () #8 0x000000000043e034 in lang_start::he9dd0a0b44e890dcTud::v0.10 () #9 0x00000000004048bf in main () (gdb) list Line number 13 out of range; prog1.rs has 12 lines. **************************************** How can I step through the source of Rng::shuffle? I downloaded the source and when I did "./configure --help" I saw "--disable-optimize don't build optimized rust code". So do I need to build the source with this option? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From sulnedinfind at gmail.com Fri Apr 11 01:57:50 2014 From: sulnedinfind at gmail.com (Yegor Wienski) Date: Fri, 11 Apr 2014 14:57:50 +0600 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <93C7C2A5-497D-491F-B726-A69B34B703FE@icloud.com> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <5EE41BA2-ABB8-4CA9-B140-71E1AD06A672@icloud.com> <93C7C2A5-497D-491F-B726-A69B34B703FE@icloud.com> Message-ID: <3D72D976-8210-4ED9-87E5-BC804D93D095@gmail.com> All of the mathematicians I know won?t bother to read them this way (if there?s no ambiguity, of course). Long names can be good in scientific papers, but in practice one should be a complete boring jerk to name them like this. It would be a pain typing even the word ?identity? in a game engine over and over. I write for Unity3d, and Vector3.zero and Vector3.one are just fine, but Quaternion.identity makes code look too verbose, so I `static readonly QI = Quaternion.identity` it. Long names require special training to get comfortable with them, and sometimes it even looks like a superpower to me. On 10 Apr 2014, at 19:07, Tommi wrote: > Actually, I'd like to reiterate my original view that num::Zero should be renamed to AdditiveIdentity (bear with me) based on the fact that when mathematicians use the symbol 0 to denote additive identity, the symbol 0 is not read "zero", but as "additive identity". > > All the reasoning above applies to renaming num::One to MultiplicativeIdentity as well (as it pertains to symbol 1 denoting multiplicative identity). > > If those names are too long, the shortened AddIdentity and MulIdentity could be used instead. > > > On 10 Apr 2014, at 00:06, Tommi Tissari wrote: > >> On 09 Apr 2014, at 23:42, Kevin Ballard wrote: >> >>> The number 0 is the additive identity for numbers. But informally, the additive identity for other things can be called "zero" without problem. >> >> Ok, so it seems. From >> http://en.m.wikipedia.org/wiki/Identity_(mathematics) >> >> The number 0 is the additive identity (identity element for the binary operation of addition) for integers, real numbers, and complex numbers. For every number a, including 0 itself, >> >> In a more general context, when a binary operation is denoted with + and has an identity, this identity is commonly denoted by the symbol 0 (zero) and called an additive identity. >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri Apr 11 13:40:18 2014 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 11 Apr 2014 13:40:18 -0700 Subject: [rust-dev] Rust windows bots have transitioned to mingw-w64 In-Reply-To: <534731E6.7090006@mozilla.com> References: <534731E6.7090006@mozilla.com> Message-ID: <53485332.4090501@mozilla.com> It turns out this was premature and the bots are still using the old toolchain. I'll keep working on it. On 04/10/2014 05:05 PM, Brian Anderson wrote: > After a long time coming, the Rust windows bots are now running an > up-to-date mingw-w64 toolchain. This was a very easy transition thanks > to the efforts of our windows devs, including Vadim, Thad, and klutzy. > > The practical impact of this is that windows developers should prefer > the mingw-w64 toolchain to the old mingw toolchain. This is the > toolchain we will be supporting on Windows for the immediate future. > > I've updated the [windows instructions] and the [getting started] page > slightly, but there's a lot of information there that I don't fully > understand. I'd appreciate if some of the more experienced windows devs > could go over them and make sure they are accurate. > > The next step will be to add 64-bit windows bots and snapshots. > > [windows instructions]: > https://github.com/mozilla/rust/wiki/Using-Rust-on-Windows > [getting started]: > https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust From thadguidry at gmail.com Fri Apr 11 16:16:47 2014 From: thadguidry at gmail.com (Thad Guidry) Date: Fri, 11 Apr 2014 18:16:47 -0500 Subject: [rust-dev] Rust windows bots have transitioned to mingw-w64 In-Reply-To: <53485332.4090501@mozilla.com> References: <534731E6.7090006@mozilla.com> <53485332.4090501@mozilla.com> Message-ID: LOL. OK, and I'll keep me fingers crossed. ;) On Fri, Apr 11, 2014 at 3:40 PM, Brian Anderson wrote: > It turns out this was premature and the bots are still using the old > toolchain. I'll keep working on it. > > > On 04/10/2014 05:05 PM, Brian Anderson wrote: > >> After a long time coming, the Rust windows bots are now running an >> up-to-date mingw-w64 toolchain. This was a very easy transition thanks >> to the efforts of our windows devs, including Vadim, Thad, and klutzy. >> >> The practical impact of this is that windows developers should prefer >> the mingw-w64 toolchain to the old mingw toolchain. This is the >> toolchain we will be supporting on Windows for the immediate future. >> >> I've updated the [windows instructions] and the [getting started] page >> slightly, but there's a lot of information there that I don't fully >> understand. I'd appreciate if some of the more experienced windows devs >> could go over them and make sure they are accurate. >> >> The next step will be to add 64-bit windows bots and snapshots. >> >> [windows instructions]: >> https://github.com/mozilla/rust/wiki/Using-Rust-on-Windows >> [getting started]: >> https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad +ThadGuidry Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From erick.tryzelaar at gmail.com Fri Apr 11 17:47:53 2014 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Fri, 11 Apr 2014 17:47:53 -0700 Subject: [rust-dev] 5/8 SF Rust Meetup and 5/10 Hackathon: John Regehr: Testing Rust and Fuzzing Compilers Message-ID: Hello Rustilians! I'm pleased to announce our next Rust meetup on Thursday May 8 in San Francisco, which will be another double feature, focused on improving and automating Rust testing. Along with this meetup, there will also be a Testing Hackathon to be held on Saturday May 10st. Our main speaker Thursday night is Professor John Regehrfrom the University of Utah. His group is focused on developing new techniques to mechanically discover errors and missed optimizations. He will be speaking about how his team has made a testing fuzzer for the C language, and how we can apply those same techniques to the Rust compiler. Also speaking will be Andrew Gallant from the east coast, who will present his QuickCheck , Random property based testing with (hopefully) minimal witnesses. Agenda: ? 7:00pm - Doors open ? 8:00pm - Plans for the Testing Hackathon ? 8:15pm - John Regehr ? 9:15pm - Andrew Gallant As always, Mozilla will be graciously providing food and drink. If you would like to attend, sign up here: Meetup: http://www.meetup.com/Rust-Bay-Area/events/169434302/ Hackathon: http://www.meetup.com/Rust-Bay-Area/events/168373782/ I hope you can all make it! -Erick -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri Apr 11 18:33:01 2014 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 11 Apr 2014 18:33:01 -0700 Subject: [rust-dev] Rust windows bots have transitioned to mingw-w64 In-Reply-To: References: <534731E6.7090006@mozilla.com> <53485332.4090501@mozilla.com> Message-ID: <534897CD.6060608@mozilla.com> I have a new bot up now that is *definitely* using the new toolchain. Haven't completed a build yet, but I think it's going to work. On 04/11/2014 04:16 PM, Thad Guidry wrote: > LOL. OK, and I'll keep me fingers crossed. ;) > > > On Fri, Apr 11, 2014 at 3:40 PM, Brian Anderson > wrote: > > It turns out this was premature and the bots are still using the old > toolchain. I'll keep working on it. > > > On 04/10/2014 05:05 PM, Brian Anderson wrote: > > After a long time coming, the Rust windows bots are now running an > up-to-date mingw-w64 toolchain. This was a very easy transition > thanks > to the efforts of our windows devs, including Vadim, Thad, and > klutzy. > > The practical impact of this is that windows developers should > prefer > the mingw-w64 toolchain to the old mingw toolchain. This is the > toolchain we will be supporting on Windows for the immediate future. > > I've updated the [windows instructions] and the [getting > started] page > slightly, but there's a lot of information there that I don't fully > understand. I'd appreciate if some of the more experienced > windows devs > could go over them and make sure they are accurate. > > The next step will be to add 64-bit windows bots and snapshots. > > [windows instructions]: > https://github.com/mozilla/__rust/wiki/Using-Rust-on-__Windows > > [getting started]: > https://github.com/mozilla/__rust/wiki/Note-getting-__started-developing-Rust > > > > _________________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/__listinfo/rust-dev > > > > > > -- > -Thad > +ThadGuidry > Thad on LinkedIn From remifontan at yahoo.fr Fri Apr 11 20:51:02 2014 From: remifontan at yahoo.fr (=?UTF-8?B?UsOpbWkgRm9udGFu?=) Date: Sat, 12 Apr 2014 15:51:02 +1200 Subject: [rust-dev] impl num::Zero and std::ops::Add error In-Reply-To: <3D72D976-8210-4ED9-87E5-BC804D93D095@gmail.com> References: <30FC0937-ECB8-454A-89D5-0A663C0512F6@icloud.com> <4F54B301-017F-420E-B1DE-9A0B14D7E51C@icloud.com> <88987DD3-828C-4C67-AF8E-FBAB4C309328@sb.org> <6FA059F5-49AA-4408-B364-F8BEDDB08A84@sb.org> <5BFD2E65-2DCD-46D9-A279-932B165D01B9@sb.org> <5EE41BA2-ABB8-4CA9-B140-71E1AD06A672@icloud.com> <93C7C2A5-497D-491F-B726-A69B34B703FE@icloud.com> <3D72D976-8210-4ED9-87E5-BC804D93D095@gmail.com> Message-ID: at some point, I conveniently used num::one and num::zero to write expressions in template code. here's a simple example. pub fn powerCosHemispherePdfW(aNormal: &Vec3x, aDirection: &Vec3x, aPower:T ) -> T { let cosTheta = num::max(num::zero::(), Vec3x::dot(aNormal, aDirection)); return (aPower + num::one::()) * num::pow(cosTheta, aPower) * (num::cast::(0.5) * num::Real::frac_1_pi()); } I already find using num::zero in that code not ideal regarding to readability, so renaming additiveIdentity even worse. it is very possible that the code above could be re-written in a better way and I would love to find out how. perhaps there is enough room in rust for both simple traits such as zero and one, and for more advanced mathematical traits such as additive identity and multiplicative identity. R?mi On Fri, Apr 11, 2014 at 8:57 PM, Yegor Wienski wrote: > All of the mathematicians I know won?t bother to read them this way (if > there?s no ambiguity, of course). Long names can be good in scientific > papers, but in practice one should be a complete boring jerk to name them > like this. > It would be a pain typing even the word ?identity? in a game engine over > and over. I write for Unity3d, and Vector3.zero and Vector3.one are just > fine, but Quaternion.identity makes code look too verbose, so I `static > readonly QI = Quaternion.identity` it. > Long names require special training to get comfortable with them, and > sometimes it even looks like a superpower to me. > > > On 10 Apr 2014, at 19:07, Tommi wrote: > > Actually, I'd like to reiterate my original view that num::Zero should be > renamed to AdditiveIdentity (bear with me) based on the fact that when > mathematicians use the symbol 0 to denote additive identity, the symbol 0 > is not read "zero", but as "additive identity". > > All the reasoning above applies to renaming num::One to > MultiplicativeIdentity as well (as it pertains to symbol 1 denoting > multiplicative identity). > > If those names are too long, the shortened AddIdentity and MulIdentity > could be used instead. > > > On 10 Apr 2014, at 00:06, Tommi Tissari wrote: > > On 09 Apr 2014, at 23:42, Kevin Ballard wrote: > > The number 0 is the additive identity for numbers. But informally, the > additive identity for other things can be called "zero" without problem. > > > Ok, so it seems. From > http://en.m.wikipedia.org/wiki/Identity_(mathematics) > > The number *0* is the *additive identity* (identity element for the > binary operation of addition) for integers, real numbers, and complex > numbers. For every number *a*, including 0 itself, > [image: 0 + a = a+0=a\,.] > In a more general context, when a binary operation is denoted with + and > has an identity, this identity is commonly denoted by the symbol 0 (zero) > and called an *additive identity*. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- R?mi Fontan : remifontan at yahoo.fr mobile: +64 21 855 351 93 Otaki Street, Miramar 6022 Wellington, New Zealand -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeremycong at gmail.com Sat Apr 12 02:04:31 2014 From: jeremycong at gmail.com (Jeremy Ong) Date: Sat, 12 Apr 2014 02:04:31 -0700 Subject: [rust-dev] [discussion] preemptive scheduling Message-ID: I am considering authoring a webserver (think nginx, apache, cowboy, etc) in Rust. From a user point of view, mapping tasks (green) to web requests makes the most sense as the tasks could be long running, perform their own I/O, sessions, or what have you. It would also allow the user to do per-request in memory caching. My main concern is obviously the cooperative scheduler. Given that the mantra of Rust seems to be safety, I'm curious about how feasible it would be to provide the option for task safety as well. Preemptive scheduling provides two things: 1. If preemption is used aggressively, the user can opt for a lower latency system (a la Erlang style round robin preemptive scheduling) 2. Preemption of any sort can be used as a safety net to isolate bugs or blocks in tasks for long running systems, or at least mitigate damage until the developer intervenes. I noticed in issue 5731[1] on the repo, it was pointed out that this was possible, albeit difficult. The issue was closed with a comment that the user should use OS threads instead. I really think this misses the point as it no longer allows preemption on a smaller granularity scale. Could any devs chime in on the scope and difficulty of this project? Could any users/devs chime in on any of the points above? tl;dr I think preemptive scheduling is a must for safe concurrency in long running executables at the bottom of the stack. Opinions? [1] https://github.com/mozilla/rust/issues/5731 From matthieu.monrocq at gmail.com Sat Apr 12 04:07:53 2014 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sat, 12 Apr 2014 13:07:53 +0200 Subject: [rust-dev] [discussion] preemptive scheduling In-Reply-To: References: Message-ID: Hello, As far as I know in Rust, a thread (green or not) that enters an infinite loop without I/O is forever stuck. The only available option to stop it is to have the OS kill the process (CTRL+C). In my day job, all our servers services are time-bounded and any that exceeds its time bound is killed. To do so requires one process per service for the exact same reason than Rust, which has the unfortunate effect of requiring a large memory footprint because "utility threads" (such as timers, and notably the watch-dog timer) are replicated in each and every process. The most common source of time-slips are disk accesses and database accesses which is covered by Rust under I/O, however I've already seen infinite loops (or very long ones) and there seems to be no way to protect against those. Of course one could recommend that such loops check a flag or something, but if we knew those loops were going to "diverge" we would fix them, not instrument them. I was hoping that with Rust (which already rids us of good-bye to dangling pointers & data races) we could move toward a single process with a lot of concurrent (green) tasks for better efficiency and ease of development, however the latter seems unattainable because of infinite loops or otherwise diverging code right now. I would thus also appreciate if anybody had an idea how to preempt a misbehaving task, even if the only option is to trigger this task failure; the goal at this point is to salvage the system without losing the current workload. -- Matthieu On Sat, Apr 12, 2014 at 11:04 AM, Jeremy Ong wrote: > I am considering authoring a webserver (think nginx, apache, cowboy, > etc) in Rust. From a user point of view, mapping tasks (green) to web > requests makes the most sense as the tasks could be long running, > perform their own I/O, sessions, or what have you. It would also allow > the user to do per-request in memory caching. > > My main concern is obviously the cooperative scheduler. Given that the > mantra of Rust seems to be safety, I'm curious about how feasible it > would be to provide the option for task safety as well. Preemptive > scheduling provides two things: > > 1. If preemption is used aggressively, the user can opt for a lower > latency system (a la Erlang style round robin preemptive scheduling) > 2. Preemption of any sort can be used as a safety net to isolate bugs > or blocks in tasks for long running systems, or at least mitigate > damage until the developer intervenes. > > I noticed in issue 5731[1] on the repo, it was pointed out that this > was possible, albeit difficult. The issue was closed with a comment > that the user should use OS threads instead. I really think this > misses the point as it no longer allows preemption on a smaller > granularity scale. Could any devs chime in on the scope and difficulty > of this project? Could any users/devs chime in on any of the points > above? > > tl;dr I think preemptive scheduling is a must for safe concurrency in > long running executables at the bottom of the stack. Opinions? > > > [1] https://github.com/mozilla/rust/issues/5731 > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From michaelwoerister at posteo.de Sat Apr 12 11:20:29 2014 From: michaelwoerister at posteo.de (Michael Woerister) Date: Sat, 12 Apr 2014 20:20:29 +0200 Subject: [rust-dev] Debugging : traversing code in libraries (rust 0.10 release) In-Reply-To: References: Message-ID: <534983ED.90408@posteo.de> If the extern crate is compiled with debug symbols, this should just work. Unfortunately, I don't think there is a 'configure' setting for enabling debug symbols for librand and the other 'post-extra' crates yet. It might be worth filing an issue for. Using --disable-optimize is not strictly necessary but debugging certainly works better for un-optimized code. On 11.04.2014 16:05, Artella Coding wrote: > Suppose I have the following code : > > **************************************** > extern crate rand; > use rand::{task_rng, Rng}; > > fn main() { > let names = ["Alice", "Bob", "Carol"]; > for name in names.iter() { > let v = task_rng().shuffle(~[1,2,3]); > for num in v.iter() { > println!("{:s} says: {:d}", *name, *num); > } > } > } > **************************************** > > Then I can put a breakpoint at shuffle by doing : > > rustc -g prog1.rs > gdb ./prog1 > rbreak shuffle > run > > However at this point if I try to step into the shuffle function and > list the code I get something like : > > **************************************** > (gdb) where > #0 0x0000000000404fe0 in Rng::shuffle_mut::h20bb47036b05fab8lja::v0.0 () > #1 0x0000000000404f58 in Rng::shuffle::h5fded7dc864fa562Uia::v0.0 () > #2 0x0000000000404634 in prog1::main () at prog1.rs:7 > #3 0x000000000043e453 in start::closure.7865 () > #4 0x00000000004d9263 in rt::task::Task::run::closure.41627 () > #5 0x00000000004e47dc in rust_try () > #6 0x00000000004d90c2 in > rt::task::Task::run::h50a26072019a80d2fs9::v0.10 () > #7 0x000000000043e244 in start::h4be0315ccbf00887zvd::v0.10 () > #8 0x000000000043e034 in lang_start::he9dd0a0b44e890dcTud::v0.10 () > #9 0x00000000004048bf in main () > (gdb) list > Line number 13 out of range; prog1.rs has 12 lines. > **************************************** > > How can I step through the source of Rng::shuffle? I downloaded the > source and when I did "./configure --help" I saw "--disable-optimize > don't build optimized rust code". So do I need to build > the source with this option? Thanks. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeremycong at gmail.com Sat Apr 12 11:45:01 2014 From: jeremycong at gmail.com (Jeremy Ong) Date: Sat, 12 Apr 2014 11:45:01 -0700 Subject: [rust-dev] [discussion] preemptive scheduling In-Reply-To: References: Message-ID: One of the benefits of providing preemption at the language level is that you are not restricted to using timers as the metric for suspending a process (although this is an option). You can also preempt after a process has performed a number of operations. One way to do this is for the compiler to inject yield hints for tasks executed as a green thread. These suggest to the scheduler that now is a decent time to suspend the process and if appropriate, the scheduler will do so. However, these hints will need to be very lightweight and regularly frequent. Again, the point of this feature would be to increase safety and reduce tail latency, not overall throughput. I would make this an option. This is more or less how the Erlang scheduler works and why it is, to date, the only VM I am aware of that optimizes for latency. For handling I/O, obviously you cannot inject yields directly in an I/O task. Better is to have an async task pool. If task A wishes to do some I/O, it fires a message to an async task and periodically checks if the task has returned. The checking can be finished immediately if it is something quick, but if not, task A can hint to suspend itself as above. In the scheme I am mentioning above, I would propose several configurable parameters. 1. Choice of scheduling algorithm to use. 2. Yield frequency (lower means lower tail latencies at the expense of mean response time and vice versa) 3. Async task pool max size. Bounds the amount of I/O tasks that can be run concurrently. I should mention that as a caveat, I have never implemented a scheduler before so I may be wildly off the mark. The bulk of my experience (in non-scripting languages) is in C++, Haskell, and Erlang so much of my thinking is borrowed from how things are thought of in those universes. I will attempt to review some of the literature today and see what I can come up with. Again, it would be great if the dev team could chime in with their thoughts on this. Cheers, J On Sat, Apr 12, 2014 at 4:07 AM, Matthieu Monrocq wrote: > Hello, > > As far as I know in Rust, a thread (green or not) that enters an infinite > loop without I/O is forever stuck. The only available option to stop it is > to have the OS kill the process (CTRL+C). > > In my day job, all our servers services are time-bounded and any that > exceeds its time bound is killed. To do so requires one process per service > for the exact same reason than Rust, which has the unfortunate effect of > requiring a large memory footprint because "utility threads" (such as > timers, and notably the watch-dog timer) are replicated in each and every > process. > > The most common source of time-slips are disk accesses and database accesses > which is covered by Rust under I/O, however I've already seen infinite loops > (or very long ones) and there seems to be no way to protect against those. > Of course one could recommend that such loops check a flag or something, but > if we knew those loops were going to "diverge" we would fix them, not > instrument them. > > > I was hoping that with Rust (which already rids us of good-bye to dangling > pointers & data races) we could move toward a single process with a lot of > concurrent (green) tasks for better efficiency and ease of development, > however the latter seems unattainable because of infinite loops or otherwise > diverging code right now. > > > I would thus also appreciate if anybody had an idea how to preempt a > misbehaving task, even if the only option is to trigger this task failure; > the goal at this point is to salvage the system without losing the current > workload. > > -- Matthieu > > > > On Sat, Apr 12, 2014 at 11:04 AM, Jeremy Ong wrote: >> >> I am considering authoring a webserver (think nginx, apache, cowboy, >> etc) in Rust. From a user point of view, mapping tasks (green) to web >> requests makes the most sense as the tasks could be long running, >> perform their own I/O, sessions, or what have you. It would also allow >> the user to do per-request in memory caching. >> >> My main concern is obviously the cooperative scheduler. Given that the >> mantra of Rust seems to be safety, I'm curious about how feasible it >> would be to provide the option for task safety as well. Preemptive >> scheduling provides two things: >> >> 1. If preemption is used aggressively, the user can opt for a lower >> latency system (a la Erlang style round robin preemptive scheduling) >> 2. Preemption of any sort can be used as a safety net to isolate bugs >> or blocks in tasks for long running systems, or at least mitigate >> damage until the developer intervenes. >> >> I noticed in issue 5731[1] on the repo, it was pointed out that this >> was possible, albeit difficult. The issue was closed with a comment >> that the user should use OS threads instead. I really think this >> misses the point as it no longer allows preemption on a smaller >> granularity scale. Could any devs chime in on the scope and difficulty >> of this project? Could any users/devs chime in on any of the points >> above? >> >> tl;dr I think preemptive scheduling is a must for safe concurrency in >> long running executables at the bottom of the stack. Opinions? >> >> >> [1] https://github.com/mozilla/rust/issues/5731 >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > From axel.viala at darnuria.eu Sat Apr 12 13:55:55 2014 From: axel.viala at darnuria.eu (Axel Viala) Date: Sat, 12 Apr 2014 22:55:55 +0200 Subject: [rust-dev] Rust Meetup Paris 03 Message-ID: <5349A85B.9080309@darnuria.eu> Third of his name. Planing: 18:00 -> 19:30: Lunch and informal meeting. 19:30 -> 23:00: Workshops for different levels. Reps Page: https://reps.mozilla.org/e/meetup-rust-paris-03/ Inscription and attendees: https://etherpad.mozilla.org/remo-meetup-rust-paris-03 From danielmicay at gmail.com Sat Apr 12 22:08:54 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 13 Apr 2014 01:08:54 -0400 Subject: [rust-dev] [discussion] preemptive scheduling In-Reply-To: References: Message-ID: <534A1BE6.6090401@gmail.com> On 12/04/14 05:04 AM, Jeremy Ong wrote: > I am considering authoring a webserver (think nginx, apache, cowboy, > etc) in Rust. From a user point of view, mapping tasks (green) to web > requests makes the most sense as the tasks could be long running, > perform their own I/O, sessions, or what have you. It would also allow > the user to do per-request in memory caching. > > My main concern is obviously the cooperative scheduler. Given that the > mantra of Rust seems to be safety, I'm curious about how feasible it > would be to provide the option for task safety as well. Preemptive > scheduling provides two things: > > 1. If preemption is used aggressively, the user can opt for a lower > latency system (a la Erlang style round robin preemptive scheduling) > 2. Preemption of any sort can be used as a safety net to isolate bugs > or blocks in tasks for long running systems, or at least mitigate > damage until the developer intervenes. > > I noticed in issue 5731[1] on the repo, it was pointed out that this > was possible, albeit difficult. The issue was closed with a comment > that the user should use OS threads instead. I really think this > misses the point as it no longer allows preemption on a smaller > granularity scale. Could any devs chime in on the scope and difficulty > of this project? Could any users/devs chime in on any of the points > above? > > tl;dr I think preemptive scheduling is a must for safe concurrency in > long running executables at the bottom of the stack. Opinions? > > > [1] https://github.com/mozilla/rust/issues/5731 Native threading is the default and provides preemption. The argument for including green threads is the potential to increase performance by eliminating context switches, and that evaporates if the compiler needs to insert yield points at loop edges. The same compiled code supports both native and green threading, so you're asking for *everyone* to pay the cost of this feature whether or not they're going to use it. Rust's goal is to be a viable systems language, and it won't be one if there's the cost of yield checks. The name of the game is "pay for what you use" and in my opinion any feature breaking that rule to this extent is a no go. It could be a compile-time flag, but the libraries shipping with Rust are not going to be compiled with it... so it would always involve someone building their own Rust compiler / libraries. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From farcaller at gmail.com Sun Apr 13 13:12:43 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Sun, 13 Apr 2014 21:12:43 +0100 Subject: [rust-dev] Convincing compiler that *T is safe Message-ID: I have a number of I/O mapped registers that look like: struct Dev { .. // u32 fields } pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev; with macro-generated getters and setters: pub fn $getter_name(&self) -> u32 { unsafe { volatile_load(&(self.$reg)) } } unfortunately, calling a getter is calling a method on *Reg, which is unsafe and looks like: unsafe { (*Dev0).SOME_REG() }; is there any way to simplify the syntax, hopefully to simple Dev0.SOME_REG()? I'm ok with any "unsafe" tricks including transmuting it to &Dev (that doesn't seem to be possible though), as the getter/setter methods are always safe in this scenario. -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From jurily at gmail.com Sun Apr 13 13:22:42 2014 From: jurily at gmail.com (=?UTF-8?Q?Gy=C3=B6rgy_Andrasek?=) Date: Sun, 13 Apr 2014 22:22:42 +0200 Subject: [rust-dev] Convincing compiler that *T is safe In-Reply-To: References: Message-ID: You could make a container struct: struct Dev { ptr: *mut InternalDev } and then impl your methods on that. From bjzaba at yahoo.com.au Sun Apr 13 14:43:36 2014 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Mon, 14 Apr 2014 07:43:36 +1000 Subject: [rust-dev] Convincing compiler that *T is safe In-Reply-To: References: Message-ID: <2B121AAA-3393-4B12-9289-300E33A88F2E@yahoo.com.au> Indeed, I would say a wrapper would be a good abstraction here. Even more so than in modern C++, ?naked? raw pointers are in general (exceptions granted) distasteful for public APIs in Rust. ~Brendan On 14 Apr 2014, at 6:22 am, Gy?rgy Andrasek wrote: > You could make a container struct: > > struct Dev { > ptr: *mut InternalDev > } > > and then impl your methods on that. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From corey at octayn.net Sun Apr 13 20:43:17 2014 From: corey at octayn.net (Corey Richardson) Date: Sun, 13 Apr 2014 23:43:17 -0400 Subject: [rust-dev] Large Collection of rustc builds Message-ID: Hello all, I now have on a disk here every merge into master that builds on my machine, built. That is, 3733 copies, using 560GB of disk, of rustc going back to the first run of bors on February 1, 2013. If there's anything interesting you want to do with them, let me know! -- http://octayn.net/ From asb at asbradbury.org Mon Apr 14 00:22:04 2014 From: asb at asbradbury.org (Alex Bradbury) Date: Mon, 14 Apr 2014 08:22:04 +0100 Subject: [rust-dev] Large Collection of rustc builds In-Reply-To: References: Message-ID: On 14 April 2014 04:43, Corey Richardson wrote: > Hello all, > > I now have on a disk here every merge into master that builds on my > machine, built. That is, 3733 copies, using 560GB of disk, of rustc > going back to the first run of bors on February 1, 2013. If there's > anything interesting you want to do with them, let me know! Rust hasn't really reached the level of stability where bisecting for regressions is commonly useful, but you may be interested in LibreOffice's bibisect which aims to provide binary builds for each commit stored in git for easy bisecting: https://wiki.documentfoundation.org/QA/HowToBibisect Alex From flaper87 at gmail.com Mon Apr 14 02:04:10 2014 From: flaper87 at gmail.com (Flaper87) Date: Mon, 14 Apr 2014 11:04:10 +0200 Subject: [rust-dev] Large Collection of rustc builds In-Reply-To: References: Message-ID: 2014-04-14 9:22 GMT+02:00 Alex Bradbury : > On 14 April 2014 04:43, Corey Richardson wrote: > > Hello all, > > > > I now have on a disk here every merge into master that builds on my > > machine, built. That is, 3733 copies, using 560GB of disk, of rustc > > going back to the first run of bors on February 1, 2013. If there's > > anything interesting you want to do with them, let me know! > > Rust hasn't really reached the level of stability where bisecting for > regressions is commonly useful, but you may be interested in > LibreOffice's bibisect which aims to provide binary builds for each > commit stored in git for easy bisecting: > https://wiki.documentfoundation.org/QA/HowToBibisect > This is interesting. Although we try hard, not all commits in Rust's git repo compile, hence the best we can do is look for bors' merges since we're sure those went through buildbot. We'll eventually need something like this, so this is great info. Also, great job, Corey. Flavio. -- Flavio (@flaper87) Percoco http://www.flaper87.com http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From flaper87 at gmail.com Mon Apr 14 02:04:45 2014 From: flaper87 at gmail.com (Flaper87) Date: Mon, 14 Apr 2014 11:04:45 +0200 Subject: [rust-dev] Convincing compiler that *T is safe In-Reply-To: References: Message-ID: 2014-04-13 22:22 GMT+02:00 Gy?rgy Andrasek : > You could make a container struct: > > struct Dev { > ptr: *mut InternalDev > } > > and then impl your methods on that. > > I'd recommend using `Unsafe` which was added to wrap types T and indicate an *unsafe interior*. It exposes a `get` method that returns a `*mut` pointer to the wrapped data. Here's the link to the Unsafe docstring (which also contains an example): https://github.com/mozilla/rust/blob/master/src/libstd/ty.rs#L16 Flavio -- Flavio (@flaper87) Percoco http://www.flaper87.com http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Mon Apr 14 02:06:27 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Mon, 14 Apr 2014 10:06:27 +0100 Subject: [rust-dev] Convincing compiler that *T is safe In-Reply-To: References: Message-ID: Looks nice, but in this case pub static Dev0: Dev isn't getting optimised away, adding bytes to the binary; that's not an acceptable tradeoff. Any other ideas? On Sun, Apr 13, 2014 at 9:22 PM, Gy?rgy Andrasek wrote: > You could make a container struct: > > struct Dev { > ptr: *mut InternalDev > } > > and then impl your methods on that. > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Mon Apr 14 02:10:39 2014 From: dbau.pp at gmail.com (Huon Wilson) Date: Mon, 14 Apr 2014 19:10:39 +1000 Subject: [rust-dev] Convincing compiler that *T is safe In-Reply-To: References: Message-ID: <534BA60F.9010000@gmail.com> On 14/04/14 19:04, Flaper87 wrote: > > > > 2014-04-13 22:22 GMT+02:00 Gy?rgy Andrasek >: > > You could make a container struct: > > struct Dev { > ptr: *mut InternalDev > } > > and then impl your methods on that. > > > I'd recommend using `Unsafe` which was added to wrap types T and > indicate an *unsafe interior*. It exposes a `get` method that returns > a `*mut` pointer to the wrapped data. > > Here's the link to the Unsafe docstring (which also contains an > example): https://github.com/mozilla/rust/blob/master/src/libstd/ty.rs#L16 > > > Flavio > > > -- > Flavio (@flaper87) Percoco > http://www.flaper87.com > http://github.com/FlaPer87 > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev I'm not sure that Unsafe is particularly useful here, since the goal is to avoid unsafety by providing a sensible wrapper around the raw pointer (since some methods are "known" to be safe). Also, the rendered docs are a better place to which to link: http://static.rust-lang.org/doc/master/std/ty/struct.Unsafe.html Huon -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Mon Apr 14 02:19:25 2014 From: dbau.pp at gmail.com (Huon Wilson) Date: Mon, 14 Apr 2014 19:19:25 +1000 Subject: [rust-dev] Convincing compiler that *T is safe In-Reply-To: References: Message-ID: <534BA81D.8040800@gmail.com> On 14/04/14 06:12, Vladimir Pouzanov wrote: > I have a number of I/O mapped registers that look like: > > struct Dev { > .. // u32 fields > } > > pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev; > > with macro-generated getters and setters: > > pub fn $getter_name(&self) -> u32 { > unsafe { volatile_load(&(self.$reg)) } > } > > unfortunately, calling a getter is calling a method on *Reg, which is > unsafe and looks like: > > unsafe { (*Dev0).SOME_REG() }; > > is there any way to simplify the syntax, hopefully to simple > Dev0.SOME_REG()? I'm ok with any "unsafe" tricks including transmuting > it to &Dev (that doesn't seem to be possible though), as the > getter/setter methods are always safe in this scenario. > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev The compiler cannot verify that these method calls are safe, so they `unsafe`'s are asserting "trust me compiler, I know more than you". You could write a macro like `get!(Dev0, SOME_REG)` that expanded to the `unsafe { (*Dev0).SOME_REG() }` invocation. But... I don't understand why transmuting to &Dev wouldn't be possible. I'd strongly recommend the weaker version `unsafe { &*Dev0 }`, to go from *mut Dev to &Dev0. However, this likely breaks the guarantees of &, since the data to which they point is supposed to be immutable, but being I/O mapped registers it would imply that external events can change the values. (I guess this is where Flavio's suggestion of storing a *Unsafe comes into play, but this still leaves you dealing with an *mut pointer to get at the data, at the end of the day.) Huon -------------- next part -------------- An HTML attachment was scrubbed... URL: From com.liigo at gmail.com Mon Apr 14 02:38:14 2014 From: com.liigo at gmail.com (Liigo Zhuang) Date: Mon, 14 Apr 2014 17:38:14 +0800 Subject: [rust-dev] master [run-pass]: most tests failed. mingw + windows 7. Message-ID: test result: FAILED. 2 passed; 1387 failed; 50 ignored; 0 measured what happens? Most tests failed at 'explicit failure': ---- [run-pass] run-pass/unwind-unique.rs stdout ---- error: test run failed! command: PATH="i686-pc-mingw32/stage2/bin/rustlib/i686-pc-mingw32/lib;;.;D:\MinGW\msys\1.0\local\bin;d:\mingw\bi n;D:\MinGW\msys\1.0\bin;c:\Perl64\site\bin;c:\Perl64\bin;c:\Windows\system32;c:\Windows;c:\Windows\System32\Wbem;c:\Wind ows\System32\WindowsPowerShell\v1.0\;d:\CrossGCC\mips\share;d:\CrossGCC\mips\bin;d:\Program Files\TortoiseSVN\bin;c:\Pro gram Files (x86)\Windows Kits\8.0\Windows Performance Toolkit\;d:\Go\bin;d:\Go\3rd\bin;d:\Program Files (x86)\Git\bin;d: \Program Files\MariaDB 5.5\bin;c:\Program Files\Microsoft SQL Server\110\Tools\Binn\;d:\Programs\lua52;c:\Program Files (x86)\Bitvise SSH Client;d:\Program Files\TortoiseGit\bin;c:\Python27;c:\Python27\Scripts;d:\Liigo\rust\rust-nightly\bin ;d:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\WinNT;d:\Program Files (x86)\Microsoft Visual Studio\Common \MSDev98\Bin;d:\Program Files (x86)\Microsoft Visual Studio\Common\Tools;d:\Program Files (x86)\Microsoft Visual Studio\ VC98\bin;d:\Program Files (x86)\CMake 2.8\bin;d:\Program Files (x86)\XinAnTong;d:\Programs\Pawn\bin;c:\nasm;i686-pc-ming w32\stage2\bin\rustlib\i686-pc-mingw32\lib" i686-pc-mingw32\test\run-pass\unwind-unique.stage2-i686-pc-mingw32.exe stdout: ------------------------------------------ ------------------------------------------ stderr: ------------------------------------------ ------------------------------------------ task '[run-pass] run-pass/unwind-unique.rs' failed at 'explicit failure', D:\MinGW\msys\1.0\home\LIIGO\rust\rust \src\compiletest\runtest.rs:963 -- by *Liigo*, http://blog.csdn.net/liigo/ Google+ https://plus.google.com/105597640837742873343/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Mon Apr 14 03:07:40 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Mon, 14 Apr 2014 11:07:40 +0100 Subject: [rust-dev] Convincing compiler that *T is safe In-Reply-To: <534BA81D.8040800@gmail.com> References: <534BA81D.8040800@gmail.com> Message-ID: Well, the &Dev as a pointer would be immutable in terms of that you can't change its address, and all access to fields is done via getter/setter methods using volatiles. It seems that I cannot use transmute in a context of static though and I can't trade runtime size over better syntax. On Mon, Apr 14, 2014 at 10:19 AM, Huon Wilson wrote: > On 14/04/14 06:12, Vladimir Pouzanov wrote: > > I have a number of I/O mapped registers that look like: > > struct Dev { > .. // u32 fields > } > > pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev; > > with macro-generated getters and setters: > > pub fn $getter_name(&self) -> u32 { > unsafe { volatile_load(&(self.$reg)) } > } > > unfortunately, calling a getter is calling a method on *Reg, which is > unsafe and looks like: > > unsafe { (*Dev0).SOME_REG() }; > > is there any way to simplify the syntax, hopefully to simple > Dev0.SOME_REG()? I'm ok with any "unsafe" tricks including transmuting it > to &Dev (that doesn't seem to be possible though), as the getter/setter > methods are always safe in this scenario. > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > > _______________________________________________ > Rust-dev mailing listRust-dev at mozilla.orghttps://mail.mozilla.org/listinfo/rust-dev > > > > The compiler cannot verify that these method calls are safe, so they > `unsafe`'s are asserting "trust me compiler, I know more than you". > > > You could write a macro like `get!(Dev0, SOME_REG)` that expanded to the > `unsafe { (*Dev0).SOME_REG() }` invocation. > > > But... I don't understand why transmuting to &Dev wouldn't be possible. > I'd strongly recommend the weaker version `unsafe { &*Dev0 }`, to go from > *mut Dev to &Dev0. However, this likely breaks the guarantees of &, since > the data to which they point is supposed to be immutable, but being I/O > mapped registers it would imply that external events can change the values. > (I guess this is where Flavio's suggestion of storing a *Unsafe comes > into play, but this still leaves you dealing with an *mut pointer to get at > the data, at the end of the day.) > > > Huon > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at steveklabnik.com Mon Apr 14 09:10:12 2014 From: steve at steveklabnik.com (Steve Klabnik) Date: Mon, 14 Apr 2014 09:10:12 -0700 Subject: [rust-dev] Large Collection of rustc builds In-Reply-To: References: Message-ID: Oh! Oh! This is really useful because we have a bootstrapped compiler. It's Monday, and I'm still on my first coffee, but couldn't this lead to every single build since the history of time being signed? - Steve From zach.lists at gmail.com Mon Apr 14 09:19:23 2014 From: zach.lists at gmail.com (Zach Moazeni) Date: Mon, 14 Apr 2014 12:19:23 -0400 Subject: [rust-dev] Do I need to watch out for memory fragmentation? Message-ID: Hello, I'm starting to explore Rust, and as someone who has primarily worked in GC'd languages I'm curious if I need to watch out for anything related to memory fragmentation. Or if Rust or LLVM is doing something under the covers where this is less of an issue. Kind regards, Zach -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Mon Apr 14 09:41:23 2014 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Mon, 14 Apr 2014 18:41:23 +0200 Subject: [rust-dev] Do I need to watch out for memory fragmentation? In-Reply-To: References: Message-ID: Memory fragmentation is a potential issue in all languages that not use a Compacting GC, so yes. There are some attenuating circumstances in Rust, notably the fact that unless you use a ~ pointer the memory is allocated in a task private heap which is entirely recycled at the death of the task, but memory fragmentation is always a potential issue. On Mon, Apr 14, 2014 at 6:19 PM, Zach Moazeni wrote: > Hello, > > I'm starting to explore Rust, and as someone who has primarily worked in > GC'd languages I'm curious if I need to watch out for anything related to > memory fragmentation. Or if Rust or LLVM is doing something under the > covers where this is less of an issue. > > Kind regards, > Zach > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From zach.lists at gmail.com Mon Apr 14 10:14:18 2014 From: zach.lists at gmail.com (Zach Moazeni) Date: Mon, 14 Apr 2014 13:14:18 -0400 Subject: [rust-dev] Do I need to watch out for memory fragmentation? In-Reply-To: References: Message-ID: Thanks Matthieu. I thought that might be the case. I'll keep a look out as I work with Rust and ping the mailing list if I need to cross that bridge. Kind Regards, Zach On Mon, Apr 14, 2014 at 12:41 PM, Matthieu Monrocq < matthieu.monrocq at gmail.com> wrote: > Memory fragmentation is a potential issue in all languages that not use a > Compacting GC, so yes. > > There are some attenuating circumstances in Rust, notably the fact that > unless you use a ~ pointer the memory is allocated in a task private heap > which is entirely recycled at the death of the task, but memory > fragmentation is always a potential issue. > > > On Mon, Apr 14, 2014 at 6:19 PM, Zach Moazeni wrote: > >> Hello, >> >> I'm starting to explore Rust, and as someone who has primarily worked in >> GC'd languages I'm curious if I need to watch out for anything related to >> memory fragmentation. Or if Rust or LLVM is doing something under the >> covers where this is less of an issue. >> >> Kind regards, >> Zach >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bascule at gmail.com Mon Apr 14 10:20:46 2014 From: bascule at gmail.com (Tony Arcieri) Date: Mon, 14 Apr 2014 10:20:46 -0700 Subject: [rust-dev] Large Collection of rustc builds In-Reply-To: References: Message-ID: On Mon, Apr 14, 2014 at 9:10 AM, Steve Klabnik wrote: > This is really useful because we have a bootstrapped compiler. It's > Monday, and I'm still on my first coffee, but couldn't this lead to > every single build since the history of time being signed? Worried about Ken Thompsonesque backdoors? ;) -- Tony Arcieri -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at steveklabnik.com Mon Apr 14 10:33:04 2014 From: steve at steveklabnik.com (Steve Klabnik) Date: Mon, 14 Apr 2014 10:33:04 -0700 Subject: [rust-dev] Large Collection of rustc builds In-Reply-To: References: Message-ID: Maybe. For anyone who doesn't get Tony's reference: http://cm.bell-labs.com/who/ken/trust.html From danielmicay at gmail.com Mon Apr 14 13:32:06 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 14 Apr 2014 16:32:06 -0400 Subject: [rust-dev] Do I need to watch out for memory fragmentation? In-Reply-To: References: Message-ID: <534C45C6.1050507@gmail.com> On 14/04/14 12:41 PM, Matthieu Monrocq wrote: > Memory fragmentation is a potential issue in all languages that not use > a Compacting GC, so yes. It's much less of an issue than people make it out to be on 32-bit, and it's a non-issue on 64-bit with a good allocator (jemalloc, tcmalloc). Small dynamic memory allocations are tightly packed in arenas, with a very low upper bound on fragmentation and metadata overhead. At a certain cutoff point, allocations begin to fall through directly to mmap instead of using the arenas. On 64-bit, the address space is enormous so fragmenting it is only a problem when it comes to causing TLB misses. > There are some attenuating circumstances in Rust, notably the fact that > unless you use a ~ pointer the memory is allocated in a task private > heap which is entirely recycled at the death of the task, but memory > fragmentation is always a potential issue. All dynamic memory allocations are currently done with the malloc family of functions, whether you use sendable types like `Vec`, `Arc` and `~T` or task-local types like `Rc`. Using a task-local heap for types like `Rc` would only serve to *increase* the level of fragmentation by splitting it up more. For example, jemalloc implements thread-local caching, and then distributes the remaining workload across a fixed number of arenas. Increasing the level of thread-local caching has a performance benefit but by definition increases the level of fragmentation due to more unused capacity assigned to specific threads. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From matthieu.monrocq at gmail.com Tue Apr 15 09:46:21 2014 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Tue, 15 Apr 2014 18:46:21 +0200 Subject: [rust-dev] Do I need to watch out for memory fragmentation? In-Reply-To: <534C45C6.1050507@gmail.com> References: <534C45C6.1050507@gmail.com> Message-ID: On Mon, Apr 14, 2014 at 10:32 PM, Daniel Micay wrote: > On 14/04/14 12:41 PM, Matthieu Monrocq wrote: > > Memory fragmentation is a potential issue in all languages that not use > > a Compacting GC, so yes. > > It's much less of an issue than people make it out to be on 32-bit, and > it's a non-issue on 64-bit with a good allocator (jemalloc, tcmalloc). > > Small dynamic memory allocations are tightly packed in arenas, with a > very low upper bound on fragmentation and metadata overhead. At a > certain cutoff point, allocations begin to fall through directly to mmap > instead of using the arenas. On 64-bit, the address space is enormous so > fragmenting it is only a problem when it comes to causing TLB misses. > By the way, do you have any idea how this is going to pan out on processors like the Mill CPU where the address space is shared among processes ? > > > There are some attenuating circumstances in Rust, notably the fact that > > unless you use a ~ pointer the memory is allocated in a task private > > heap which is entirely recycled at the death of the task, but memory > > fragmentation is always a potential issue. > > All dynamic memory allocations are currently done with the malloc family > of functions, whether you use sendable types like `Vec`, `Arc` and > `~T` or task-local types like `Rc`. Using a task-local heap for types > like `Rc` would only serve to *increase* the level of fragmentation > by splitting it up more. > > For example, jemalloc implements thread-local caching, and then > distributes the remaining workload across a fixed number of arenas. > Increasing the level of thread-local caching has a performance benefit > but by definition increases the level of fragmentation due to more > unused capacity assigned to specific threads. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcwalton at mozilla.com Tue Apr 15 10:12:55 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Tue, 15 Apr 2014 10:12:55 -0700 Subject: [rust-dev] Removing ~"foo" Message-ID: <534D6897.6080202@mozilla.com> Hi everyone, I'd like to remove the `~"foo"` literal syntax for owned strings in both expressions and patterns. After dynamically sized types, this syntax is the last remnant of the strange parser behavior by which the parser does something different for `~"foo"` and `~("foo")` (i.e. by which it looks at the next token when it sees a sigil and does something different than it would otherwise). The new replacement for `~"foo"` will be `"foo".to_owned()`. You can also use the `fmt!()` macro or the `.to_str()` function. Post-DST, you will likely also be able to write `Heap::from("foo")`. This has no effect on constants since `~"foo"` is not allowed there anyway. Patrick From steve at steveklabnik.com Tue Apr 15 10:20:37 2014 From: steve at steveklabnik.com (Steve Klabnik) Date: Tue, 15 Apr 2014 10:20:37 -0700 Subject: [rust-dev] Removing ~"foo" In-Reply-To: <534D6897.6080202@mozilla.com> References: <534D6897.6080202@mozilla.com> Message-ID: I can finally retire that bookmark to https://mail.mozilla.org/pipermail/rust-dev/2013-April/003867.html ! From hatahet at gmail.com Tue Apr 15 11:04:09 2014 From: hatahet at gmail.com (Ziad Hatahet) Date: Tue, 15 Apr 2014 11:04:09 -0700 Subject: [rust-dev] Removing ~"foo" In-Reply-To: References: <534D6897.6080202@mozilla.com> Message-ID: On Tue, Apr 15, 2014 at 10:20 AM, Steve Klabnik wrote: > I can finally retire that bookmark to > https://mail.mozilla.org/pipermail/rust-dev/2013-April/003867.html ! > How will that change though? Won't we still have to call `.equiv()`? Furthermore, wasn't the plan to use `box("string")` to create owned pointers? -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From slabode at aim.com Tue Apr 15 11:06:47 2014 From: slabode at aim.com (SiegeLord) Date: Tue, 15 Apr 2014 14:06:47 -0400 Subject: [rust-dev] Removing ~"foo" In-Reply-To: <534D6897.6080202@mozilla.com> References: <534D6897.6080202@mozilla.com> Message-ID: <534D7537.5010602@aim.com> On 04/15/2014 01:12 PM, Patrick Walton wrote: > The new replacement for `~"foo"` will be `"foo".to_owned()`. You can > also use the `fmt!()` macro or the `.to_str()` function. Post-DST, you > will likely also be able to write `Heap::from("foo")`. Why not `box "foo"`? Is that scheduled to break? -SL From corey at octayn.net Tue Apr 15 11:10:11 2014 From: corey at octayn.net (Corey Richardson) Date: Tue, 15 Apr 2014 14:10:11 -0400 Subject: [rust-dev] Removing ~"foo" In-Reply-To: <534D7537.5010602@aim.com> References: <534D6897.6080202@mozilla.com> <534D7537.5010602@aim.com> Message-ID: `box "foo"` would create a SomeBox<&'static str>, as outlined in the meeting notes: box "foo" -> Heap<&'static Str> "foo".to_owned() -> Heap (or ~Str) Heap::from("foo") -> Heap (or ~Str) Rc::from("foo") -> Rc On Tue, Apr 15, 2014 at 2:06 PM, SiegeLord wrote: > On 04/15/2014 01:12 PM, Patrick Walton wrote: >> >> The new replacement for `~"foo"` will be `"foo".to_owned()`. You can >> also use the `fmt!()` macro or the `.to_str()` function. Post-DST, you >> will likely also be able to write `Heap::from("foo")`. > > > Why not `box "foo"`? Is that scheduled to break? > > -SL > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ From hatahet at gmail.com Tue Apr 15 11:25:17 2014 From: hatahet at gmail.com (Ziad Hatahet) Date: Tue, 15 Apr 2014 11:25:17 -0700 Subject: [rust-dev] Removing ~"foo" In-Reply-To: References: <534D6897.6080202@mozilla.com> <534D7537.5010602@aim.com> Message-ID: So the new Vec and Str/StrBuf types are all "reference" types, correct? What happens if we pass around a borrowed or owned pointer to one of these types? Won't there be an extra level of indirection to get to the underlying data pointer? -- Ziad On Tue, Apr 15, 2014 at 11:10 AM, Corey Richardson wrote: > `box "foo"` would create a SomeBox<&'static str>, as outlined in the > meeting notes: > > box "foo" -> Heap<&'static Str> > "foo".to_owned() -> Heap (or ~Str) > Heap::from("foo") -> Heap (or ~Str) > Rc::from("foo") -> Rc > > On Tue, Apr 15, 2014 at 2:06 PM, SiegeLord wrote: > > On 04/15/2014 01:12 PM, Patrick Walton wrote: > >> > >> The new replacement for `~"foo"` will be `"foo".to_owned()`. You can > >> also use the `fmt!()` macro or the `.to_str()` function. Post-DST, you > >> will likely also be able to write `Heap::from("foo")`. > > > > > > Why not `box "foo"`? Is that scheduled to break? > > > > -SL > > > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > > -- > http://octayn.net/ > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Tue Apr 15 11:35:03 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 15 Apr 2014 14:35:03 -0400 Subject: [rust-dev] Do I need to watch out for memory fragmentation? In-Reply-To: References: <534C45C6.1050507@gmail.com> Message-ID: <534D7BD7.4000709@gmail.com> On 15/04/14 12:46 PM, Matthieu Monrocq wrote: > > By the way, do you have any idea how this is going to pan out on > processors like the Mill CPU where the address space is shared among > processes ? x86_64 and ARM64 really have a 48-bit address space (cut down to 47-bit by Linux to separate the kernel/userspace) while the Mill has a 60-bit address space so it doesn't seem like a problem. It's an enormous amount of usable virtual memory. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From danielmicay at gmail.com Tue Apr 15 11:38:37 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 15 Apr 2014 14:38:37 -0400 Subject: [rust-dev] Removing ~"foo" In-Reply-To: References: <534D6897.6080202@mozilla.com> <534D7537.5010602@aim.com> Message-ID: <534D7CAD.8060307@gmail.com> On 15/04/14 02:25 PM, Ziad Hatahet wrote: > So the new Vec and Str/StrBuf types are all "reference" types, correct? > What happens if we pass around a borrowed or owned pointer to one of > these types? Won't there be an extra level of indirection to get to the > underlying data pointer? There's close to no reason to store `Vec` or `StrBuf` in an owned box, and very little reason to pass around a reference to them. You can obtain a slice (either &[T] or &mut [T]) into `Vec` and the same goes for strings. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From artella.coding at googlemail.com Tue Apr 15 06:28:47 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Tue, 15 Apr 2014 14:28:47 +0100 Subject: [rust-dev] Specifying lifetimes in return types of overloaded operators Message-ID: Currently if I try to specify lifetimes in the return types of overloaded operators like Index ([]), I get an error message : "method `index` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter &" Why has this restriction been placed, given that I can write custom functions which can have bounded lifetimes specifications in the return type? Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Sun Apr 13 00:23:43 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Sun, 13 Apr 2014 08:23:43 +0100 Subject: [rust-dev] Debugging : traversing code in libraries (rust 0.10 release) In-Reply-To: <534983ED.90408@posteo.de> References: <534983ED.90408@posteo.de> Message-ID: Hi, I made an issue at https://github.com/mozilla/rust/issues/13492 Thanks On Sat, Apr 12, 2014 at 7:20 PM, Michael Woerister < michaelwoerister at posteo.de> wrote: > If the extern crate is compiled with debug symbols, this should just > work. Unfortunately, I don't think there is a 'configure' setting for > enabling debug symbols for librand and the other 'post-extra' crates yet. > It might be worth filing an issue for. > Using --disable-optimize is not strictly necessary but debugging certainly > works better for un-optimized code. > > > On 11.04.2014 16:05, Artella Coding wrote: > > Suppose I have the following code : > > **************************************** > extern crate rand; > use rand::{task_rng, Rng}; > > fn main() { > let names = ["Alice", "Bob", "Carol"]; > for name in names.iter() { > let v = task_rng().shuffle(~[1,2,3]); > for num in v.iter() { > println!("{:s} says: {:d}", *name, *num); > } > } > } > **************************************** > > Then I can put a breakpoint at shuffle by doing : > > rustc -g prog1.rs > gdb ./prog1 > rbreak shuffle > run > > However at this point if I try to step into the shuffle function and > list the code I get something like : > > **************************************** > (gdb) where > #0 0x0000000000404fe0 in Rng::shuffle_mut::h20bb47036b05fab8lja::v0.0 () > #1 0x0000000000404f58 in Rng::shuffle::h5fded7dc864fa562Uia::v0.0 () > #2 0x0000000000404634 in prog1::main () at prog1.rs:7 > #3 0x000000000043e453 in start::closure.7865 () > #4 0x00000000004d9263 in rt::task::Task::run::closure.41627 () > #5 0x00000000004e47dc in rust_try () > #6 0x00000000004d90c2 in rt::task::Task::run::h50a26072019a80d2fs9::v0.10 > () > #7 0x000000000043e244 in start::h4be0315ccbf00887zvd::v0.10 () > #8 0x000000000043e034 in lang_start::he9dd0a0b44e890dcTud::v0.10 () > #9 0x00000000004048bf in main () > (gdb) list > Line number 13 out of range; prog1.rs has 12 lines. > **************************************** > > How can I step through the source of Rng::shuffle? I downloaded the > source and when I did "./configure --help" I saw "--disable-optimize > don't build optimized rust code". So do I need to build the source > with this option? Thanks. > > > _______________________________________________ > Rust-dev mailing listRust-dev at mozilla.orghttps://mail.mozilla.org/listinfo/rust-dev > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Tue Apr 15 13:09:34 2014 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 15 Apr 2014 13:09:34 -0700 Subject: [rust-dev] Removing ~"foo" In-Reply-To: <534D6897.6080202@mozilla.com> References: <534D6897.6080202@mozilla.com> Message-ID: <534D91FE.4070300@mozilla.com> On 04/15/2014 10:12 AM, Patrick Walton wrote: > Hi everyone, > > I'd like to remove the `~"foo"` literal syntax for owned strings in both > expressions and patterns. After dynamically sized types, this syntax is > the last remnant of the strange parser behavior by which the parser does > something different for `~"foo"` and `~("foo")` (i.e. by which it looks > at the next token when it sees a sigil and does something different than > it would otherwise). > > The new replacement for `~"foo"` will be `"foo".to_owned()`. You can > also use the `fmt!()` macro or the `.to_str()` function. Post-DST, you > will likely also be able to write `Heap::from("foo")`. > > This has no effect on constants since `~"foo"` is not allowed there anyway. > Thanks, Patrick. Full steam ahead. Let's get DST done. From hatahet at gmail.com Tue Apr 15 13:28:21 2014 From: hatahet at gmail.com (Ziad Hatahet) Date: Tue, 15 Apr 2014 13:28:21 -0700 Subject: [rust-dev] Removing ~"foo" In-Reply-To: <534D6897.6080202@mozilla.com> References: <534D6897.6080202@mozilla.com> Message-ID: Would it be worth introducing an own!() macro for this purpose? I came across this suggestion on the reddit thread: http://www.reddit.com/r/rust/comments/2340zb/rustdev_removing_foo/ -- Ziad On Tue, Apr 15, 2014 at 10:12 AM, Patrick Walton wrote: > Hi everyone, > > I'd like to remove the `~"foo"` literal syntax for owned strings in both > expressions and patterns. After dynamically sized types, this syntax is the > last remnant of the strange parser behavior by which the parser does > something different for `~"foo"` and `~("foo")` (i.e. by which it looks at > the next token when it sees a sigil and does something different than it > would otherwise). > > The new replacement for `~"foo"` will be `"foo".to_owned()`. You can also > use the `fmt!()` macro or the `.to_str()` function. Post-DST, you will > likely also be able to write `Heap::from("foo")`. > > This has no effect on constants since `~"foo"` is not allowed there anyway. > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Tue Apr 15 13:41:24 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 15 Apr 2014 16:41:24 -0400 Subject: [rust-dev] Removing ~"foo" In-Reply-To: References: <534D6897.6080202@mozilla.com> Message-ID: <534D9974.1070801@gmail.com> On 15/04/14 04:28 PM, Ziad Hatahet wrote: > Would it be worth introducing an own!() macro for this purpose? I came > across this suggestion on the reddit > thread: http://www.reddit.com/r/rust/comments/2340zb/rustdev_removing_foo/ > > -- > Ziad I think using the term "own" for that would greatly increase confusion. An unboxed value is just as owned as one placed in an owned box. I don't really think we need any sugar beyond `to_owned()` for allocating memory dynamically and copying over a string. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From rusty.gates at icloud.com Tue Apr 15 18:20:42 2014 From: rusty.gates at icloud.com (Tommi) Date: Wed, 16 Apr 2014 04:20:42 +0300 Subject: [rust-dev] A generalization of unsafe blocks Message-ID: <76728E6C-234B-4B7D-8C4D-B42D379C1FFF@icloud.com> Disclaimer: I don't know the current status of 'assert' macro, but for the duration of this post I'll assume that it's going to change into a sanity-checking tool and will get compiled away in release builds. I'll also assume that there will be a macro called 'enforce' that will do the same thing as 'assert' except that it won't disappear in release builds. Intro: The 'unsafe' keyword represents the programmer's promise not to write any memory-safety bugs in the block that follows it. Suggestion: Let's add another keyword, say 'bugprone', that would represent the programmer's promise not to write any non-memory-safety bugs in the block that follows it. The effect would be that in such a block, all uses of the 'enforce' macro would disappear. Motivating example: fn foo(x: int, y: int) { enforce!(x < y); ... } It is documented that the function above has a prerequisite x < y and that if it's satisfied, the function call is valid and won't cause a task failure. When the programmer is in a position to know that the prerequisite is satisfied, he could use this new keyword to make all 'enforce' statements in 'foo' disappear: bugprone { foo(x, y) } From danielmicay at gmail.com Tue Apr 15 18:34:30 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 15 Apr 2014 21:34:30 -0400 Subject: [rust-dev] A generalization of unsafe blocks In-Reply-To: <76728E6C-234B-4B7D-8C4D-B42D379C1FFF@icloud.com> References: <76728E6C-234B-4B7D-8C4D-B42D379C1FFF@icloud.com> Message-ID: <534DDE26.2050001@gmail.com> On 15/04/14 09:20 PM, Tommi wrote: > Disclaimer: > I don't know the current status of 'assert' macro, but for the duration of this post I'll assume that it's going to change into a sanity-checking tool and will get compiled away in release builds. I'll also assume that there will be a macro called 'enforce' that will do the same thing as 'assert' except that it won't disappear in release builds. > > Intro: > The 'unsafe' keyword represents the programmer's promise not to write any memory-safety bugs in the block that follows it. > > Suggestion: > Let's add another keyword, say 'bugprone', that would represent the programmer's promise not to write any non-memory-safety bugs in the block that follows it. The effect would be that in such a block, all uses of the 'enforce' macro would disappear. > > Motivating example: > fn foo(x: int, y: int) { > enforce!(x < y); > ... > } > It is documented that the function above has a prerequisite x < y and that if it's satisfied, the function call is valid and won't cause a task failure. When the programmer is in a position to know that the prerequisite is satisfied, he could use this new keyword to make all 'enforce' statements in 'foo' disappear: > bugprone { foo(x, y) } This would require compiling the functions again, and assumes the `enforce!()` macro is only used to handle safety critical preconditions. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From singingboyo at gmail.com Tue Apr 15 18:39:41 2014 From: singingboyo at gmail.com (Brandon Sanderson) Date: Tue, 15 Apr 2014 18:39:41 -0700 Subject: [rust-dev] A generalization of unsafe blocks In-Reply-To: <76728E6C-234B-4B7D-8C4D-B42D379C1FFF@icloud.com> References: <76728E6C-234B-4B7D-8C4D-B42D379C1FFF@icloud.com> Message-ID: Similar to what Daniel said, I don't think this works nicely unless all possible calls to foo are enclosed with this keyword. The code for enforce! would be part of foo, and called from multiple locations. If some disable it and some don't, then what? In general, I'd be against allowing disabling of something like 'enforce!'. The whole point of using such a macro would be to say "Never let this be false. If it is, fail so that it can't cause bigger problems". Your 'bugprone' keyword removes the certainty this offers. In general, I think safety enforced within a function should not be removable by callers of said function. Basically, that makes coding those safety assurances useless. If you want the checks to be removable, use assert. - Brandon -------------- next part -------------- An HTML attachment was scrubbed... URL: From ecreed at cs.washington.edu Tue Apr 15 18:48:22 2014 From: ecreed at cs.washington.edu (Eric Reed) Date: Tue, 15 Apr 2014 18:48:22 -0700 Subject: [rust-dev] Specifying lifetimes in return types of overloaded operators In-Reply-To: References: Message-ID: Could you provide a code sample that causes this error? On Tue, Apr 15, 2014 at 6:28 AM, Artella Coding < artella.coding at googlemail.com> wrote: > > Currently if I try to specify lifetimes in the return types of overloaded > operators like Index ([]), I get an error message : > > "method `index` has an incompatible type for trait: expected concrete > lifetime, but found bound lifetime parameter &" > > Why has this restriction been placed, given that I can write custom > functions which can have bounded lifetimes specifications in the return > type? > > Thanks > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Tue Apr 15 20:18:53 2014 From: rusty.gates at icloud.com (Tommi) Date: Wed, 16 Apr 2014 06:18:53 +0300 Subject: [rust-dev] A generalization of unsafe blocks In-Reply-To: <534DDE26.2050001@gmail.com> References: <76728E6C-234B-4B7D-8C4D-B42D379C1FFF@icloud.com> <534DDE26.2050001@gmail.com> Message-ID: <988F8DEA-2265-4BAA-B3AC-EE34FBF535EF@icloud.com> On 2014-04-16, at 4:34, Daniel Micay wrote: > On 15/04/14 09:20 PM, Tommi wrote: >> Disclaimer: >> I don't know the current status of 'assert' macro, but for the duration of this post I'll assume that it's going to change into a sanity-checking tool and will get compiled away in release builds. I'll also assume that there will be a macro called 'enforce' that will do the same thing as 'assert' except that it won't disappear in release builds. >> >> Intro: >> The 'unsafe' keyword represents the programmer's promise not to write any memory-safety bugs in the block that follows it. >> >> Suggestion: >> Let's add another keyword, say 'bugprone', that would represent the programmer's promise not to write any non-memory-safety bugs in the block that follows it. The effect would be that in such a block, all uses of the 'enforce' macro would disappear. >> >> Motivating example: >> fn foo(x: int, y: int) { >> enforce!(x < y); >> ... >> } >> It is documented that the function above has a prerequisite x < y and that if it's satisfied, the function call is valid and won't cause a task failure. When the programmer is in a position to know that the prerequisite is satisfied, he could use this new keyword to make all 'enforce' statements in 'foo' disappear: >> bugprone { foo(x, y) } > > This would require compiling the functions again, and assumes the > `enforce!()` macro is only used to handle safety critical preconditions. > Yes, the 'enforce' macro would be coupled with the 'bugprone' keyword, that's the idea. But, if it's too much complexity or code-bloat to make two versions of functions, then perhaps I'll change my suggestion to something like D's input contracts. That is, a programmer specifies that a function 'foo' has a certain 'precondition' function which checks the arguments passed to 'foo' and fails if they're not valid. If the arguments passed to 'foo' are determined valid by the 'precondition' function, then the function 'foo' is called. Then, the programmer can force the compiler to omit the call to the 'precondition' function by wrapping the call to 'foo' in a 'bugprone' block. Something like: fn foo(x: int, y: int) -> int precondition { x < y || fail!(); } { // function block ... } ... and the following could be a shorthand for the above: fn foo(x: int, y: int) -> int precondition x < y { // function block ... } Or, we can use the keyword 'in' instead of 'precondition' like D does, or 'if'. From rusty.gates at icloud.com Tue Apr 15 20:43:44 2014 From: rusty.gates at icloud.com (Tommi) Date: Wed, 16 Apr 2014 06:43:44 +0300 Subject: [rust-dev] A generalization of unsafe blocks In-Reply-To: References: <76728E6C-234B-4B7D-8C4D-B42D379C1FFF@icloud.com> Message-ID: <63DEA62D-A257-44A1-9E56-E15249280253@icloud.com> On 2014-04-16, at 4:39, Brandon Sanderson wrote: > In general, I'd be against allowing disabling of something like 'enforce!'. The whole point of using such a macro would be to say "Never let this be false. If it is, fail so that it can't cause bigger problems". Your 'bugprone' keyword removes the certainty this offers. > Yes, perhaps this potentially disappearing macro shouldn't be named 'enforce' but rather something like 'check_precondition'. The macro named 'enforce' would be guaranteed to stick around no matter what, and the macro named 'assert' would disappear in release builds. > In general, I think safety enforced within a function should not be removable by callers of said function. Basically, that makes coding those safety assurances useless. > I think the precondition checking should be removable by the caller of the function when the caller has already checked or otherwise knows that the precondition is satisfied. It would be silly to check the precondition twice. Coding those bug-safety checks isn't useless, because anyone who writes a straight-forward call to my function gets that safety. The programmer needs to explicitly think and make his code uglier to remove those bug-safety checks. > If you want the checks to be removable, use assert. > If I use 'assert' to verify input, I loose all bug-safety in release mode without any guarantee that the caller of the function has passed in arguments that satisfy the preconditions. -------------- next part -------------- An HTML attachment was scrubbed... URL: From comexk at gmail.com Tue Apr 15 21:21:20 2014 From: comexk at gmail.com (comex) Date: Wed, 16 Apr 2014 00:21:20 -0400 Subject: [rust-dev] Removing ~"foo" In-Reply-To: <534D6897.6080202@mozilla.com> References: <534D6897.6080202@mozilla.com> Message-ID: On Tue, Apr 15, 2014 at 1:12 PM, Patrick Walton wrote: > Hi everyone, > > I'd like to remove the `~"foo"` literal syntax for owned strings in both > expressions and patterns. After dynamically sized types, this syntax is the > last remnant of the strange parser behavior by which the parser does > something different for `~"foo"` and `~("foo")` (i.e. by which it looks at > the next token when it sees a sigil and does something different than it > would otherwise). If I have x: &[char, ..5], I can use ~*x to get an owned version without a lot of typing. Would it be too insane to have that work for &[char] or &str with DST? From pcwalton at mozilla.com Wed Apr 16 00:14:45 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Wed, 16 Apr 2014 00:14:45 -0700 Subject: [rust-dev] Removing ~"foo" In-Reply-To: References: <534D6897.6080202@mozilla.com> Message-ID: <534E2DE5.8000309@mozilla.com> On 4/15/14 9:21 PM, comex wrote: > If I have x: &[char, ..5], I can use ~*x to get an owned version > without a lot of typing. Would it be too insane to have that work for > &[char] or &str with DST? Yes, I believe that will work just fine. Niko will have to answer for sure because I don't recall with 100% certainty that we could make that work, but I know we discussed this. Patrick From artella.coding at googlemail.com Tue Apr 15 22:23:29 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Wed, 16 Apr 2014 06:23:29 +0100 Subject: [rust-dev] Specifying lifetimes in return types of overloaded operators In-Reply-To: References: Message-ID: Hi Eric, this is an example of code which gives the error : ************************************************************ struct Cls { vec : ~[~int] } /* Does not compile, yielding error message : "method `index` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter &" */ impl<'a> Index for Cls { fn index(&'a self, i: &uint) -> &'a ~int { let val = &'a self.vec[*i]; return val; } } fn main(){} ************************************************************ It is easy to write a function which does the exact same thing (for the struct above) and has a return type with a bounded lifetime, and therefore it does not make sense to me why operator overloading would be restricted in this fashion (i.e. restricted to return concrete lifetimes). Thanks. On Wed, Apr 16, 2014 at 2:48 AM, Eric Reed wrote: > Could you provide a code sample that causes this error? > > > On Tue, Apr 15, 2014 at 6:28 AM, Artella Coding < > artella.coding at googlemail.com> wrote: > >> >> Currently if I try to specify lifetimes in the return types of overloaded >> operators like Index ([]), I get an error message : >> >> "method `index` has an incompatible type for trait: expected concrete >> lifetime, but found bound lifetime parameter &" >> >> Why has this restriction been placed, given that I can write custom >> functions which can have bounded lifetimes specifications in the return >> type? >> >> Thanks >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Wed Apr 16 12:09:18 2014 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Thu, 17 Apr 2014 05:09:18 +1000 Subject: [rust-dev] Specifying lifetimes in return types of overloaded operators In-Reply-To: References: Message-ID: <40B8254E-E96F-47FE-89E2-B99B54E9AC78@yahoo.com.au> For one, the Index trait is in dire need of an overhaul. In respect to the operator traits in general, I have actually been thinking of submitting an RFC proposing that they take thier parameters by-value instead of by-ref. That would remove the auto-ref behaviour of the operators which is more consistent with the rest of Rust: impl<'a, 'b, T> Mul<&'b Mat, Mat> for &'a Mat { fn mul(&'a self, other: &'b Mat) -> T { ... } } let m2: Mat<_> = &m0 * &m1; ~Brendan On 16 Apr 2014, at 3:23 pm, Artella Coding wrote: > Hi Eric, this is an example of code which gives the error : > > ************************************************************ > struct Cls { > vec : ~[~int] > } > > /* > Does not compile, yielding error message : > > "method `index` has an incompatible type for trait: > expected concrete lifetime, but found bound lifetime > parameter &" > */ > impl<'a> Index for Cls { > fn index(&'a self, i: &uint) -> &'a ~int { > let val = &'a self.vec[*i]; > return val; > } > } > > fn main(){} > ************************************************************ > > It is easy to write a function which does the exact same thing (for the struct above) and has a return type with a bounded lifetime, and therefore it does not make sense to me why operator overloading would be restricted in this fashion (i.e. restricted to return concrete lifetimes). Thanks. > > > > On Wed, Apr 16, 2014 at 2:48 AM, Eric Reed wrote: > Could you provide a code sample that causes this error? > > > On Tue, Apr 15, 2014 at 6:28 AM, Artella Coding wrote: > > Currently if I try to specify lifetimes in the return types of overloaded operators like Index ([]), I get an error message : > > "method `index` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter &" > > Why has this restriction been placed, given that I can write custom functions which can have bounded lifetimes specifications in the return type? > > Thanks > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From slabode at aim.com Wed Apr 16 16:23:35 2014 From: slabode at aim.com (SiegeLord) Date: Wed, 16 Apr 2014 19:23:35 -0400 Subject: [rust-dev] Specifying lifetimes in return types of overloaded operators In-Reply-To: <40B8254E-E96F-47FE-89E2-B99B54E9AC78@yahoo.com.au> References: <40B8254E-E96F-47FE-89E2-B99B54E9AC78@yahoo.com.au> Message-ID: <534F10F7.4010404@aim.com> On 04/16/2014 03:09 PM, Brendan Zabarauskas wrote: > For one, the Index trait is in dire need of an overhaul. > > In respect to the operator traits in general, I have actually been thinking of submitting an RFC proposing that they take thier parameters by-value instead of by-ref. That would remove the auto-ref behaviour of the operators which is more consistent with the rest of Rust: > > > impl<'a, 'b, T> Mul<&'b Mat, Mat> for &'a Mat { > fn mul(&'a self, other: &'b Mat) -> T { ... } > } > > let m2: Mat<_> = &m0 * &m1; > It's not super clear to me how this is different from what you can do right now, e.g. here's the Mul implementation from my linear algebra library: impl<'l, RHS: VectorGet + Clone> Mul> for &'l Vector { fn mul(&self, rhs: &RHS) -> VectorBinOp<&'l Vector, RHS, OpMul> { VectorBinOp::new(self.clone(), rhs.clone(), OpMul::new()) } } impl<'l> VectorGet for &'l Vector { ... } The usage syntax (with the explicit borrowing and all) is the same. -SL From alex at crichton.co Wed Apr 16 17:11:41 2014 From: alex at crichton.co (Alex Crichton) Date: Wed, 16 Apr 2014 17:11:41 -0700 Subject: [rust-dev] Keeping up with Breaking Changes Message-ID: Greetings Rustlers! Projects such as cargo and Servo have recently expressed interest in having a "breaking changes" changelog as part of the rust repository. It's often difficult for those not closely tied to the compiler itself to keep up with all the changes that are getting made. Additionally, I imagine that some sort of changelog such as this would be quite useful to others! With this in mind, we're going to introduce two new measures to help developers port code to newer versions of Rust. The first is to produce a "breaking changes log" of changes to the language and its libraries that may break existing code, *along with instructions for porting*. The second is to use the #[deprecated] attribute more aggressively to instruct the compiler to inform users how to upgrade their code. # A log of Breaking Changes The way we've decided to go about doing this is to start being stricter about the content of commit messages. Any commit which is a breaking change will be required to adhere to a particular template. In doing this, we hope to avoid merge conflicts on one literal changelog file, and we also hope to leverage what git already gives us. Note that this requires isolating the breaking change to a single commit instead of having extra changes leak into the commit. If multiple distinct breaking changes are made, they will require separate commits. The precise definition of a breaking change will likely be an evolving concept, but there are a few classes of changes that definitely count: * Changing the semantics of existing functionality in the standard libraries * Removing functionality from the standard libraries * Modifications to the language itself (parsing and semantics) The template which breaking changes will be required to look like is: First, a brief one-line summary of the change Second, take as long as is necessary to explain exactly what the change is, why it's being changed, what it can be replaced with (if applicable) and general guidelines about dealing with the change. In addition to a few paragraphs about the change itself, the literal string "[breaking-change]" must appear at the end of the commit message in order to indicate that it is a commit that has a breaking change. This will allow filtering commits on this string to only take a look at breaking changes. [breaking-change] To get a log of breaking changes, you can use git-log: git log --grep breaking-change # Exclude bors merge commits git log --grep breaking-change --no-merges # Usage of #[deprecated] In addition to a stricter policy around commit messages, we're going to start encouraging more aggressive use of the #[deprecated] attribute to help transitioning code. A good example of this recently is when the `shuffle_mut` function was renamed to `shuffle`. The original function had an attribute that looked like: #[deprecated = "function renamed to `shuffle`"] We aren't yet going to require that the old function retain its functionality, it is acceptable to replace it with a fail!()-ing stub for now. The compilation warning should be a good enough indicator about what needs to be changed. The deprecated functions themselves aren't expected to stick around for all eternity. By 1.0 we will clean out all #[deprecated] functionality, and before then we'll likely leave in #[deprecated] functions for about a month or so. # Be on the lookout! With these two guidelines in place, we hope to ease the pain of upgrading through versions of rust while it's still under rapid development. Reviewers, be sure to keep an eye out for breaking changes in the future and make sure that the that these measures are followed! From me at nongraphical.com Wed Apr 16 17:39:35 2014 From: me at nongraphical.com (Frank Huang) Date: Wed, 16 Apr 2014 17:39:35 -0700 Subject: [rust-dev] Storing Handle (for Select) in a collection causes a crash Message-ID: Hello all, I have two somewhat related questions to ask you fine folks. I'm trying to implement something that selects on a variable number of receivers, which can change during program execution. I've been attempting to do so by making Handles to those receivers and storing the handles in a HashMap, but this causes the program to crash when Select::wait() is called. For example, here's a small case which illustrates the problem: fn main() { let mut handles = HashMap::new(); let (tx, rx): (Sender, Receiver) = channel(); spawn(proc() { tx.send(10); }); let select = Select::new(); let mut h = select.handle(&rx); unsafe { h.add(); } handles.insert(h.id(), h); let id = select.wait(); let handle = handles.get_mut(&id); let num = handle.recv(); println!("num = {}", num); } The segmentation fault happens at the line "let id = select.wait()". I can confirm that this happens on OSX and armhf. I can confirm that this also happens with a Vec. BTW thanks to mcpherrin on IRC for suggesting the HashMap solution. Second somewhat related question: why can't I write this? fn main() { let mut v = Vec::new(); v.push(10); // get last item let n = v.get_mut(v.len()-1); println!("item = {}", *n); } For this program, the compiler complains at the line with v.get_mut that "cannot borrow `v` as immutable because is is also borrowed as mutable". Is there another way to retrieve, mutably, the last element of a vector? (this is relevant if I want to have a vector of Handles, since Handle::recv() requires &mut self) Thanks for your help! Frank -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcwalton at mozilla.com Wed Apr 16 17:41:21 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Wed, 16 Apr 2014 17:41:21 -0700 Subject: [rust-dev] Storing Handle (for Select) in a collection causes a crash In-Reply-To: References: Message-ID: <534F2331.2080804@mozilla.com> On 4/16/14 5:39 PM, Frank Huang wrote: > Second somewhat related question: why can't I write this? > > fn main() { > let mut v = Vec::new(); > v.push(10); > // get last item > let n = v.get_mut(v.len()-1); > println!("item = {}", *n); > } > > For this program, the compiler complains at the line with v.get_mut that > "cannot borrow `v` as immutable because is is also borrowed as mutable". > Is there another way to retrieve, mutably, the last element of a vector? > (this is relevant if I want to have a vector of Handles, since > Handle::recv() requires &mut self) Unnest it and assign "v.len()" to a temporary first. This is a borrow check annoyance that will probably be fixed at some point. In the meantime we should probably have a better error message. Patrick From alex at crichton.co Wed Apr 16 17:45:58 2014 From: alex at crichton.co (Alex Crichton) Date: Wed, 16 Apr 2014 17:45:58 -0700 Subject: [rust-dev] Storing Handle (for Select) in a collection causes a crash In-Reply-To: References: Message-ID: > unsafe { h.add(); } > > handles.insert(h.id(), h); This is why the add method is unsafe: "This method is unsafe because it requires that the Handle is not moved while it is added to the Select set." You're moving the handle after it's been added, which later will cause a segfault. From me at nongraphical.com Wed Apr 16 17:55:07 2014 From: me at nongraphical.com (Frank Huang) Date: Wed, 16 Apr 2014 17:55:07 -0700 Subject: [rust-dev] Storing Handle (for Select) in a collection causes a crash In-Reply-To: References: Message-ID: Ah, yes I failed to see the warning in the documentation. add()ing the handle after moving it into the hashmap does seem to make things better. Thanks for your help! Frank On Wed, Apr 16, 2014 at 5:45 PM, Alex Crichton wrote: > > unsafe { h.add(); } > > > > handles.insert(h.id(), h); > > This is why the add method is unsafe: "This method is unsafe because > it requires that the Handle is not moved while it is added to the > Select set." > > You're moving the handle after it's been added, which later will cause > a segfault. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Wed Apr 16 22:20:39 2014 From: rusty.gates at icloud.com (Tommi) Date: Thu, 17 Apr 2014 08:20:39 +0300 Subject: [rust-dev] Expected fields in traits Message-ID: I can't figure out how GitHub works, so can someone please commit the following RFC, thank you: - Start Date: 2014-04-17 - RFC PR #: - Rust Issue #: # Summary Add the ability to specify that a type, which implements a certain trait, must have certain set of fields (data members) of certain types so that the trait may then use those expected fields in the methods it provides (has a default definition for). # Motivation This enables much more code re-use than traits currently do. This also provides what other languages call "multiple inheritance" without facing the so called "diamond problem". # Detailed design A trait may specify a set of expected fields. For each expected field the trait definition must provide a type and a unique name. When a type implements such a trait, it must specify which of its fields correspond with each of the trait's expected fields. The types of the fields must match with the types of the corresponding expected fields of the trait and no two fields of the type may map to the same expected field of the trait. The type implementing the trait may have more fields than there are expected fields in the trait, and the order of fields doesn't matter. The knowledge of which field each expected field corresponds to can then be used by the trait to locate and use the data it expects to find by adding the offset of the field to a pointer to the first byte of ```self``` and by re-interpreting the pointed-to data as the expected field's type. What follows next is an example code snippet where I present the syntax I propose for this feature. And after that I'll provide the (currently valid) Rust code which the first example would conceptually correspond with. Example 1: The proposed syntax ``` trait Unify { Self { x: T, y: T } fn unify(&mut self) { self.y = self.x.clone(); } } struct Stuff { a: u32, b: u32 } impl Unify for Stuff { Stuff { x => a, y => b } } ``` Example 2: The code that corresponds with example 1 ``` use std::cast::transmute; trait Unify { fn x_offset(&self) -> int; // This should be replaced with an associated constant once we get those fn y_offset(&self) -> int; // This should be replaced with an associated constant once we get those fn unify(&mut self) { unsafe { let self_x: *mut T = transmute::<*mut u8, *mut T>(transmute::<&mut Self, *mut u8>(self).offset(self.x_offset())); let self_y: *mut T = transmute::<*mut u8, *mut T>(transmute::<&mut Self, *mut u8>(self).offset(self.y_offset())); *self_y = (*self_x).clone(); } } } struct Stuff { a: u32, // is at offset 0 bytes b: u32 // is at offset 4 bytes } impl Unify for Stuff { fn x_offset(&self) -> int { 0 // The offset of field 'a' } fn y_offset(&self) -> int { 4 // The offset of field 'b' } } ``` # Alternatives Code re-use is possible also with macros, but this solution is much more elegant and may allow better opportunities for the compiler to reduce template code-bloat. # Unresolved questions The syntax is completely open to debate. From flaper87 at gmail.com Thu Apr 17 00:21:15 2014 From: flaper87 at gmail.com (Flaper87) Date: Thu, 17 Apr 2014 09:21:15 +0200 Subject: [rust-dev] Keeping up with Breaking Changes In-Reply-To: References: Message-ID: 2014-04-17 2:11 GMT+02:00 Alex Crichton : > The template which breaking changes will be required to look like is: > > First, a brief one-line summary of the change > > Second, take as long as is necessary to explain exactly what the > change is, > why it's being changed, what it can be replaced with (if applicable) > and > general guidelines about dealing with the change. > > In addition to a few paragraphs about the change itself, the literal > string > "[breaking-change]" must appear at the end of the commit message in > order > to indicate that it is a commit that has a breaking change. This will > allow > filtering commits on this string to only take a look at breaking > changes. > > [breaking-change] > Sometimes, the breaking change is split in several commits. I'd recommend to add to the breaking change tag the number of the GH issue (I wanted to propose a "change tag" but I don't think that will end well). I don't expect breaking changes to happen without a GH issue baking them - or at least, I don't think that should happen. Tagging the last commit of the series should probably be enough but, for completeness, I think they should all be tagged. This will produce a more complete output when `grepping` for breaking changes. > > To get a log of breaking changes, you can use git-log: > > git log --grep breaking-change > > # Exclude bors merge commits > git log --grep breaking-change --no-merges > > # Usage of #[deprecated] > > In addition to a stricter policy around commit messages, we're going to > start > encouraging more aggressive use of the #[deprecated] attribute to help > transitioning code. A good example of this recently is when the > `shuffle_mut` > function was renamed to `shuffle`. The original function had an attribute > that > looked like: > > #[deprecated = "function renamed to `shuffle`"] > > We aren't yet going to require that the old function retain its > functionality, > it is acceptable to replace it with a fail!()-ing stub for now. The > compilation > warning should be a good enough indicator about what needs to be changed. > > The deprecated functions themselves aren't expected to stick around for all > eternity. By 1.0 we will clean out all #[deprecated] functionality, and > before > then we'll likely leave in #[deprecated] functions for about a month or so. > I think we should retain the previous functionality. Since it's already there, I don't think it will be of any harm (in most of the cases). Also, I think it'd be good to keep the deprecated function for at least 1 release. I believe this is a good practice and gives users of that function enough time to migrate. This obviously doesn't make much sense if we replace the functionality with a `fail` > # Be on the lookout! > > With these two guidelines in place, we hope to ease the pain of upgrading > through versions of rust while it's still under rapid development. > Reviewers, be > sure to keep an eye out for breaking changes in the future and make sure > that > the that these measures are followed! > I'm really happy to see this happening! -- Flavio (@flaper87) Percoco http://www.flaper87.com http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From loebel.marvin at gmail.com Thu Apr 17 01:25:10 2014 From: loebel.marvin at gmail.com (=?UTF-8?Q?Marvin_L=C3=B6bel?=) Date: Thu, 17 Apr 2014 10:25:10 +0200 Subject: [rust-dev] Expected fields in traits In-Reply-To: References: Message-ID: Hi, Im actually working on a more detailed version of this proposal myself, covering more of the problem space (thin pointer, implications, etc). However, I hadn't yet considered the possibility of remapping the fields, instead assuming a simple same-name prefix restriction. Would you mind me taking this RFC over and including it into my proposal? It's not ready to post yet though. Am 17.04.2014 07:20 schrieb "Tommi" : > I can't figure out how GitHub works, so can someone please commit the > following RFC, thank you: > > - Start Date: 2014-04-17 > - RFC PR #: > - Rust Issue #: > > # Summary > > Add the ability to specify that a type, which implements a certain trait, > must have certain set of fields (data members) of certain types so that the > trait may then use those expected fields in the methods it provides (has a > default definition for). > > # Motivation > > This enables much more code re-use than traits currently do. This also > provides what other languages call "multiple inheritance" without facing > the so called "diamond problem". > > # Detailed design > > A trait may specify a set of expected fields. For each expected field the > trait definition must provide a type and a unique name. When a type > implements such a trait, it must specify which of its fields correspond > with each of the trait's expected fields. The types of the fields must > match with the types of the corresponding expected fields of the trait and > no two fields of the type may map to the same expected field of the trait. > The type implementing the trait may have more fields than there are > expected fields in the trait, and the order of fields doesn't matter. The > knowledge of which field each expected field corresponds to can then be > used by the trait to locate and use the data it expects to find by adding > the offset of the field to a pointer to the first byte of ```self``` and by > re-interpreting the pointed-to data as the expected field's type. > > What follows next is an example code snippet where I present the syntax I > propose for this feature. And after that I'll provide the (currently valid) > Rust code which the first example would conceptually correspond with. > > Example 1: The proposed syntax > ``` > trait Unify { > Self { > x: T, > y: T > } > > fn unify(&mut self) { > self.y = self.x.clone(); > } > } > > struct Stuff { > a: u32, > b: u32 > } > > impl Unify for Stuff { > Stuff { > x => a, > y => b > } > } > ``` > > Example 2: The code that corresponds with example 1 > ``` > use std::cast::transmute; > > trait Unify { > fn x_offset(&self) -> int; // This should be replaced with an > associated constant once we get those > fn y_offset(&self) -> int; // This should be replaced with an > associated constant once we get those > > fn unify(&mut self) { > unsafe { > let self_x: *mut T = transmute::<*mut u8, *mut > T>(transmute::<&mut Self, *mut u8>(self).offset(self.x_offset())); > let self_y: *mut T = transmute::<*mut u8, *mut > T>(transmute::<&mut Self, *mut u8>(self).offset(self.y_offset())); > > *self_y = (*self_x).clone(); > } > } > } > > struct Stuff { > a: u32, // is at offset 0 bytes > b: u32 // is at offset 4 bytes > } > > impl Unify for Stuff { > fn x_offset(&self) -> int { > 0 // The offset of field 'a' > } > > fn y_offset(&self) -> int { > 4 // The offset of field 'b' > } > } > ``` > > # Alternatives > > Code re-use is possible also with macros, but this solution is much more > elegant and may allow better opportunities for the compiler to reduce > template code-bloat. > > # Unresolved questions > > The syntax is completely open to debate. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From nical.silva at gmail.com Thu Apr 17 01:37:09 2014 From: nical.silva at gmail.com (Nicolas Silva) Date: Thu, 17 Apr 2014 10:37:09 +0200 Subject: [rust-dev] Keeping up with Breaking Changes In-Reply-To: References: Message-ID: This is great, thanks! On Thu, Apr 17, 2014 at 9:21 AM, Flaper87 wrote: > > > > 2014-04-17 2:11 GMT+02:00 Alex Crichton : > > The template which breaking changes will be required to look like is: >> >> First, a brief one-line summary of the change >> >> Second, take as long as is necessary to explain exactly what the >> change is, >> why it's being changed, what it can be replaced with (if applicable) >> and >> general guidelines about dealing with the change. >> >> In addition to a few paragraphs about the change itself, the literal >> string >> "[breaking-change]" must appear at the end of the commit message in >> order >> to indicate that it is a commit that has a breaking change. This will >> allow >> filtering commits on this string to only take a look at breaking >> changes. >> >> [breaking-change] >> > > > Sometimes, the breaking change is split in several commits. I'd recommend > to add to the breaking change tag the number of the GH issue (I wanted to > propose a "change tag" but I don't think that will end well). I don't > expect breaking changes to happen without a GH issue baking them - or at > least, I don't think that should happen. > > Tagging the last commit of the series should probably be enough but, for > completeness, I think they should all be tagged. This will produce a more > complete output when `grepping` for breaking changes. > > >> >> To get a log of breaking changes, you can use git-log: >> >> git log --grep breaking-change >> >> # Exclude bors merge commits >> git log --grep breaking-change --no-merges >> >> # Usage of #[deprecated] >> >> In addition to a stricter policy around commit messages, we're going to >> start >> encouraging more aggressive use of the #[deprecated] attribute to help >> transitioning code. A good example of this recently is when the >> `shuffle_mut` >> function was renamed to `shuffle`. The original function had an attribute >> that >> looked like: >> >> #[deprecated = "function renamed to `shuffle`"] >> >> We aren't yet going to require that the old function retain its >> functionality, >> it is acceptable to replace it with a fail!()-ing stub for now. The >> compilation >> warning should be a good enough indicator about what needs to be changed. >> >> The deprecated functions themselves aren't expected to stick around for >> all >> eternity. By 1.0 we will clean out all #[deprecated] functionality, and >> before >> then we'll likely leave in #[deprecated] functions for about a month or >> so. >> > > I think we should retain the previous functionality. Since it's already > there, I don't think it will be of any harm (in most of the cases). > > Also, I think it'd be good to keep the deprecated function for at least 1 > release. I believe this is a good practice and gives users of that function > enough time to migrate. This obviously doesn't make much sense if we > replace the functionality with a `fail` > > >> # Be on the lookout! >> >> With these two guidelines in place, we hope to ease the pain of upgrading >> through versions of rust while it's still under rapid development. >> Reviewers, be >> sure to keep an eye out for breaking changes in the future and make sure >> that >> the that these measures are followed! >> > > > I'm really happy to see this happening! > > -- > Flavio (@flaper87) Percoco > http://www.flaper87.com > http://github.com/FlaPer87 > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Thu Apr 17 06:01:08 2014 From: rusty.gates at icloud.com (Tommi) Date: Thu, 17 Apr 2014 16:01:08 +0300 Subject: [rust-dev] Expected fields in traits In-Reply-To: References: Message-ID: <30DAB023-27F7-4337-9AB1-63B6145FF710@icloud.com> On 2014-04-17, at 11:25, Marvin L?bel wrote: > Would you mind me taking this RFC over and including it into my proposal? Yes please, by all means. I'm looking forward to your proposal. But actually I just realized that my proposal is essentially just a syntax sugar for a macro producing boiler-plate code. That imaginary macro simply copy pastes the provided method defined in the trait to the trait implementation and replaces each use of an expected field with the actual field that's mapped to it. So, in some sense you could simply think of my example 1 (the one with the imaginary syntax) translating to this (actual Rust code): trait Unify { fn unify(&mut self); } struct Stuff { a: u32, b: u32 } impl Unify for Stuff { fn unify(&mut self) { self.b = self.a.clone(); } } And here's that example 1 again for completeness sake: trait Unify { Self { x: T, y: T } fn unify(&mut self) { self.y = self.x.clone(); } } struct Stuff { a: u32, b: u32 } impl Unify for Stuff { Stuff { x => a, y => b } } But a small and important detail about the compiler implementation is that if there are multiple types that implement Unify with the exactly same field offsets for the expected fields, then the compiler can compile the function Unify::unify for those types just once and use the same function for each type. A simple textual macro with a search & replace is very easy to reason about. -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Thu Apr 17 07:39:15 2014 From: rusty.gates at icloud.com (Tommi) Date: Thu, 17 Apr 2014 17:39:15 +0300 Subject: [rust-dev] Why mod.rs files? Message-ID: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> Can someone explain me why the module system maps to the file system in the way it does? The problem is that you can end up with these modules named mod.rs instead of the more informative names. If you have the following modules: foo foo::lut bar bar::lut ...that maps to files and folders as such: foo/mod.rs foo/lut.rs bar/mod.rs bar/lut.rs ...but why not map such modules to files and folders as the following: foo.rs foo/lut.rs bar.rs bar/lut.rs ...and have each module informatively named. From niko at alum.mit.edu Thu Apr 17 08:56:12 2014 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 17 Apr 2014 11:56:12 -0400 Subject: [rust-dev] Why mod.rs files? In-Reply-To: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> References: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> Message-ID: <20140417155612.GB18037@Mr-Bennet> On Thu, Apr 17, 2014 at 05:39:15PM +0300, Tommi wrote: > ...but why not map such modules to files and folders as the following: > > foo.rs > foo/lut.rs > bar.rs > bar/lut.rs > > ...and have each module informatively named. This used to be our system and we found it very confusing in practice. Basically the code that was logically related to subsystem `foo` was divided between two directories, and that caused mental discord. I can't exactly explain *why*, but it certainly did, and hence we were unhappy enough to switch over to the current system. Note that you can use the `#[path=...]` attribute to override the defaults if you choose. Niko [1] If you are using emacs, I strongly suggest enabling the uniquify settings . Otherwise you get useless buffer names like `mod.rs<2>` rather than `foo/mod.rs` and so on. I would hope that vim and SublimeText2 and whatever new-fangled editors people are using these days have similar options. From edward.yu.wang at gmail.com Thu Apr 17 08:55:57 2014 From: edward.yu.wang at gmail.com (Edward Wang) Date: Thu, 17 Apr 2014 23:55:57 +0800 Subject: [rust-dev] Shouldn't task::try(...).unwrap() fail to compile? Message-ID: It current can compile, but judging from signatures: std::task::try is pub fn try(f: proc(): Send -> T) -> Result std::result::unwrap on the other hand is impl Result { fn unwrap(self) -> T {...} } There's no way the error part of result from task::try(...) can fulfil Show so it shouldn't compile. Though to ask the list first before filing a bug report. Regards, Edward -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Thu Apr 17 09:10:07 2014 From: alex at crichton.co (Alex Crichton) Date: Thu, 17 Apr 2014 09:10:07 -0700 Subject: [rust-dev] Shouldn't task::try(...).unwrap() fail to compile? In-Reply-To: References: Message-ID: The ~Any type has a special implementation of Show: https://github.com/mozilla/rust/blob/master/src/libstd/any.rs#L151-L155 I believe it was primarily used in failure messages originally (you can fail a task with ~Any) On Thu, Apr 17, 2014 at 8:55 AM, Edward Wang wrote: > It current can compile, but judging from signatures: > > std::task::try is pub fn try(f: proc(): Send -> T) -> Result ~Any:Send> > std::result::unwrap on the other hand is impl Result { fn > unwrap(self) -> T {...} } > > There's no way the error part of result from task::try(...) can fulfil Show > so it shouldn't compile. > > Though to ask the list first before filing a bug report. > > Regards, > Edward > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From sfackler at gmail.com Thu Apr 17 09:14:21 2014 From: sfackler at gmail.com (Steven Fackler) Date: Thu, 17 Apr 2014 09:14:21 -0700 Subject: [rust-dev] Shouldn't task::try(...).unwrap() fail to compile? In-Reply-To: References: Message-ID: You can use task::try(...).ok().unwrap() for Results with non-Show error types. Steven Fackler On Thu, Apr 17, 2014 at 8:55 AM, Edward Wang wrote: > It current can compile, but judging from signatures: > > std::task::try is pub fn try(f: proc(): Send -> T) -> Result ~Any:Send> > std::result::unwrap on the other hand is impl Result { > fn unwrap(self) -> T {...} } > > There's no way the error part of result from task::try(...) can fulfil > Show so it shouldn't compile. > > Though to ask the list first before filing a bug report. > > Regards, > Edward > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eg1290 at gmail.com Thu Apr 17 09:22:13 2014 From: eg1290 at gmail.com (Evan G) Date: Thu, 17 Apr 2014 11:22:13 -0500 Subject: [rust-dev] Why mod.rs files? In-Reply-To: <20140417155612.GB18037@Mr-Bennet> References: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> <20140417155612.GB18037@Mr-Bennet> Message-ID: Sublime does this automatically. On Thu, Apr 17, 2014 at 10:56 AM, Niko Matsakis wrote: > On Thu, Apr 17, 2014 at 05:39:15PM +0300, Tommi wrote: > > ...but why not map such modules to files and folders as the following: > > > > foo.rs > > foo/lut.rs > > bar.rs > > bar/lut.rs > > > > ...and have each module informatively named. > > This used to be our system and we found it very confusing in practice. > Basically the code that was logically related to subsystem `foo` was > divided between two directories, and that caused mental discord. I > can't exactly explain *why*, but it certainly did, and hence we were > unhappy enough to switch over to the current system. > > Note that you can use the `#[path=...]` attribute to override the > defaults if you choose. > > > Niko > > [1] If you are using emacs, I strongly suggest enabling the uniquify > settings . Otherwise you get > useless buffer names like `mod.rs<2>` rather than `foo/mod.rs` and so > on. I would hope that vim and SublimeText2 and whatever new-fangled > editors people are using these days have similar options. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Thu Apr 17 09:45:32 2014 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Thu, 17 Apr 2014 18:45:32 +0200 Subject: [rust-dev] Why mod.rs files? In-Reply-To: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> References: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> Message-ID: <51899ED4-F60D-4956-A31D-71082AF12C07@mozilla.com> Tommi (cc'ing rust-dev)- I don't know if this is considered an anti-pattern or not, but if you want to structure your files in the manner you describe, you can do so without resorting to `#[path=?]`, assuming you're willing to add a bit of boilerplate to the foo.rs and bar.rs to pull in the modules that are in the subdirectories. I've included a transcript describing a tiny example of your layout ("variant1") versus the mod.rs-based layout ("variant2"). The main difference is that one needs to put declarations of the modules in the subdirectory into a nested private mod (`mod foo { pub mod lut; }`) and a reexport (`pub use lut = self::foo::lut`) within "foo.rs" in the parent directory. (In case its not obvious from the context, it is legal to put the `foo` mod at either

/foo.rs or at /foo/mod.rs; the compiler will look in both places for it. If you put a file for the `foo` mod in both places, the compiler signals an error since that is an ambiguity.) Cheers, -Felix Transcript illustrating directory layout and how to make your code accommodate either layout. % find variant1 -type file variant1/foo/lut.rs variant1/foo.rs variant1/main.rs % find variant2 -type file variant2/foo/lut.rs variant2/foo/mod.rs variant2/main.rs % rustc variant1/main.rs && ./main m/variant1/foo.rs m/variant1/foo/lut.rs % rustc variant2/main.rs && ./main m/variant2/foo/mod.rs m/variant2/foo/lut.rs % find variant1 -type file -exec echo == {} == \; -exec cat {} \; == variant1/foo/lut.rs == pub fn lut() -> ~str { ~"m/variant1/foo/lut.rs" } == variant1/foo.rs == pub use lut = self::foo::lut; pub fn foo() -> ~str { ~"m/variant1/foo.rs" } mod foo { pub mod lut; } == variant1/main.rs == mod foo; fn main() { println!("{} {}", foo::foo(), foo::lut::lut()); } % find variant2 -type file -exec echo == {} == \; -exec cat {} \; == variant2/foo/lut.rs == pub fn lut() -> ~str { ~"m/variant2/foo/lut.rs" } == variant2/foo/mod.rs == pub fn foo() -> ~str { ~"m/variant2/foo/mod.rs" } pub mod lut; == variant2/main.rs == mod foo; fn main() { println!("{} {}", foo::foo(), foo::lut::lut()); } % On 17 Apr 2014, at 16:39, Tommi wrote: > Can someone explain me why the module system maps to the file system in the way it does? The problem is that you can end up with these modules named mod.rs instead of the more informative names. If you have the following modules: > > foo > foo::lut > bar > bar::lut > > ...that maps to files and folders as such: > > foo/mod.rs > foo/lut.rs > bar/mod.rs > bar/lut.rs > > ...but why not map such modules to files and folders as the following: > > foo.rs > foo/lut.rs > bar.rs > bar/lut.rs > > ...and have each module informatively named. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From banderson at mozilla.com Thu Apr 17 11:16:12 2014 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 17 Apr 2014 11:16:12 -0700 Subject: [rust-dev] Keeping up with Breaking Changes In-Reply-To: References: Message-ID: <53501A6C.9070505@mozilla.com> On 04/17/2014 12:21 AM, Flaper87 wrote: > > > > 2014-04-17 2:11 GMT+02:00 Alex Crichton >: > > The template which breaking changes will be required to look like is: > > First, a brief one-line summary of the change > > Second, take as long as is necessary to explain exactly what > the change is, > why it's being changed, what it can be replaced with (if > applicable) and > general guidelines about dealing with the change. > > In addition to a few paragraphs about the change itself, the > literal string > "[breaking-change]" must appear at the end of the commit > message in order > to indicate that it is a commit that has a breaking change. > This will allow > filtering commits on this string to only take a look at > breaking changes. > > [breaking-change] > > > > Sometimes, the breaking change is split in several commits. I'd > recommend to add to the breaking change tag the number of the GH issue > (I wanted to propose a "change tag" but I don't think that will end > well). I don't expect breaking changes to happen without a GH issue > baking them - or at least, I don't think that should happen. > > Tagging the last commit of the series should probably be enough but, for > completeness, I think they should all be tagged. This will produce a > more complete output when `grepping` for breaking changes. I hope it's not typically hard to isolate the "break" to a single commit, particularly when it comes to library refactoring, which is where most of the breakage is going to be going forward. > > > To get a log of breaking changes, you can use git-log: > > git log --grep breaking-change > > # Exclude bors merge commits > git log --grep breaking-change --no-merges > > # Usage of #[deprecated] > > In addition to a stricter policy around commit messages, we're going > to start > encouraging more aggressive use of the #[deprecated] attribute to help > transitioning code. A good example of this recently is when the > `shuffle_mut` > function was renamed to `shuffle`. The original function had an > attribute that > looked like: > > #[deprecated = "function renamed to `shuffle`"] > > We aren't yet going to require that the old function retain its > functionality, > it is acceptable to replace it with a fail!()-ing stub for now. The > compilation > warning should be a good enough indicator about what needs to be > changed. > > The deprecated functions themselves aren't expected to stick around > for all > eternity. By 1.0 we will clean out all #[deprecated] functionality, > and before > then we'll likely leave in #[deprecated] functions for about a month > or so. > > > I think we should retain the previous functionality. Since it's already > there, I don't think it will be of any harm (in most of the cases). > > Also, I think it'd be good to keep the deprecated function for at least > 1 release. I believe this is a good practice and gives users of that > function enough time to migrate. This obviously doesn't make much sense > if we replace the functionality with a `fail` > > > # Be on the lookout! > > With these two guidelines in place, we hope to ease the pain of > upgrading > through versions of rust while it's still under rapid development. > Reviewers, be > sure to keep an eye out for breaking changes in the future and make > sure that > the that these measures are followed! > > > > I'm really happy to see this happening! > > -- > Flavio (@flaper87) Percoco > http://www.flaper87.com > http://github.com/FlaPer87 > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From banderson at mozilla.com Thu Apr 17 11:38:46 2014 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 17 Apr 2014 11:38:46 -0700 Subject: [rust-dev] Why mod.rs files? In-Reply-To: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> References: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> Message-ID: <53501FB6.8080201@mozilla.com> On 04/17/2014 07:39 AM, Tommi wrote: > Can someone explain me why the module system maps to the file system in the way it does? The problem is that you can end up with these modules named mod.rs instead of the more informative names. If you have the following modules: > > foo > foo::lut > bar > bar::lut > > ...that maps to files and folders as such: > > foo/mod.rs > foo/lut.rs > bar/mod.rs > bar/lut.rs > > ...but why not map such modules to files and folders as the following: > > foo.rs > foo/lut.rs > bar.rs > bar/lut.rs > > ...and have each module informatively named. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > We did used to do exactly that, but it was considered very odd that part of a module is defined outside of it's directory and part inside. This structure can still be achieved in Rust with `#[path = "..."]` but it's not the opinionated default. From rusty.gates at icloud.com Thu Apr 17 11:58:20 2014 From: rusty.gates at icloud.com (Tommi) Date: Thu, 17 Apr 2014 21:58:20 +0300 Subject: [rust-dev] Why mod.rs files? In-Reply-To: <20140417155612.GB18037@Mr-Bennet> References: <9E80D053-BF62-41BC-971A-A460AC950374@icloud.com> <20140417155612.GB18037@Mr-Bennet> Message-ID: <926D576A-7CFF-48A4-8B4D-33B472C3B15D@icloud.com> Okay, thanks for explaining the reasoning. I think I'll conform to the standard way of doing things. On 2014-04-17, at 18:56, Niko Matsakis wrote: > On Thu, Apr 17, 2014 at 05:39:15PM +0300, Tommi wrote: >> ...but why not map such modules to files and folders as the following: >> >> foo.rs >> foo/lut.rs >> bar.rs >> bar/lut.rs >> >> ...and have each module informatively named. > > This used to be our system and we found it very confusing in practice. > Basically the code that was logically related to subsystem `foo` was > divided between two directories, and that caused mental discord. I > can't exactly explain *why*, but it certainly did, and hence we were > unhappy enough to switch over to the current system. > > Note that you can use the `#[path=...]` attribute to override the > defaults if you choose. > > > Niko > > [1] If you are using emacs, I strongly suggest enabling the uniquify > settings . Otherwise you get > useless buffer names like `mod.rs<2>` rather than `foo/mod.rs` and so > on. I would hope that vim and SublimeText2 and whatever new-fangled > editors people are using these days have similar options. From rusty.gates at icloud.com Thu Apr 17 20:27:51 2014 From: rusty.gates at icloud.com (Tommi) Date: Fri, 18 Apr 2014 06:27:51 +0300 Subject: [rust-dev] Private trait items Message-ID: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> Could someone please commit this RFC for me, thank you: - Start Date: 2014-04-18 - RFC PR #: - Rust Issue #: # Summary I propose the ability to set trait items (i.e. just methods currently) private as well as public in order to expand the scope of possible use cases of provided methods (i.e. default trait method implementations). I also propose that trait items should be private by default. # Motivation Sometimes a trait may be able to provide a default implementation for a method iff it can use a certain method which only the type that implements the trait is in a position to provide a definition for. Often times such a feedback method is supposed to be only a tool for the trait to be able to define provided methods with, and as such, not supposed to become a part of the public interface of the trait or any type which implements the trait. Therefore such a feedback method should be made private. Trait items should be private by default so that we don't have the need to reintroduce the 'priv' keyword. If in future we get the ability to specify that a certain provided method in a trait is 'final' (i.e. not overridable by the type which implements the trait), then, together with private trait methods, we can use the Non-Virtual Interface (NVI) idiom coined and described here by Herb Sutter: http://www.gotw.ca/publications/mill18.htm # Detailed design One way of looking at private trait methods (or any private trait items) is to see them as private dialog between a trait and a type which implements the trait. This view could lead to a design where no-one else except the trait and the type which implements it is allowed access to such private feedback item. But given how Rust privacy rules work at module boundaries (and also extend access to submodules), it would make sense that access to a private trait item extended from just the trait or the type which implements it to the enclosing module and its submodules. By this logic I suggest the following privacy rules for private trait items: Given that: 1) A trait ```Tr``` specifies a private item ```priv_item``` and is defined in module ```mod_tr``` 3) A type ```Foo``` implements ```Tr``` and is defined in module ```mod_foo``` 3) A type ```Bar``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` 4) A type ```Baz``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` It follows that: 1) ```priv_item``` is accessible from ```mod_tr``` and all its submodules. 2) ```priv_item``` is accessible from ```mod_foo``` and all its submodules iff it is certain at compile-time that it refers to the ```Foo```'s implementation ```priv_item``` 3) ```priv_item``` is accessible from ```mod_bar_and_baz``` and all its submodules iff it is certain at compile-time that it refers to either the ```Bar```'s or ```Baz```'s implementation of ```priv_item``` And ```priv_item``` is not accessible from anywhere else. Example: ``` // in mod_tr.rs pub trait Tr { priv fn priv_item(&self); pub fn do_stuff(&self) { self.priv_item(); // OK } } pub fn do_other_stuff(a: &A) { a.priv_item(); // OK } // in mod_foo.rs use mod_tr::Tr; pub struct Foo; impl Tr for Foo { priv fn priv_item(&self) {} } pub fn do_foo_stuff(foo: &Foo) { foo.priv_item(); // OK } pub fn do_incorrect_stuff(a: &A) { a.priv_item(); // ERROR: "A private trait item Tr::priv_item not accessible from mod_foo" } ``` # Alternatives # Unresolved questions From edward.yu.wang at gmail.com Thu Apr 17 23:42:39 2014 From: edward.yu.wang at gmail.com (Edward Wang) Date: Fri, 18 Apr 2014 14:42:39 +0800 Subject: [rust-dev] Shouldn't task::try(...).unwrap() fail to compile? In-Reply-To: References: Message-ID: Alex, you are right. I need to rephrase my question. Consider the following: pub trait T1 {} pub trait T2 {} impl T1 for ~T2 {} pub struct S; impl T2 for S {} fn check_bounds(_: U) {} fn main() { let x = ~S as ~T2:Send; check_bounds(x); } Should check_bounds fail? It currently compiles, but according to https://github.com/mozilla/rust/issues/5781, trait matching should be invariant. If that's true, ~T2 and ~T2:Send would be different so here we only have a T1 implementation for ~T2, not ~T2:Send, an error. Then task::try(...).unwrap() should fail, too, if my interpretation is correct. On Fri, Apr 18, 2014 at 12:10 AM, Alex Crichton wrote: > The ~Any type has a special implementation of Show: > > https://github.com/mozilla/rust/blob/master/src/libstd/any.rs#L151-L155 > > I believe it was primarily used in failure messages originally (you > can fail a task with ~Any) > > On Thu, Apr 17, 2014 at 8:55 AM, Edward Wang > wrote: > > It current can compile, but judging from signatures: > > > > std::task::try is pub fn try(f: proc(): Send -> T) -> Result > ~Any:Send> > > std::result::unwrap on the other hand is impl Result { > fn > > unwrap(self) -> T {...} } > > > > There's no way the error part of result from task::try(...) can fulfil > Show > > so it shouldn't compile. > > > > Though to ask the list first before filing a bug report. > > > > Regards, > > Edward > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rustphil at phildawes.net Fri Apr 18 04:38:26 2014 From: rustphil at phildawes.net (Phil Dawes) Date: Fri, 18 Apr 2014 12:38:26 +0100 Subject: [rust-dev] possible code dump bug (state machine iterator) Message-ID: Hello everyone, I was trying to create an iterator that used a function pointer to alternate between different states, and ended up core dumping. I've pasted a version that generates the issue on my box (Ubuntu 12.04 LTS, rust-nightly pulled just now). Can anybody reproduce this on their machines? If so I'll file a bug. Cheers, Phil struct StateMachineIter<'a> { statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str> } impl<'a> Iterator<&'static str> for StateMachineIter<'a> { fn next(&mut self) -> Option<&'static str> { return (*self.statefn)(self); } } fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { self_.statefn = &state2; return Some("state1"); } fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { self_.statefn = &state3; return Some("state2"); } fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { self_.statefn = &finished; return Some("state3"); } fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { return None; } fn state_iter() -> StateMachineIter { StateMachineIter { statefn: &state1 } } fn main() { let mut it = state_iter(); println!("{}",it.next()); println!("{}",it.next()); println!("{}",it.next()); println!("{}",it.next()); println!("{}",it.next()); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From hatahet at gmail.com Fri Apr 18 08:30:02 2014 From: hatahet at gmail.com (Ziad Hatahet) Date: Fri, 18 Apr 2014 08:30:02 -0700 Subject: [rust-dev] possible code dump bug (state machine iterator) In-Reply-To: References: Message-ID: Confirm repro on an older rustc version. Ubuntu 13.10 running rustc 0.11-pre (ecc774f 2014-04-11 13:46:45 -0700). -- Ziad On Fri, Apr 18, 2014 at 4:38 AM, Phil Dawes wrote: > Hello everyone, > > I was trying to create an iterator that used a function pointer to > alternate between different states, and ended up core dumping. I've pasted > a version that generates the issue on my box (Ubuntu 12.04 LTS, > rust-nightly pulled just now). Can anybody reproduce this on their > machines? If so I'll file a bug. > > Cheers, > > Phil > > struct StateMachineIter<'a> { > statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str> > } > > impl<'a> Iterator<&'static str> for StateMachineIter<'a> { > fn next(&mut self) -> Option<&'static str> { > return (*self.statefn)(self); > } > } > > fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { > self_.statefn = &state2; > return Some("state1"); > } > > fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { > self_.statefn = &state3; > return Some("state2"); > } > > fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { > self_.statefn = &finished; > return Some("state3"); > } > > fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { > return None; > } > > fn state_iter() -> StateMachineIter { > StateMachineIter { statefn: &state1 } > } > > > fn main() { > let mut it = state_iter(); > println!("{}",it.next()); > println!("{}",it.next()); > println!("{}",it.next()); > println!("{}",it.next()); > println!("{}",it.next()); > } > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sfackler at gmail.com Fri Apr 18 08:47:47 2014 From: sfackler at gmail.com (Steven Fackler) Date: Fri, 18 Apr 2014 08:47:47 -0700 Subject: [rust-dev] possible code dump bug (state machine iterator) In-Reply-To: References: Message-ID: There's an extra layer of indirection in that struct definition. A &'a fn() is a pointer to a pointer to a function. A statement like "self_.statefn = &finished;" expands to "let foo = finished; self_.statefn = &foo". That's obviously creating a dangling pointer onto the stack which is why it ends up crashing. Adjusting the struct definition to struct StateMachineIter { statefn: fn(&mut StateMachineIter) -> Option<&'static str> } should make things work as you want. There's also a bug in rustc for even letting that program compile. I'm not sure if it's already been run into and filed. Steven Fackler On Fri, Apr 18, 2014 at 8:30 AM, Ziad Hatahet wrote: > Confirm repro on an older rustc version. Ubuntu 13.10 running rustc > 0.11-pre (ecc774f 2014-04-11 13:46:45 -0700). > > > -- > Ziad > > > On Fri, Apr 18, 2014 at 4:38 AM, Phil Dawes wrote: > >> Hello everyone, >> >> I was trying to create an iterator that used a function pointer to >> alternate between different states, and ended up core dumping. I've pasted >> a version that generates the issue on my box (Ubuntu 12.04 LTS, >> rust-nightly pulled just now). Can anybody reproduce this on their >> machines? If so I'll file a bug. >> >> Cheers, >> >> Phil >> >> struct StateMachineIter<'a> { >> statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str> >> } >> >> impl<'a> Iterator<&'static str> for StateMachineIter<'a> { >> fn next(&mut self) -> Option<&'static str> { >> return (*self.statefn)(self); >> } >> } >> >> fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { >> self_.statefn = &state2; >> return Some("state1"); >> } >> >> fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { >> self_.statefn = &state3; >> return Some("state2"); >> } >> >> fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { >> self_.statefn = &finished; >> return Some("state3"); >> } >> >> fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { >> return None; >> } >> >> fn state_iter() -> StateMachineIter { >> StateMachineIter { statefn: &state1 } >> } >> >> >> fn main() { >> let mut it = state_iter(); >> println!("{}",it.next()); >> println!("{}",it.next()); >> println!("{}",it.next()); >> println!("{}",it.next()); >> println!("{}",it.next()); >> } >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rustphil at phildawes.net Fri Apr 18 09:03:01 2014 From: rustphil at phildawes.net (Phil Dawes) Date: Fri, 18 Apr 2014 17:03:01 +0100 Subject: [rust-dev] possible code dump bug (state machine iterator) In-Reply-To: References: Message-ID: Awesome, thanks Steven, that works now. BTW, I filed bug https://github.com/mozilla/rust/issues/13595 before I read your reply. I'll leave it for now in case the bug isn't recorded somewhere else. Cheers, Phil On Fri, Apr 18, 2014 at 4:47 PM, Steven Fackler wrote: > There's an extra layer of indirection in that struct definition. A &'a > fn() is a pointer to a pointer to a function. A statement like > "self_.statefn = &finished;" expands to "let foo = finished; self_.statefn > = &foo". That's obviously creating a dangling pointer onto the stack which > is why it ends up crashing. Adjusting the struct definition to > > struct StateMachineIter { > statefn: fn(&mut StateMachineIter) -> Option<&'static str> > } > > should make things work as you want. There's also a bug in rustc for even > letting that program compile. I'm not sure if it's already been run into > and filed. > > > Steven Fackler > > > On Fri, Apr 18, 2014 at 8:30 AM, Ziad Hatahet wrote: > >> Confirm repro on an older rustc version. Ubuntu 13.10 running rustc >> 0.11-pre (ecc774f 2014-04-11 13:46:45 -0700). >> >> >> -- >> Ziad >> >> >> On Fri, Apr 18, 2014 at 4:38 AM, Phil Dawes wrote: >> >>> Hello everyone, >>> >>> I was trying to create an iterator that used a function pointer to >>> alternate between different states, and ended up core dumping. I've pasted >>> a version that generates the issue on my box (Ubuntu 12.04 LTS, >>> rust-nightly pulled just now). Can anybody reproduce this on their >>> machines? If so I'll file a bug. >>> >>> Cheers, >>> >>> Phil >>> >>> struct StateMachineIter<'a> { >>> statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str> >>> } >>> >>> impl<'a> Iterator<&'static str> for StateMachineIter<'a> { >>> fn next(&mut self) -> Option<&'static str> { >>> return (*self.statefn)(self); >>> } >>> } >>> >>> fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { >>> self_.statefn = &state2; >>> return Some("state1"); >>> } >>> >>> fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { >>> self_.statefn = &state3; >>> return Some("state2"); >>> } >>> >>> fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { >>> self_.statefn = &finished; >>> return Some("state3"); >>> } >>> >>> fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { >>> return None; >>> } >>> >>> fn state_iter() -> StateMachineIter { >>> StateMachineIter { statefn: &state1 } >>> } >>> >>> >>> fn main() { >>> let mut it = state_iter(); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> } >>> >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Fri Apr 18 12:29:27 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Fri, 18 Apr 2014 20:29:27 +0100 Subject: [rust-dev] possible code dump bug (state machine iterator) In-Reply-To: References: Message-ID: "There's an extra layer of indirection in that struct definition. A &'a fn() is a pointer to a pointer to a function. A statement like "self_.statefn = &finished;" expands to "let foo = finished; self_.statefn = &foo". That's obviously creating a dangling pointer onto the stack which is why it ends up crashing." I'm not sure I fully understand the above. If what you say is true, then why does the following code (which also uses &'a fn()) work? [using rustc 0.11-pre-nightly (e332287 2014-04-16 00:56:30 -0700) on ubuntu 14.04] Thanks.: ************************************************************************************************************ struct StateMachineIter<'a> { statefn: &'a fn(&mut StateMachineIter<'a>) } fn next(self_: &mut StateMachineIter) { return (*self_.statefn)(self_); } fn state1(self_: &mut StateMachineIter) { println!("state1"); self_.statefn = &state2; } fn state2(self_: &mut StateMachineIter) { println!("state2"); self_.statefn = &state3; } fn state3(self_: &mut StateMachineIter) { println!("state3"); self_.statefn = &finished; } fn finished(_: &mut StateMachineIter) { println!("finished"); } fn state_iter() -> StateMachineIter { StateMachineIter { statefn: &state1 } } fn main() { let it =& mut state_iter(); next(it); next(it); next(it); next(it); next(it); /* Prints out : state1 state2 state3 finished finished */ } ************************************************************************************************************ On Fri, Apr 18, 2014 at 4:47 PM, Steven Fackler wrote: > There's an extra layer of indirection in that struct definition. A &'a > fn() is a pointer to a pointer to a function. A statement like > "self_.statefn = &finished;" expands to "let foo = finished; self_.statefn > = &foo". That's obviously creating a dangling pointer onto the stack which > is why it ends up crashing. Adjusting the struct definition to > > struct StateMachineIter { > statefn: fn(&mut StateMachineIter) -> Option<&'static str> > } > > should make things work as you want. There's also a bug in rustc for even > letting that program compile. I'm not sure if it's already been run into > and filed. > > > Steven Fackler > > > On Fri, Apr 18, 2014 at 8:30 AM, Ziad Hatahet wrote: > >> Confirm repro on an older rustc version. Ubuntu 13.10 running rustc >> 0.11-pre (ecc774f 2014-04-11 13:46:45 -0700). >> >> >> -- >> Ziad >> >> >> On Fri, Apr 18, 2014 at 4:38 AM, Phil Dawes wrote: >> >>> Hello everyone, >>> >>> I was trying to create an iterator that used a function pointer to >>> alternate between different states, and ended up core dumping. I've pasted >>> a version that generates the issue on my box (Ubuntu 12.04 LTS, >>> rust-nightly pulled just now). Can anybody reproduce this on their >>> machines? If so I'll file a bug. >>> >>> Cheers, >>> >>> Phil >>> >>> struct StateMachineIter<'a> { >>> statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str> >>> } >>> >>> impl<'a> Iterator<&'static str> for StateMachineIter<'a> { >>> fn next(&mut self) -> Option<&'static str> { >>> return (*self.statefn)(self); >>> } >>> } >>> >>> fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { >>> self_.statefn = &state2; >>> return Some("state1"); >>> } >>> >>> fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { >>> self_.statefn = &state3; >>> return Some("state2"); >>> } >>> >>> fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { >>> self_.statefn = &finished; >>> return Some("state3"); >>> } >>> >>> fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { >>> return None; >>> } >>> >>> fn state_iter() -> StateMachineIter { >>> StateMachineIter { statefn: &state1 } >>> } >>> >>> >>> fn main() { >>> let mut it = state_iter(); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> println!("{}",it.next()); >>> } >>> >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsteinbr at gmail.com Sat Apr 19 02:14:21 2014 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sat, 19 Apr 2014 11:14:21 +0200 Subject: [rust-dev] possible code dump bug (state machine iterator) In-Reply-To: References: Message-ID: <20140419091421.GA13717@atjola.homenet> On 2014.04.18 20:29:27 +0100, Artella Coding wrote: > "There's an extra layer of indirection in that struct definition. A &'a > fn() is a pointer to a pointer to a function. A statement like > "self_.statefn = &finished;" expands to "let foo = finished; self_.statefn > = &foo". That's obviously creating a dangling pointer onto the stack which > is why it ends up crashing." Just a dangling pointer is not enough for a crash. You also need some code to corrupt the memory it is pointing at. That's the bit that makes such errors so much fun to debug :-) > I'm not sure I fully understand the above. If what you say is true, then > why does the following code (which also uses &'a fn()) work? [using rustc > 0.11-pre-nightly (e332287 2014-04-16 00:56:30 -0700) on ubuntu 14.04] Actually, that code also crashes when you compile with optimizations. The reason why it doesn't fail without optimizations is that there is nothing that could corrupt the stack state between storing the pointer and reading it. To see this, try the following: 1) Move the println!() in state1() _after_ the assignment. 2) Insert `println!("{}", Some(4));` after the first call to `it.next()` Doing either of these changes alone doesn't change anything, but combined, you should see a crash. The first change is just to move the `addr_of` temporary (the internal name for what Steven called `foo`) up on the stack, i.e. closer to the stack frame of `main()`, since println!() uses quite a bit of stack. The second one then just creates some code that uses just enough stack to overwrite the address that `addr_of` is stored at now. HTH Bj?rn > struct StateMachineIter<'a> { > statefn: &'a fn(&mut StateMachineIter<'a>) > } > > fn next(self_: &mut StateMachineIter) { > return (*self_.statefn)(self_); > } > > fn state1(self_: &mut StateMachineIter) { > println!("state1"); > self_.statefn = &state2; > } > > fn state2(self_: &mut StateMachineIter) { > println!("state2"); > self_.statefn = &state3; > } > > fn state3(self_: &mut StateMachineIter) { > println!("state3"); > self_.statefn = &finished; > } > > fn finished(_: &mut StateMachineIter) { > println!("finished"); > } > > fn state_iter() -> StateMachineIter { > StateMachineIter { statefn: &state1 } > } > > > fn main() { > let it =& mut state_iter(); > next(it); > next(it); > next(it); > next(it); > next(it); > > /* > Prints out : > > state1 > state2 > state3 > finished > finished > */ > } From jon.mb at proinbox.com Sat Apr 19 02:36:36 2014 From: jon.mb at proinbox.com (John Mija) Date: Sat, 19 Apr 2014 10:36:36 +0100 Subject: [rust-dev] Ideas to build Rust projects Message-ID: <535243A4.4010007@proinbox.com> Sometimes, developers need ideas or cool projects to be inspired. Here you have some ones, please share some more. + Implementation of the Raft distributed consensus protocol. It will allow to build distributed systems Implementations in Go: https://github.com/goraft/raft https://github.com/hashicorp/raft + Key-value embedded database LDBM was built as backend for OpenLDAP, but it is being used in many projects. The benchmarks (LevelDB, Kyoto TreeDB, LDBM, BerkeleyDB, SQLite3) show that it is faster for read operations, although it's something slower than LevelDB for writing. http://symas.com/mdb/ There is a pure Go key/value store inspired by the LMDB project: https://github.com/boltdb/bolt + Terminal portable Today, to access to a terminal in Unix or windows, you need to provide an interface. The great issue is that Unix terminal and Windows console have different APIs, so it's very hard to get a portable API for each system. Instead, could be created a terminal from scratch handling all in low level (without using the Windows API). From artella.coding at googlemail.com Sat Apr 19 06:29:59 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Sat, 19 Apr 2014 14:29:59 +0100 Subject: [rust-dev] possible code dump bug (state machine iterator) In-Reply-To: <20140419091421.GA13717@atjola.homenet> References: <20140419091421.GA13717@atjola.homenet> Message-ID: Aha thanks, I am beginning to understand I think. Regarding : "The first change is just to move the `addr_of` temporary (the internal name for what Steven called `foo`) up on the stack, i.e. closer to the stack frame of `main()`, since println!() uses quite a bit of stack." How did you work this out? Is this how programs normally work? Thanks. On Sat, Apr 19, 2014 at 10:14 AM, Bj?rn Steinbrink wrote: > On 2014.04.18 20:29:27 +0100, Artella Coding wrote: > > "There's an extra layer of indirection in that struct definition. A &'a > > fn() is a pointer to a pointer to a function. A statement like > > "self_.statefn = &finished;" expands to "let foo = finished; > self_.statefn > > = &foo". That's obviously creating a dangling pointer onto the stack > which > > is why it ends up crashing." > > Just a dangling pointer is not enough for a crash. You also need some > code to corrupt the memory it is pointing at. That's the bit that makes > such errors so much fun to debug :-) > > > I'm not sure I fully understand the above. If what you say is true, then > > why does the following code (which also uses &'a fn()) work? [using rustc > > 0.11-pre-nightly (e332287 2014-04-16 00:56:30 -0700) on ubuntu 14.04] > > Actually, that code also crashes when you compile with optimizations. > The reason why it doesn't fail without optimizations is that there is > nothing that could corrupt the stack state between storing the pointer > and reading it. > > To see this, try the following: > > 1) Move the println!() in state1() _after_ the assignment. > 2) Insert `println!("{}", Some(4));` after the first call to `it.next()` > > Doing either of these changes alone doesn't change anything, but > combined, you should see a crash. > > The first change is just to move the `addr_of` temporary (the internal > name for what Steven called `foo`) up on the stack, i.e. closer to the > stack frame of `main()`, since println!() uses quite a bit of stack. > > The second one then just creates some code that uses just enough stack > to overwrite the address that `addr_of` is stored at now. > > HTH > Bj?rn > > > struct StateMachineIter<'a> { > > statefn: &'a fn(&mut StateMachineIter<'a>) > > } > > > > fn next(self_: &mut StateMachineIter) { > > return (*self_.statefn)(self_); > > } > > > > fn state1(self_: &mut StateMachineIter) { > > println!("state1"); > > self_.statefn = &state2; > > } > > > > fn state2(self_: &mut StateMachineIter) { > > println!("state2"); > > self_.statefn = &state3; > > } > > > > fn state3(self_: &mut StateMachineIter) { > > println!("state3"); > > self_.statefn = &finished; > > } > > > > fn finished(_: &mut StateMachineIter) { > > println!("finished"); > > } > > > > fn state_iter() -> StateMachineIter { > > StateMachineIter { statefn: &state1 } > > } > > > > > > fn main() { > > let it =& mut state_iter(); > > next(it); > > next(it); > > next(it); > > next(it); > > next(it); > > > > /* > > Prints out : > > > > state1 > > state2 > > state3 > > finished > > finished > > */ > > } > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mahmutbulut0 at gmail.com Sat Apr 19 07:45:13 2014 From: mahmutbulut0 at gmail.com (Mahmut Bulut) Date: Sat, 19 Apr 2014 17:45:13 +0300 Subject: [rust-dev] Ideas to build Rust projects In-Reply-To: <535243A4.4010007@proinbox.com> References: <535243A4.4010007@proinbox.com> Message-ID: Terminal portable is good choice for all. But I want to say that I started to write util-linux in Rust. Ok there is coreutils but we should extend it with perfect system integration. I don't have time to complete all of util-linux but if contrbution comes it can merge into coreutils. You can take a look to Trafo(rewrite of util-linux): https://github.com/vertexclique/trafo ---- Mahmut Bulut > On 19 Apr 2014, at 12:36, John Mija wrote: > > Sometimes, developers need ideas or cool projects to be inspired. Here you have some ones, please share some more. > > + Implementation of the Raft distributed consensus protocol. It will allow to build distributed systems > > Implementations in Go: > https://github.com/goraft/raft > https://github.com/hashicorp/raft > > + Key-value embedded database > > LDBM was built as backend for OpenLDAP, but it is being used in many projects. The benchmarks (LevelDB, Kyoto TreeDB, LDBM, BerkeleyDB, SQLite3) show that it is faster for read operations, although it's something slower than LevelDB for writing. > > http://symas.com/mdb/ > > There is a pure Go key/value store inspired by the LMDB project: > https://github.com/boltdb/bolt > > + Terminal portable > > Today, to access to a terminal in Unix or windows, you need to provide an interface. The great issue is that Unix terminal and Windows console have different APIs, so it's very hard to get a portable API for each system. > > Instead, could be created a terminal from scratch handling all in low level (without using the Windows API). > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsteinbr at gmail.com Sat Apr 19 07:59:30 2014 From: bsteinbr at gmail.com (=?iso-8859-1?Q?Bj=F6rn?= Steinbrink) Date: Sat, 19 Apr 2014 16:59:30 +0200 Subject: [rust-dev] possible code dump bug (state machine iterator) In-Reply-To: References: <20140419091421.GA13717@atjola.homenet> Message-ID: <20140419145930.GB13717@atjola.homenet> On 2014.04.19 14:29:59 +0100, Artella Coding wrote: > Aha thanks, I am beginning to understand I think. Regarding : > > "The first change is just to move the `addr_of` temporary (the internal > name for what Steven called `foo`) up on the stack, i.e. closer to the > stack frame of `main()`, since println!() uses quite a bit of stack." > > How did you work this out? Is this how programs normally work? Thanks. Yeah, that's basically just how programs work when using a "classical" stack. The growth direction depends on the architecture, but the idea of moving the item closer to the caller's stack frame stays the same. Note that with the spaghetti/segmented stacks that earlier versions of rust used, you might get different results (depending on whether or not the call requires a new stack segment). Of course, it also helps to know that with today's rustc + LLVM and without optimizations, variables get allocated on the stack roughly in order of their declaration (or use in case of implicitly created temporaries). This might of course change, and then different variations of the code might fail expose or hide the error. Bj?rn > On Sat, Apr 19, 2014 at 10:14 AM, Bj?rn Steinbrink wrote: > > > On 2014.04.18 20:29:27 +0100, Artella Coding wrote: > > > "There's an extra layer of indirection in that struct definition. A &'a > > > fn() is a pointer to a pointer to a function. A statement like > > > "self_.statefn = &finished;" expands to "let foo = finished; > > self_.statefn > > > = &foo". That's obviously creating a dangling pointer onto the stack > > which > > > is why it ends up crashing." > > > > Just a dangling pointer is not enough for a crash. You also need some > > code to corrupt the memory it is pointing at. That's the bit that makes > > such errors so much fun to debug :-) > > > > > I'm not sure I fully understand the above. If what you say is true, then > > > why does the following code (which also uses &'a fn()) work? [using rustc > > > 0.11-pre-nightly (e332287 2014-04-16 00:56:30 -0700) on ubuntu 14.04] > > > > Actually, that code also crashes when you compile with optimizations. > > The reason why it doesn't fail without optimizations is that there is > > nothing that could corrupt the stack state between storing the pointer > > and reading it. > > > > To see this, try the following: > > > > 1) Move the println!() in state1() _after_ the assignment. > > 2) Insert `println!("{}", Some(4));` after the first call to `it.next()` > > > > Doing either of these changes alone doesn't change anything, but > > combined, you should see a crash. > > > > The first change is just to move the `addr_of` temporary (the internal > > name for what Steven called `foo`) up on the stack, i.e. closer to the > > stack frame of `main()`, since println!() uses quite a bit of stack. > > > > The second one then just creates some code that uses just enough stack > > to overwrite the address that `addr_of` is stored at now. > > > > HTH > > Bj?rn > > > > > struct StateMachineIter<'a> { > > > statefn: &'a fn(&mut StateMachineIter<'a>) > > > } > > > > > > fn next(self_: &mut StateMachineIter) { > > > return (*self_.statefn)(self_); > > > } > > > > > > fn state1(self_: &mut StateMachineIter) { > > > println!("state1"); > > > self_.statefn = &state2; > > > } > > > > > > fn state2(self_: &mut StateMachineIter) { > > > println!("state2"); > > > self_.statefn = &state3; > > > } > > > > > > fn state3(self_: &mut StateMachineIter) { > > > println!("state3"); > > > self_.statefn = &finished; > > > } > > > > > > fn finished(_: &mut StateMachineIter) { > > > println!("finished"); > > > } > > > > > > fn state_iter() -> StateMachineIter { > > > StateMachineIter { statefn: &state1 } > > > } > > > > > > > > > fn main() { > > > let it =& mut state_iter(); > > > next(it); > > > next(it); > > > next(it); > > > next(it); > > > next(it); > > > > > > /* > > > Prints out : > > > > > > state1 > > > state2 > > > state3 > > > finished > > > finished > > > */ > > > } > > From richo at psych0tik.net Sun Apr 20 00:13:57 2014 From: richo at psych0tik.net (richo) Date: Sun, 20 Apr 2014 00:13:57 -0700 Subject: [rust-dev] Pattern matching on std::os::args() Message-ID: <20140420071357.GA71270@elektra.local> o/ Rustlers, So, as an indirect result of the absence of pattern matching on unique vectors, I'm having a lot of trouble writing a sane CLI interface based on the results of os::args() The full code in a more readable format is available at here[1] So what I really want is something like: let args = os::args(); match args.as_slice() { [] => unreachable!(), [ref argv0] => println!("Called as: {}", argv0), [ref argv0, "foo", ref argv2] => println!("Matched on foo"), [ref argv0, "bar", ref argv2] => println!("Matched on bar"), [ref argv0, ref argv1, ref argv2] => println!("Called as: {} with: {}, {}", argv0, argv1, argv2), _ => fail!("OHSHI-"), } Basically, I'm interested in matching my CLI on some subcommands, with a variable number of arguments. I got this *really close* to working with something closer to: let args = os::args(); match args.as_slice() { [] => unreachable!(), [ref argv0] => println!("Called as: {}", argv0), [ref argv0, ref argv1] => println!("Called as: {} with: {}", argv0, argv1), [ref argv0, ref argv1, ref argv2] => { println!("Called as: {} with: {}, {}", argv0, argv1, argv2); match argv1 { "foo" => println!("Matched on foo"), "bar" => println!("Matched on bar"), _ => println!("No match on `argv1`") } }, _ => fail!("OHSHI-"), } But this still gets very upset because of trying to match a ~str against a &'static str My resulting two questions are: While I understand the virtues of memory/type safety, it seems that (naively) for the purposes of a string comparison to pattern match on, matching a string literal against a string variable that's in scope should more or less Just Work from the user perspective, I'm not asking for this to be solved at the language level, despite how nice that would be for people just picking this up, in the short term my assumption is that I'll wind up pulling this out into a module or library, how *should* I be attempting to do something like this? Is it actually supported? I've been working on rust-http over the last few days and I understand enough to see how I could build out macros to do what I want, but it seems like a lot of error prone indirection that isn't strictly necessary. Cheers richo [1]: https://gist.github.com/richo/11104624 -- richo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From edward.yu.wang at gmail.com Sun Apr 20 00:31:07 2014 From: edward.yu.wang at gmail.com (Edward Wang) Date: Sun, 20 Apr 2014 15:31:07 +0800 Subject: [rust-dev] Missing lifetime parameter in std::str::MaybeOwned Message-ID: The snippet is extracted from std::str: pub enum MaybeOwned<'a> { /// A borrowed string Slice(&'a str), /// An owned string Owned(~str) } impl<'a> Eq for MaybeOwned<'a> { #[inline] fn eq(&self, _other: &MaybeOwned) -> bool { true } } fn main() {} Note the Eq implementation for MaybeOwned, a lifetime parameter is missing. Isn't it ought to be: impl<'a, 'b> Eq for MaybeOwned<'a> { #[inline] fn eq(&self, _other: &MaybeOwned<'b>) -> bool { true } } If so, then I'll file a bug report. -Ed -------------- next part -------------- An HTML attachment was scrubbed... URL: From geo.couprie at gmail.com Sun Apr 20 01:44:34 2014 From: geo.couprie at gmail.com (Geoffroy Couprie) Date: Sun, 20 Apr 2014 10:44:34 +0200 Subject: [rust-dev] Pattern matching on std::os::args() In-Reply-To: <20140420071357.GA71270@elektra.local> References: <20140420071357.GA71270@elektra.local> Message-ID: Hi, I encountered the same problem, and I wound up writing a library to solve it (instead of working on my original code): https://github.com/Geal/typedopts The basic idea is to define a Decoder that can work on command line options. Then you just need to add "#[deriving(Decodable)]" to a structure that represents your command line options, and the matching will be safe and easy. I chose to make the Decoder work on the results of getopts, but it is possible to work directly on os::args. There is another library that does the same thing here: https://github.com/wycats/hammer.rs On Sun, Apr 20, 2014 at 9:13 AM, richo wrote: > o/ Rustlers, > > So, as an indirect result of the absence of pattern matching on unique > vectors, I'm having a lot of trouble writing a sane CLI interface based on > the results of os::args() > > The full code in a more readable format is available at here[1] > > So what I really want is something like: > > let args = os::args(); > match args.as_slice() { > [] => unreachable!(), > [ref argv0] => println!("Called as: {}", argv0), > [ref argv0, "foo", ref argv2] => println!("Matched on foo"), > [ref argv0, "bar", ref argv2] => println!("Matched on bar"), > [ref argv0, ref argv1, ref argv2] => println!("Called as: {} with: > {}, {}", argv0, argv1, argv2), > _ => fail!("OHSHI-"), > } > > Basically, I'm interested in matching my CLI on some subcommands, with a > variable number of arguments. > > I got this *really close* to working with something closer to: > > let args = os::args(); > match args.as_slice() { > [] => unreachable!(), > [ref argv0] => println!("Called as: {}", argv0), > [ref argv0, ref argv1] => println!("Called as: {} with: {}", argv0, > argv1), > [ref argv0, ref argv1, ref argv2] => { > println!("Called as: {} with: {}, {}", argv0, argv1, argv2); > match argv1 { > "foo" => println!("Matched on foo"), > "bar" => println!("Matched on bar"), > _ => println!("No match on `argv1`") > } > }, > _ => fail!("OHSHI-"), > } > > But this still gets very upset because of trying to match a ~str against a > &'static str > > My resulting two questions are: > > While I understand the virtues of memory/type safety, it seems that > (naively) > for the purposes of a string comparison to pattern match on, matching a > string literal against a string variable that's in scope should more or > less > Just Work from the user perspective, > > I'm not asking for this to be solved at the language level, despite how > nice > that would be for people just picking this up, in the short term my > assumption is that I'll wind up pulling this out into a module or library, > how *should* I be attempting to do something like this? Is it actually > supported? I've been working on rust-http over the last few days and I > understand enough to see how I could build out macros to do what I want, > but > it seems like a lot of error prone indirection that isn't strictly > necessary. > > > Cheers > > richo > > [1]: https://gist.github.com/richo/11104624 > > -- > richo > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > Cheers, Geoffroy -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Sun Apr 20 01:46:21 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Sun, 20 Apr 2014 09:46:21 +0100 Subject: [rust-dev] LLVM doesn't inline my static, any good reason for that? Message-ID: I'm working on a proof-of-concept implementation for https://github.com/rust-lang/rfcs/pull/44 [Linker placement attribute], and I actually got code that is working, but the outcome is worse than I expected. Consider the following snippet: #[unsafe_override_address] static Tinst : T = 1000; What it is expected to do is to create a '1000 as *T' with the semantics of T (the reasons for that are in RFC). My patch actually works as expected in this regard, I evaluate the expr as uint, and store a LLVMConstIntToPtr made from that uint in ccx.const_values. The results in the following IR: @Tinst = internal constant %struct.T* inttoptr (i32 1000 to %struct.T*) The problem is that llvm never inlines the constant (even with #[address_insignificant]), so instead of making the binary smaller as llvm can optimize integer addresses better (as it knows them) it makes the binary bigger, as it takes 4 bytes to store address value in .rodata, and two instructions to fetch it. Any ideas on what I could be missing? -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From richo at psych0tik.net Sun Apr 20 02:50:06 2014 From: richo at psych0tik.net (richo) Date: Sun, 20 Apr 2014 02:50:06 -0700 Subject: [rust-dev] Pattern matching on std::os::args() In-Reply-To: References: <20140420071357.GA71270@elektra.local> Message-ID: <20140420092845.GA75443@elektra.local> On 20/04/14 10:44 +0200, Geoffroy Couprie wrote: >Hi, > >I encountered the same problem, and I wound up writing a library to solve >it (instead of working on my original code): >https://github.com/Geal/typedopts > >The basic idea is to define a Decoder that can work on command line >options. Then you just need to add "#[deriving(Decodable)]" to a structure >that represents your command line options, and the matching will be safe >and easy. >I chose to make the Decoder work on the results of getopts, but it is >possible to work directly on os::args. > >There is another library that does the same thing here: >https://github.com/wycats/hammer.rs >Cheers, > >Geoffroy Thanks for the tips! So neither seems to solve my issue at face value. I'm just going through and fixing some ~[T] and ~str -> StrBuf issues in hammer at the moment so I can play with it (PR incoming, if you're subbed wycats). My underlying issue is a bit more "Why can't I do this totally plausible looking thing", albeit wrapped strongly in the "Pattern matching on args is a generally useful thing" context. I'll fiddle with both of these and see if I can get them to work for me. Thanks again! -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 473 bytes Desc: not available URL: From matthieu.monrocq at gmail.com Sun Apr 20 03:50:44 2014 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sun, 20 Apr 2014 12:50:44 +0200 Subject: [rust-dev] Ideas to build Rust projects In-Reply-To: References: <535243A4.4010007@proinbox.com> Message-ID: I agree that a protable terminal would be sweet, however the terminal and shell are only half the story: you then need a uniform set of tools behind the scenes else all your scripts fail. I would like to take the opportunity to point out Mosh [1] as an existing (and recent) shell, it might make for a great starting point. Regarding project ideas, I myself would be very interested in: - concurrent collections (lists, hash-sets, hash-maps, ...), while I know this is not in the spirit of CSP sometimes forcing a single queue to access a collection creates a bottleneck. - a MPMC queue, at the moment Rust stops at MPSC with its channels and once again when the load is too important you really need to be able to have multiple consumers. It could potentially be tied into a WorkerPool implementation where you can freely administrate the pool size and just post jobs to the pool, but maybe it could be implemented free-standing. [1]: http://mosh.mit.edu/ On Sat, Apr 19, 2014 at 4:45 PM, Mahmut Bulut wrote: > Terminal portable is good choice for all. > But I want to say that I started to write util-linux in Rust. Ok there is > coreutils but we should extend it with perfect system integration. I don't > have time to complete all of util-linux but if contrbution comes it can > merge into coreutils. > > You can take a look to Trafo(rewrite of util-linux): > > https://github.com/vertexclique/trafo > > ---- > Mahmut Bulut > > On 19 Apr 2014, at 12:36, John Mija wrote: > > Sometimes, developers need ideas or cool projects to be inspired. Here you > have some ones, please share some more. > > + Implementation of the Raft distributed consensus protocol. It will allow > to build distributed systems > > Implementations in Go: > https://github.com/goraft/raft > https://github.com/hashicorp/raft > > + Key-value embedded database > > LDBM was built as backend for OpenLDAP, but it is being used in many > projects. The benchmarks (LevelDB, Kyoto TreeDB, LDBM, BerkeleyDB, SQLite3) > show that it is faster for read operations, although it's something slower > than LevelDB for writing. > > http://symas.com/mdb/ > > There is a pure Go key/value store inspired by the LMDB project: > https://github.com/boltdb/bolt > > + Terminal portable > > Today, to access to a terminal in Unix or windows, you need to provide an > interface. The great issue is that Unix terminal and Windows console have > different APIs, so it's very hard to get a portable API for each system. > > Instead, could be created a terminal from scratch handling all in low > level (without using the Windows API). > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jurily at gmail.com Sun Apr 20 06:04:53 2014 From: jurily at gmail.com (=?UTF-8?Q?Gy=C3=B6rgy_Andrasek?=) Date: Sun, 20 Apr 2014 15:04:53 +0200 Subject: [rust-dev] LLVM doesn't inline my static, any good reason for that? In-Reply-To: References: Message-ID: On Sun, Apr 20, 2014 at 10:46 AM, Vladimir Pouzanov wrote: > The results in the following IR: > > @Tinst = internal constant %struct.T* inttoptr (i32 1000 to %struct.T*) > > The problem is that llvm never inlines the constant (even with > #[address_insignificant]), so instead of making the binary smaller as llvm > can optimize integer addresses better (as it knows them) it makes the binary > bigger, as it takes 4 bytes to store address value in .rodata, and two > instructions to fetch it. Does it show up in the asm after optimizations? After LTO? From farcaller at gmail.com Sun Apr 20 11:05:57 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Sun, 20 Apr 2014 19:05:57 +0100 Subject: [rust-dev] LLVM doesn't inline my static, any good reason for that? In-Reply-To: References: Message-ID: Apparently I had a problem of double pointer. The solution was to use static Tinst : &'static T = 1000; though I have modified the code now so that T works as well. On Sun, Apr 20, 2014 at 2:04 PM, Gy?rgy Andrasek wrote: > On Sun, Apr 20, 2014 at 10:46 AM, Vladimir Pouzanov > wrote: > > The results in the following IR: > > > > @Tinst = internal constant %struct.T* inttoptr (i32 1000 to %struct.T*) > > > > The problem is that llvm never inlines the constant (even with > > #[address_insignificant]), so instead of making the binary smaller as > llvm > > can optimize integer addresses better (as it knows them) it makes the > binary > > bigger, as it takes 4 bytes to store address value in .rodata, and two > > instructions to fetch it. > > Does it show up in the asm after optimizations? After LTO? > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Mon Apr 21 03:57:53 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Mon, 21 Apr 2014 11:57:53 +0100 Subject: [rust-dev] Generic enums : manually implementing Clone trait Message-ID: Suppose I have the enum : enum Coll { A(f64,T), B(f64,T) } I know that the compiler can automatically derive the Clone trait for the above. However I would like to manually implement it and was unsuccessful in my attempt. I tried the following : enum Coll { A(f64,T), B(f64,T) } impl Clone for Coll { fn clone (&self) -> Coll { match *self { A(x,y) => A(x,y.clone()), B(x,y) => B(x,y.clone()) } } } but I got the error message : q.rs:9:13: 9:19 error: cannot move out of dereference of `&`-pointer q.rs:9 A(x,y) => A(x,y.clone()), ^~~~~~ q.rs:10:13: 10:19 error: cannot move out of dereference of `&`-pointer q.rs:10 B(x,y) => B(x,y.clone()) ^~~~~~ error: aborting due to 2 previous errors What do I need to do to fix the code above? Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From judofyr at gmail.com Mon Apr 21 04:07:24 2014 From: judofyr at gmail.com (Magnus Holm) Date: Mon, 21 Apr 2014 13:07:24 +0200 Subject: [rust-dev] Generic enums : manually implementing Clone trait In-Reply-To: References: Message-ID: I'm guessing matching with a reference will help: mpl Clone for Coll { fn clone (&self) -> Coll { match *self { A(x,ref y) => A(x,y.clone()), B(x,ref y) => B(x,y.clone()) } } } (Haven't tried it though) // Magnus Holm On Mon, Apr 21, 2014 at 12:57 PM, Artella Coding wrote: > > Suppose I have the enum : > > enum Coll { > A(f64,T), > B(f64,T) > } > > I know that the compiler can automatically derive the Clone trait for the > above. However I would like to manually implement it and was unsuccessful in > my attempt. I tried the following : > > enum Coll { > A(f64,T), > B(f64,T) > } > > impl Clone for Coll { > fn clone (&self) -> Coll { > match *self { > A(x,y) => A(x,y.clone()), > B(x,y) => B(x,y.clone()) > } > } > } > > but I got the error message : > > q.rs:9:13: 9:19 error: cannot move out of dereference of `&`-pointer > q.rs:9 A(x,y) => A(x,y.clone()), > ^~~~~~ > q.rs:10:13: 10:19 error: cannot move out of dereference of `&`-pointer > q.rs:10 B(x,y) => B(x,y.clone()) > ^~~~~~ > error: aborting due to 2 previous errors > > What do I need to do to fix the code above? Thanks > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From leo.testard at gmail.com Mon Apr 21 04:10:06 2014 From: leo.testard at gmail.com (=?iso-8859-1?Q?L=E9o_Testard?=) Date: Mon, 21 Apr 2014 13:10:06 +0200 Subject: [rust-dev] Generic enums : manually implementing Clone trait In-Reply-To: References: Message-ID: Le 21 avr. 2014 ? 12:57, Artella Coding a ?crit : > > Suppose I have the enum : > > enum Coll { > A(f64,T), > B(f64,T) > } > > I know that the compiler can automatically derive the Clone trait for the above. However I would like to manually implement it and was unsuccessful in my attempt. I tried the following : > > enum Coll { > A(f64,T), > B(f64,T) > } > > impl Clone for Coll { > fn clone (&self) -> Coll { > match *self { > A(x,y) => A(x,y.clone()), > B(x,y) => B(x,y.clone()) > } > } > } The error is in your match statement. You try to bind the "T" part of your type to the "y" variable, which causes by default a by-value binding. Since you can't know statically if T has value or move semantics, you can't do this, since in the case of move semantics, this would move the T out of self, that you don't own because you take it as a reference (&self). You have instead to explicitly bind T by ref : match *self { A(x, ref y) => A(x ,y.clone()), B(x, ref y) => B(x, y.clone()) } Leo From artella.coding at googlemail.com Mon Apr 21 04:11:48 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Mon, 21 Apr 2014 12:11:48 +0100 Subject: [rust-dev] Generic enums : manually implementing Clone trait In-Reply-To: References: Message-ID: Awesome that worked! Thanks. On Mon, Apr 21, 2014 at 12:07 PM, Magnus Holm wrote: > I'm guessing matching with a reference will help: > > mpl Clone for Coll { > fn clone (&self) -> Coll { > match *self { > A(x,ref y) => A(x,y.clone()), > B(x,ref y) => B(x,y.clone()) > } > } > } > > (Haven't tried it though) > > // Magnus Holm > > > On Mon, Apr 21, 2014 at 12:57 PM, Artella Coding > wrote: > > > > Suppose I have the enum : > > > > enum Coll { > > A(f64,T), > > B(f64,T) > > } > > > > I know that the compiler can automatically derive the Clone trait for the > > above. However I would like to manually implement it and was > unsuccessful in > > my attempt. I tried the following : > > > > enum Coll { > > A(f64,T), > > B(f64,T) > > } > > > > impl Clone for Coll { > > fn clone (&self) -> Coll { > > match *self { > > A(x,y) => A(x,y.clone()), > > B(x,y) => B(x,y.clone()) > > } > > } > > } > > > > but I got the error message : > > > > q.rs:9:13: 9:19 error: cannot move out of dereference of `&`-pointer > > q.rs:9 A(x,y) => A(x,y.clone()), > > ^~~~~~ > > q.rs:10:13: 10:19 error: cannot move out of dereference of `&`-pointer > > q.rs:10 B(x,y) => B(x,y.clone()) > > ^~~~~~ > > error: aborting due to 2 previous errors > > > > What do I need to do to fix the code above? Thanks > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From axel.viala at darnuria.eu Mon Apr 21 06:27:28 2014 From: axel.viala at darnuria.eu (Axel Viala) Date: Mon, 21 Apr 2014 15:27:28 +0200 Subject: [rust-dev] Remember RustMeetup paris 03 Tonight Message-ID: <53551CC0.2050109@darnuria.eu> That confirmed it's tonight! Third of his name. Planing: 18:00 -> 19:30: Lunch and informal meeting. 19:30 -> 23:00: Workshops for different levels. Reps Page: https://reps.mozilla.org/e/meetup-rust-paris-03/ Inscription and attendees: https://etherpad.mozilla.org/remo-meetup-rust-paris-03 Important: Bring some food it's a holiday in France so buying take-off food will be expensive! ;) Thanks! /Et Bonne journ?e from France!/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Mon Apr 21 06:50:23 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Mon, 21 Apr 2014 14:50:23 +0100 Subject: [rust-dev] morestack prologue contains broken machine code Message-ID: Starting recently (no more than two weeks), rustc is generating a broken prologue for arm. Here's the sample assembly: 0x00000f44 <+0>: push {r4, r5} => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} 0x00000f4a <+6>: mov r5, sp 0x00000f4c <+8>: b.n 0xa78 0x00000f4e <+10>: ands r4, r0 0x00000f50 <+12>: cmp r4, r5 0x00000f52 <+14>: bcc.n 0xf66 <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> 0x00000f54 <+16>: movs r4, #16 0x00000f56 <+18>: movs r5, #0 0x00000f58 <+20>: push {lr} 0x00000f5a <+22>: bl 0x19d8 <__morestack> 0x00000f5e <+26>: ldr.w lr, [sp], #4 0x00000f62 <+30>: pop {r4, r5} 0x00000f64 <+32>: bx lr The problem is at 0x00000f46, where code tries to read from coprocessor 15 register 13, which is "process id register". Well, coprocessor 15 (actually, all of the coprocessors) are missing from my target thumbv7m-linux-eabi (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant anyway), so I'm getting hardfaults in every function that rust doesn't inline. Any ideas on what might be going wrong? I assume that this is actually llvm's fault, as llvm should not materialize machine code which is not available for target anyway. Wrapping everything in #[no_split_stack] is a temporary workaround and surely not a long-term strategy. -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsancio at gmail.com Mon Apr 21 07:59:08 2014 From: jsancio at gmail.com (=?UTF-8?Q?Jos=C3=A9_Armando_Garc=C3=ADa_Sancio?=) Date: Mon, 21 Apr 2014 07:59:08 -0700 Subject: [rust-dev] Generic enums : manually implementing Clone trait In-Reply-To: References: Message-ID: On a similar note, why did Rust decide to use the keyword "ref" when "borrowing" in those cases and the keyword "&" when borrowing in function arguments? Is the semantic different? Feel free to RTFM with a link if it has already been documented. Thanks, Jose On Apr 21, 2014 4:10 AM, "L?o Testard" wrote: > > Le 21 avr. 2014 ? 12:57, Artella Coding a > ?crit : > > > > > Suppose I have the enum : > > > > enum Coll { > > A(f64,T), > > B(f64,T) > > } > > > > I know that the compiler can automatically derive the Clone trait for > the above. However I would like to manually implement it and was > unsuccessful in my attempt. I tried the following : > > > > enum Coll { > > A(f64,T), > > B(f64,T) > > } > > > > impl Clone for Coll { > > fn clone (&self) -> Coll { > > match *self { > > A(x,y) => A(x,y.clone()), > > B(x,y) => B(x,y.clone()) > > } > > } > > } > > The error is in your match statement. You try to bind the "T" part of your > type to the "y" variable, which causes by default a by-value binding. > Since you can't know statically if T has value or move semantics, you > can't do this, since in the case of move semantics, this would move the T > out of self, that you don't own because you take it as a reference (&self). > > You have instead to explicitly bind T by ref : > > match *self { > A(x, ref y) => A(x ,y.clone()), > B(x, ref y) => B(x, y.clone()) > } > > Leo > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcwalton at mozilla.com Mon Apr 21 08:24:33 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Mon, 21 Apr 2014 08:24:33 -0700 Subject: [rust-dev] Generic enums : manually implementing Clone trait In-Reply-To: References: Message-ID: <53553831.5070707@mozilla.com> On 4/21/14 7:59 AM, Jos? Armando Garc?a Sancio wrote: > On a similar note, why did Rust decide to use the keyword "ref" when > "borrowing" in those cases and the keyword "&" when borrowing in > function arguments? Is the semantic different? `&` in a pattern is the opposite of a reference: it *de*references in pattern bindings. For example let &x = &3; sets `x` to 3 (not `&3`). This is for symmetry: consider that: let (x, y) = (1, 2); sets `x` to 1 and `y` to 2. Because `&` is taken to destructure references, we needed another keyword to take a reference. Hence, `ref`. Patrick From artella.coding at googlemail.com Mon Apr 21 08:56:42 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Mon, 21 Apr 2014 16:56:42 +0100 Subject: [rust-dev] Cloning Generic Structs/Enums with lifetime parameters Message-ID: How do I manually implement "clone()" for Structs/Enums with lifetime parameters (e.g. for struct below)? I could not even work out how to get the compiler to automatically implement "clone()". That is : --------------------------------------------------- struct Cls<'a,T> { x:&'a T } fn main(){} --------------------------------------------------- compiles fine, but as soon as I try to get the compiler to automatically generate "clone()" via : --------------------------------------------------- #[deriving(Clone)] struct Cls<'a,T> { x:&'a T } fn main(){} --------------------------------------------------- I get the following error : test1.rs:3:5: 3:12 error: mismatched types: expected `&` but found `T` (expected &-ptr but found type parameter) test1.rs:3 x:&'a T ^~~~~~~ note: in expansion of #[deriving] test1.rs:1:1: 2:7 note: expansion site error: aborting due to previous error I was also trying to specify that T itself implemented the Clone trait, but couldn't work out how to do that. Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Mon Apr 21 09:13:59 2014 From: alex at crichton.co (Alex Crichton) Date: Mon, 21 Apr 2014 09:13:59 -0700 Subject: [rust-dev] Cloning Generic Structs/Enums with lifetime parameters In-Reply-To: References: Message-ID: > How do I manually implement "clone()" for Structs/Enums with lifetime > parameters (e.g. for struct below)? > > --------------------------------------------------- > struct Cls<'a,T> { > x:&'a T > } impl<'a, T: Clone> Clone for Cls<'a, T> { fn clone(&self) -> Cls<'a, T> { Cls { x: self.x } } } You may find the generics [1] and traits [2] sections of the tutorial helpful as well! [1] - http://static.rust-lang.org/doc/master/tutorial.html#generics [2] - http://static.rust-lang.org/doc/master/tutorial.html#traits From alex at crichton.co Mon Apr 21 09:23:39 2014 From: alex at crichton.co (Alex Crichton) Date: Mon, 21 Apr 2014 09:23:39 -0700 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: The split stack patches for ARM were recently upstreamed, and they were modified when being upstreamed as well. Primarily the location of the split stack is no longer at a magic address for thumb, but rather it uses the same instruction as ARM (some thumb processors do indeed have the coprocessor). More information is in the long thread starting at the initial attempt to upstream [1]. For now you'll have to use no_split_stack because the thumb split stack will always use a coprocessor, but I'm sure that the upstream LLVM devs would be quite welcoming to tweaks to the slit-stack support (I'd also be willing to help). You can find the initial commit for support at rust-lang/llvm [2]. [1] - http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html [2] - https://github.com/rust-lang/llvm/pull/4 On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov wrote: > Starting recently (no more than two weeks), rustc is generating a broken > prologue for arm. Here's the sample assembly: > 0x00000f44 <+0>: push {r4, r5} > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} > 0x00000f4a <+6>: mov r5, sp > 0x00000f4c <+8>: b.n 0xa78 > 0x00000f4e <+10>: ands r4, r0 > 0x00000f50 <+12>: cmp r4, r5 > 0x00000f52 <+14>: bcc.n 0xf66 > <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> > 0x00000f54 <+16>: movs r4, #16 > 0x00000f56 <+18>: movs r5, #0 > 0x00000f58 <+20>: push {lr} > 0x00000f5a <+22>: bl 0x19d8 <__morestack> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 > 0x00000f62 <+30>: pop {r4, r5} > 0x00000f64 <+32>: bx lr > > The problem is at 0x00000f46, where code tries to read from coprocessor 15 > register 13, which is "process id register". Well, coprocessor 15 (actually, > all of the coprocessors) are missing from my target thumbv7m-linux-eabi > (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant > anyway), so I'm getting hardfaults in every function that rust doesn't > inline. > > Any ideas on what might be going wrong? I assume that this is actually > llvm's fault, as llvm should not materialize machine code which is not > available for target anyway. > > Wrapping everything in #[no_split_stack] is a temporary workaround and > surely not a long-term strategy. > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From artella.coding at googlemail.com Mon Apr 21 09:30:43 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Mon, 21 Apr 2014 17:30:43 +0100 Subject: [rust-dev] Cloning Generic Structs/Enums with lifetime parameters In-Reply-To: References: Message-ID: Cool thanks. I had skimmed through the sections you cited, but the problem was that in my version I was trying to clone by creating a new copy of x as follows : impl<'a,T: Clone> Clone for Cls<'a,T> { fn clone(&self) -> Cls<'a, T> { Cls{ x: & (*self.x).clone() } } } and I was getting the error message : test1.rs:8:17: 8:36 error: borrowed value does not live long enough test1.rs:8 Cls{ x: & (*self.x).clone() } Your solution solves my problem. Thanks. On Mon, Apr 21, 2014 at 5:13 PM, Alex Crichton wrote: > > How do I manually implement "clone()" for Structs/Enums with lifetime > > parameters (e.g. for struct below)? > > > > --------------------------------------------------- > > struct Cls<'a,T> { > > x:&'a T > > } > > impl<'a, T: Clone> Clone for Cls<'a, T> { > fn clone(&self) -> Cls<'a, T> { > Cls { x: self.x } > } > } > > You may find the generics [1] and traits [2] sections of the tutorial > helpful as well! > > [1] - http://static.rust-lang.org/doc/master/tutorial.html#generics > [2] - http://static.rust-lang.org/doc/master/tutorial.html#traits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Mon Apr 21 10:12:07 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Mon, 21 Apr 2014 18:12:07 +0100 Subject: [rust-dev] Specifying lifetimes in return types of overloaded operators In-Reply-To: References: Message-ID: Just realised that the following seems to work : struct Cls<'a> { vec : &'a ~[~int] } impl<'a> Index for Cls<'a> { fn index(&self,i:&uint)->&'a ~int { &(self.vec[*i]) } } fn main(){} On Wed, Apr 16, 2014 at 6:23 AM, Artella Coding < artella.coding at googlemail.com> wrote: > Hi Eric, this is an example of code which gives the error : > > ************************************************************ > struct Cls { > vec : ~[~int] > } > > /* > Does not compile, yielding error message : > > > "method `index` has an incompatible type for trait: > expected concrete lifetime, but found bound lifetime > parameter &" > */ > impl<'a> Index for Cls { > fn index(&'a self, i: &uint) -> &'a ~int { > let val = &'a self.vec[*i]; > return val; > } > } > > fn main(){} > ************************************************************ > > It is easy to write a function which does the exact same thing (for the > struct above) and has a return type with a bounded lifetime, and therefore > it does not make sense to me why operator overloading would be restricted > in this fashion (i.e. restricted to return concrete lifetimes). Thanks. > > > > On Wed, Apr 16, 2014 at 2:48 AM, Eric Reed wrote: > >> Could you provide a code sample that causes this error? >> >> >> On Tue, Apr 15, 2014 at 6:28 AM, Artella Coding < >> artella.coding at googlemail.com> wrote: >> >>> >>> Currently if I try to specify lifetimes in the return types of >>> overloaded operators like Index ([]), I get an error message : >>> >>> "method `index` has an incompatible type for trait: expected concrete >>> lifetime, but found bound lifetime parameter &" >>> >>> Why has this restriction been placed, given that I can write custom >>> functions which can have bounded lifetimes specifications in the return >>> type? >>> >>> Thanks >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Mon Apr 21 10:34:05 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Mon, 21 Apr 2014 18:34:05 +0100 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: Hm, it seems to have precautions to stop mrc from materializing on Thumb1. I guess I need to take a better look into what's going wrong on my side. I'll see what I can do with that. On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton wrote: > The split stack patches for ARM were recently upstreamed, and they > were modified when being upstreamed as well. Primarily the location of > the split stack is no longer at a magic address for thumb, but rather > it uses the same instruction as ARM (some thumb processors do indeed > have the coprocessor). More information is in the long thread starting > at the initial attempt to upstream [1]. > > For now you'll have to use no_split_stack because the thumb split > stack will always use a coprocessor, but I'm sure that the upstream > LLVM devs would be quite welcoming to tweaks to the slit-stack support > (I'd also be willing to help). You can find the initial commit for > support at rust-lang/llvm [2]. > > [1] - > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html > [2] - https://github.com/rust-lang/llvm/pull/4 > > On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov > wrote: > > Starting recently (no more than two weeks), rustc is generating a broken > > prologue for arm. Here's the sample assembly: > > 0x00000f44 <+0>: push {r4, r5} > > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} > > 0x00000f4a <+6>: mov r5, sp > > 0x00000f4c <+8>: b.n 0xa78 > > 0x00000f4e <+10>: ands r4, r0 > > 0x00000f50 <+12>: cmp r4, r5 > > 0x00000f52 <+14>: bcc.n 0xf66 > > > <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> > > 0x00000f54 <+16>: movs r4, #16 > > 0x00000f56 <+18>: movs r5, #0 > > 0x00000f58 <+20>: push {lr} > > 0x00000f5a <+22>: bl 0x19d8 <__morestack> > > 0x00000f5e <+26>: ldr.w lr, [sp], #4 > > 0x00000f62 <+30>: pop {r4, r5} > > 0x00000f64 <+32>: bx lr > > > > The problem is at 0x00000f46, where code tries to read from coprocessor > 15 > > register 13, which is "process id register". Well, coprocessor 15 > (actually, > > all of the coprocessors) are missing from my target thumbv7m-linux-eabi > > (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant > > anyway), so I'm getting hardfaults in every function that rust doesn't > > inline. > > > > Any ideas on what might be going wrong? I assume that this is actually > > llvm's fault, as llvm should not materialize machine code which is not > > available for target anyway. > > > > Wrapping everything in #[no_split_stack] is a temporary workaround and > > surely not a long-term strategy. > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at steveklabnik.com Mon Apr 21 10:42:32 2014 From: steve at steveklabnik.com (Steve Klabnik) Date: Mon, 21 Apr 2014 10:42:32 -0700 Subject: [rust-dev] r? Rust on exercism.io Message-ID: Hey all, exercism.io is a site where you can try to solve short programming problems, and then get feedback on your solution from others. A few people have done some great work to get examples going in Rust, and now that 0.10 is out, we want to try to ship it. Would anyone mind checking out the PR and giving some thoughts on the solutions? There's one or two diffs that I'm not 100% sure about. https://github.com/exercism/xrust/pull/8 <3 - Steve From alex.besogonov at gmail.com Sat Apr 19 18:36:31 2014 From: alex.besogonov at gmail.com (Aleksei Besogonov) Date: Sun, 20 Apr 2014 04:36:31 +0300 Subject: [rust-dev] Per-process arenas and ARCs Message-ID: Good ! I?m planning to use Rust for some high-performant low-latency server-side code. It?ll need some complicated data structures for each request, so I?m thinking about using RC boxes for them. Refcounting is, of course, unsuitable for objects with circular links and I?m going to have plenty of them. So I?m thinking about adding per-task arenas that can be freed once the task completes. It looks like it?s possible, but not implemented yet. Additionally, RC boxes are not sendable - is there an easy way to ?upgrade? an object graph to ARCs and then send it? From alex at crichton.co Mon Apr 21 11:21:30 2014 From: alex at crichton.co (Alex Crichton) Date: Mon, 21 Apr 2014 11:21:30 -0700 Subject: [rust-dev] Per-process arenas and ARCs In-Reply-To: References: Message-ID: > Refcounting is, of course, unsuitable for objects with circular links and I?m going to have plenty of them. You may be interested in the downgrade() method on Rc/Arc along with the Weak pointers (they allow cycles, but also allow for destruction). > So I?m thinking about adding per-task arenas that can be freed once the task completes. It looks like it?s possible, but not implemented yet. There is some initial support in libarena [1] you may find useful (specifically the TypedArena) > Additionally, RC boxes are not sendable - is there an easy way to ?upgrade? an object graph to ARCs and then send it? At this time, you'll have to initially create everything as an Arc, you can't upgrade from an Rc to an Arc (totally separate) Hope that help! [1] - http://static.rust-lang.org/doc/master/arena/index.html From banderson at mozilla.com Mon Apr 21 14:06:39 2014 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 21 Apr 2014 14:06:39 -0700 Subject: [rust-dev] Announcing the newest member of Mozilla's Rust team, Aaron Turon Message-ID: <5355885F.3040803@mozilla.com> Hey there, Rusticators, Grand news! Starting today Aaron Turon is joining the Rust team. Aaron did his PhD thesis on concurrency at Northeastern University, where he published widely-noted papers on 'reagents' and 'LVars'. He will be focusing on making Rust's standard libraries the best they can be. He's aturon on IRC; say 'hi' when you see him. Welcome aboard, Aaron. From alex at crichton.co Mon Apr 21 14:18:54 2014 From: alex at crichton.co (Alex Crichton) Date: Mon, 21 Apr 2014 14:18:54 -0700 Subject: [rust-dev] Announcing the newest member of Mozilla's Rust team, Aaron Turon In-Reply-To: <5355885F.3040803@mozilla.com> References: <5355885F.3040803@mozilla.com> Message-ID: Welcome Aaron! I'm so excited to have you with us! On Mon, Apr 21, 2014 at 2:06 PM, Brian Anderson wrote: > Hey there, Rusticators, > > Grand news! Starting today Aaron Turon is joining the Rust team. Aaron did > his PhD thesis on concurrency at Northeastern University, where he published > widely-noted papers on 'reagents' and 'LVars'. He will be focusing on making > Rust's standard libraries the best they can be. He's aturon on IRC; say 'hi' > when you see him. > > Welcome aboard, Aaron. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From ben.striegel at gmail.com Mon Apr 21 15:40:35 2014 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Mon, 21 Apr 2014 18:40:35 -0400 Subject: [rust-dev] Announcing the newest member of Mozilla's Rust team, Aaron Turon In-Reply-To: References: <5355885F.3040803@mozilla.com> Message-ID: Welcome Aaron! And "LVars" sounds familiar... was that something that Lindsey Kuper was working on? On Mon, Apr 21, 2014 at 5:18 PM, Alex Crichton wrote: > Welcome Aaron! I'm so excited to have you with us! > > On Mon, Apr 21, 2014 at 2:06 PM, Brian Anderson > wrote: > > Hey there, Rusticators, > > > > Grand news! Starting today Aaron Turon is joining the Rust team. Aaron > did > > his PhD thesis on concurrency at Northeastern University, where he > published > > widely-noted papers on 'reagents' and 'LVars'. He will be focusing on > making > > Rust's standard libraries the best they can be. He's aturon on IRC; say > 'hi' > > when you see him. > > > > Welcome aboard, Aaron. > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From aturon at mozilla.com Mon Apr 21 15:41:43 2014 From: aturon at mozilla.com (Aaron Turon) Date: Mon, 21 Apr 2014 15:41:43 -0700 (PDT) Subject: [rust-dev] Announcing the newest member of Mozilla's Rust team, Aaron Turon In-Reply-To: <2134075677.18675178.1398119989334.JavaMail.zimbra@mozilla.com> Message-ID: <659913640.18675322.1398120103569.JavaMail.zimbra@mozilla.com> Thanks for the welcome. I've been watching Rust from the academic sidelines with excitement, and I feel very lucky to become part of such a great team! Aaron On Mon, Apr 21, 2014 at 2:06 PM, Brian Anderson wrote: > Hey there, Rusticators, > > Grand news! Starting today Aaron Turon is joining the Rust team. Aaron did > his PhD thesis on concurrency at Northeastern University, where he published > widely-noted papers on 'reagents' and 'LVars'. He will be focusing on making > Rust's standard libraries the best they can be. He's aturon on IRC; say 'hi' > when you see him. > > Welcome aboard, Aaron. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From aturon at mozilla.com Mon Apr 21 15:47:06 2014 From: aturon at mozilla.com (Aaron Turon) Date: Mon, 21 Apr 2014 15:47:06 -0700 (PDT) Subject: [rust-dev] Announcing the newest member of Mozilla's Rust team, Aaron Turon In-Reply-To: References: <5355885F.3040803@mozilla.com> Message-ID: <1089552204.18677280.1398120426972.JavaMail.zimbra@mozilla.com> Yes, LVars are part of Lindsey Kuper's PhD thesis work. We had a paper together on them in this year's POPL: http://www.mpi-sws.org/~turon/lvish.pdf Lindsey did the original LVars design, and then we worked together to extend it to a fuller library implementation called "LVish"; I got to do a lot of fun Haskell concurrency hacking to make it all go, which you can see here: https://github.com/iu-parfunc/lvars/tree/master/haskell/lvish (For those unfamiliar, the nutshell selling point is that LVars let you have your lock-free data structures but guarantee overall deterministic execution too.) Aaron ----- Original Message ----- From: "Benjamin Striegel" Cc: rust-dev at mozilla.org Sent: Monday, April 21, 2014 3:40:35 PM Subject: Re: [rust-dev] Announcing the newest member of Mozilla's Rust team, Aaron Turon Welcome Aaron! And "LVars" sounds familiar... was that something that Lindsey Kuper was working on? On Mon, Apr 21, 2014 at 5:18 PM, Alex Crichton < alex at crichton.co > wrote: Welcome Aaron! I'm so excited to have you with us! On Mon, Apr 21, 2014 at 2:06 PM, Brian Anderson < banderson at mozilla.com > wrote: > Hey there, Rusticators, > > Grand news! Starting today Aaron Turon is joining the Rust team. Aaron did > his PhD thesis on concurrency at Northeastern University, where he published > widely-noted papers on 'reagents' and 'LVars'. He will be focusing on making > Rust's standard libraries the best they can be. He's aturon on IRC; say 'hi' > when you see him. > > Welcome aboard, Aaron. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From cptroot at gmail.com Mon Apr 21 15:54:07 2014 From: cptroot at gmail.com (Evan Davis) Date: Mon, 21 Apr 2014 15:54:07 -0700 Subject: [rust-dev] Generic enums : manually implementing Clone trait In-Reply-To: <53553831.5070707@mozilla.com> References: <53553831.5070707@mozilla.com> Message-ID: On Mon, Apr 21, 2014 at 8:24 AM, Patrick Walton wrote: > > > Because `&` is taken to destructure references, we needed another keyword > to take a reference. Hence, `ref`. > > Patrick > > Is that explanation of ref given anywhere in the rust-lang tutorial? I feel like it would have been incredibly helpful to me as a beginner. -Evan Davis -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Mon Apr 21 16:11:17 2014 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 21 Apr 2014 16:11:17 -0700 Subject: [rust-dev] Call for a "practical" Rust guide Message-ID: <5355A595.1060104@mozilla.com> Hi. I've been convinced recently that Rust is missing crucial documentation of a particular nature: using Rust in practice. I would like to have such a standalone guide, and these are some ideas about what should be in it. This is a guide that runs through creating an entire Rust project from installation, using the tools, writing code, through deployment, touching on the practical aspects of coding Rust, not glossing over whatever ugly bits are necessary to do real work. Some of the topics I might expect include: * Installation * Running rustc * lib.rs/bin.rs/mod.rs conventions * Evolving a project from a single file to multi-file/mod/directory * Picking the correct types for various problems * Obtaining and using other crates * Setting up a build system (not cargo to start, cargo when it's ready) * Working with the compiler to find the correct algorithms. Show typical ways you might concieve the solution incorrectly and how the compiler helps guide you to the correct one. Particularly re: borrowck. * Common Rust patterns (like?) * Rust CI, other community resources? * Using rust-bindgen to create bindings that don't already exist * Error handling * Practical corner cases and workarounds of various types, e.g. - #[path], #[link_args]? There's some overlap here with the current tutorial, which I think is good, since I want to find new homes for most of the content there. I've filed this as issue #13669, but have no plans to work on it personally at this time. If anybody has an interest in taking it on, please coordinate there. Finally, I'd like to update folks with a few words on how I'm currently envisioning the Rust documentation story. I've become convinced that relatively small and self-contained guides are our best format for producing standalone documentation about Rust. By being small, they require minimal investment by any single individual, so we can experiment quite freely with what docs are provided, what order they are presented, and the schedule on which they are created. Right now I am aiming for three introductory guides, serving distinct purposes: * "A 30-minute intro to Rust" - Very high-level, purely to excited prospective users, let them know whether Rust is for them * "The Philosophy of Rust" - Covers about a dozen subjects that are crucial to understanding why Rust is like it is. It would be impossible to do anything useful in Rust without understanding this material: stack vs. heap, ownership, copying, moving, borrowing, lifetimes. Experienced devs will also pick up a lot of basic syntax in passing. * "Practical Rust" - Using Rust to build real software. After these, a new user should be well on their way to writing Rust, especially after reading the various other guides on more focused topics. "The Philosophy of Rust" is a document that Sam Wright, Niko and I are working on. The title will almost certainly change. Sam will have a new pull request up soon. As to the existing tutorial, after the new docs mature I expect to demote it to "The (old) Rust tutorial", then start looking for new homes for the material there. This won't happen for a while, until the new docs are a good enough substitute. Regards, Brian From mozilla at mcpherrin.ca Mon Apr 21 18:32:04 2014 From: mozilla at mcpherrin.ca (Matthew McPherrin) Date: Mon, 21 Apr 2014 18:32:04 -0700 Subject: [rust-dev] Call for a "practical" Rust guide In-Reply-To: <5355A595.1060104@mozilla.com> References: <5355A595.1060104@mozilla.com> Message-ID: I think this sounds good overall. However, I don't think we can completely kill the tutorial: I think we still need a "Getting Started with Rust" document that is an expanded version of the tutorial section of the same name, and an abbreviated version of the rest of the tutorial. I imagine this is much more hand-holding than your practical guide. That should probably go through Installing Rust, writing and running Hello World, and then some simple program involving at least using some standard library code, a struct, enum and function definition. Using a for loop and an if statement. Maybe a simple "guessing game" or something. I'd also imagine it being "localized" for each OS we support, especially with respect to installation, compiling, and running a program. In contrast, I'd expect the "practical guide" to include more information about what options are available for rustc installation, including the merits of source versus nightly installation, etc. Questions that a developer interested in seriously using rust may care about, but which would be "noise" for someone wanting to quickly try out Rust. On Mon, Apr 21, 2014 at 4:11 PM, Brian Anderson wrote: > Hi. > > I've been convinced recently that Rust is missing crucial documentation of a > particular nature: using Rust in practice. I would like to have such a > standalone guide, and these are some ideas about what should be in it. > > This is a guide that runs through creating an entire Rust project from > installation, using the tools, writing code, through deployment, touching on > the practical aspects of coding Rust, not glossing over whatever ugly bits > are necessary to do real work. > > Some of the topics I might expect include: > > * Installation > * Running rustc > * lib.rs/bin.rs/mod.rs conventions > * Evolving a project from a single file to multi-file/mod/directory > * Picking the correct types for various problems > * Obtaining and using other crates > * Setting up a build system (not cargo to start, cargo when it's ready) > * Working with the compiler to find the correct algorithms. Show typical > ways you might concieve the solution incorrectly and how the compiler helps > guide you to the correct one. Particularly re: borrowck. > * Common Rust patterns (like?) > * Rust CI, other community resources? > * Using rust-bindgen to create bindings that don't already exist > * Error handling > * Practical corner cases and workarounds of various types, e.g. > - #[path], #[link_args]? > > There's some overlap here with the current tutorial, which I think is good, > since I want to find new homes for most of the content there. > > I've filed this as issue #13669, but have no plans to work on it personally > at this time. If anybody has an interest in taking it on, please coordinate > there. > > Finally, I'd like to update folks with a few words on how I'm currently > envisioning the Rust documentation story. > > I've become convinced that relatively small and self-contained guides are > our best format for producing standalone documentation about Rust. By being > small, they require minimal investment by any single individual, so we can > experiment quite freely with what docs are provided, what order they are > presented, and the schedule on which they are created. > > Right now I am aiming for three introductory guides, serving distinct > purposes: > > * "A 30-minute intro to Rust" - Very high-level, purely to excited > prospective users, let them know whether Rust is for them > * "The Philosophy of Rust" - Covers about a dozen subjects that are crucial > to understanding why Rust is like it is. It would be impossible to do > anything useful in Rust without understanding this material: stack vs. heap, > ownership, copying, moving, borrowing, lifetimes. Experienced devs will also > pick up a lot of basic syntax in passing. > * "Practical Rust" - Using Rust to build real software. > > After these, a new user should be well on their way to writing Rust, > especially after reading the various other guides on more focused topics. > > "The Philosophy of Rust" is a document that Sam Wright, Niko and I are > working on. The title will almost certainly change. Sam will have a new pull > request up soon. > > As to the existing tutorial, after the new docs mature I expect to demote it > to "The (old) Rust tutorial", then start looking for new homes for the > material there. This won't happen for a while, until the new docs are a good > enough substitute. > > Regards, > Brian > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From daimrod at gmail.com Mon Apr 21 19:40:45 2014 From: daimrod at gmail.com (Daimrod) Date: Tue, 22 Apr 2014 11:40:45 +0900 Subject: [rust-dev] Call for a "practical" Rust guide In-Reply-To: <5355A595.1060104@mozilla.com> (Brian Anderson's message of "Mon, 21 Apr 2014 16:11:17 -0700") References: <5355A595.1060104@mozilla.com> Message-ID: <87a9bekrwy.fsf@tanger.home> Brian Anderson writes: > Hi. Hi, > I've been convinced recently that Rust is missing crucial > documentation of a particular nature: using Rust in practice. I would > like to have such a standalone guide, and these are some ideas about > what should be in it. > > This is a guide that runs through creating an entire Rust project from > installation, using the tools, writing code, through deployment, > touching on the practical aspects of coding Rust, not glossing over > whatever ugly bits are necessary to do real work. As a newbie, I would love to read a tutorial on how to implement a basic data structure but with non-trivial operation. For example, the current tutorial shows a single linked list with two operations: eq and append. But when I tried to implement some methods like a `push_back` or an `insert` that keeps the list sorted I hit a wall (especially because I wanted them iterative not recursive). Maybe it is because I have done some C but almost no C++ and no "modern" C++ at all (no smart pointers or RAII), but even though I've read the Pointers and Lifetime&Reference Guides, I still have difficulties to know how to manipulate objects because it requires a good understanding of a mix of concepts (owned box/borrowed box/pointers + lifetime + [im]mutability). I understand more or less each of them individually, but in practice, I'm mostly playing a "guess game" with the compiler. To summarize, I think that a guide that shows how Rust fits "in the large" is good, but it's especially good for people with a C++ background who want to know how Rust can replace C++ for big projects. However, I think that people that are used to more high-level languages (I'm mostly a Lisp guy) lack the "low bits" of Rust. But I also think that it's this aspect of Rust that appeals to them, though I may be generalizing my own feeling. Best, -- Daimrod/Greg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From lkuper at cs.indiana.edu Mon Apr 21 23:19:54 2014 From: lkuper at cs.indiana.edu (Lindsey Kuper) Date: Tue, 22 Apr 2014 02:19:54 -0400 Subject: [rust-dev] Announcing the newest member of Mozilla's Rust team, Aaron Turon Message-ID: Congratulations, Aaron! Very exciting! > And "LVars" sounds familiar... was that something that Lindsey Kuper was working on? Yep. In addition to the POPL paper that Aaron linked to, you can find everything LVars at http://www.cs.indiana.edu/~lkuper/, or on my blog under http://composition.al/blog/categories/lvars/ . Of course, now that Aaron is on the Rust team, I wouldn't be shocked if an LVars library for Rust turned up any day now. ;) Lindsey From yannick.dominguez at gmail.com Tue Apr 22 00:18:51 2014 From: yannick.dominguez at gmail.com (Yannick Dominguez) Date: Tue, 22 Apr 2014 09:18:51 +0200 Subject: [rust-dev] Remember RustMeetup paris 03 Tonight In-Reply-To: <53551CC0.2050109@darnuria.eu> References: <53551CC0.2050109@darnuria.eu> Message-ID: Thanks for the meetup, it was nice meeting you guys. See you next month ! 2014-04-21 15:27 GMT+02:00 Axel Viala : > That confirmed it's tonight! > > Third of his name. > > Planing: > 18:00 -> 19:30: Lunch and informal meeting. > 19:30 -> 23:00: Workshops for different levels. > > Reps Page: https://reps.mozilla.org/e/meetup-rust-paris-03/ > Inscription and attendees:https://etherpad.mozilla.org/remo-meetup-rust-paris-03 > > > Important: Bring some food it's a holiday in France so buying take-off food will be expensive! ;) > > Thanks! > *Et Bonne journ?e from France!* > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Tue Apr 22 00:43:18 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Tue, 22 Apr 2014 08:43:18 +0100 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: The problem is that mrc is generated unless target is thumb1, but cortex-m3 is thumb2 that still doesn't support mrc: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html, so an additional check to ST->TargetTriple.Data is required to verify it's not thumbv7m. Do I need to submit patch against https://github.com/rust-lang/llvm or send it to upstream? On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov wrote: > Hm, it seems to have precautions to stop mrc from materializing on Thumb1. > I guess I need to take a better look into what's going wrong on my side. > I'll see what I can do with that. > > > On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton wrote: > >> The split stack patches for ARM were recently upstreamed, and they >> were modified when being upstreamed as well. Primarily the location of >> the split stack is no longer at a magic address for thumb, but rather >> it uses the same instruction as ARM (some thumb processors do indeed >> have the coprocessor). More information is in the long thread starting >> at the initial attempt to upstream [1]. >> >> For now you'll have to use no_split_stack because the thumb split >> stack will always use a coprocessor, but I'm sure that the upstream >> LLVM devs would be quite welcoming to tweaks to the slit-stack support >> (I'd also be willing to help). You can find the initial commit for >> support at rust-lang/llvm [2]. >> >> [1] - >> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html >> [2] - https://github.com/rust-lang/llvm/pull/4 >> >> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov >> wrote: >> > Starting recently (no more than two weeks), rustc is generating a broken >> > prologue for arm. Here's the sample assembly: >> > 0x00000f44 <+0>: push {r4, r5} >> > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} >> > 0x00000f4a <+6>: mov r5, sp >> > 0x00000f4c <+8>: b.n 0xa78 >> > 0x00000f4e <+10>: ands r4, r0 >> > 0x00000f50 <+12>: cmp r4, r5 >> > 0x00000f52 <+14>: bcc.n 0xf66 >> > >> <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> >> > 0x00000f54 <+16>: movs r4, #16 >> > 0x00000f56 <+18>: movs r5, #0 >> > 0x00000f58 <+20>: push {lr} >> > 0x00000f5a <+22>: bl 0x19d8 <__morestack> >> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 >> > 0x00000f62 <+30>: pop {r4, r5} >> > 0x00000f64 <+32>: bx lr >> > >> > The problem is at 0x00000f46, where code tries to read from coprocessor >> 15 >> > register 13, which is "process id register". Well, coprocessor 15 >> (actually, >> > all of the coprocessors) are missing from my target thumbv7m-linux-eabi >> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant >> > anyway), so I'm getting hardfaults in every function that rust doesn't >> > inline. >> > >> > Any ideas on what might be going wrong? I assume that this is actually >> > llvm's fault, as llvm should not materialize machine code which is not >> > available for target anyway. >> > >> > Wrapping everything in #[no_split_stack] is a temporary workaround and >> > surely not a long-term strategy. >> > >> > -- >> > Sincerely, >> > Vladimir "Farcaller" Pouzanov >> > http://farcaller.net/ >> > >> > _______________________________________________ >> > Rust-dev mailing list >> > Rust-dev at mozilla.org >> > https://mail.mozilla.org/listinfo/rust-dev >> > >> > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Tue Apr 22 00:54:11 2014 From: corey at octayn.net (Corey Richardson) Date: Tue, 22 Apr 2014 03:54:11 -0400 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: Sending it upstream is far better. Ping someone (probably Alex) to upgrade our LLVM once it's merged. On Tue, Apr 22, 2014 at 3:43 AM, Vladimir Pouzanov wrote: > The problem is that mrc is generated unless target is thumb1, but cortex-m3 > is thumb2 that still doesn't support mrc: > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html, > so an additional check to ST->TargetTriple.Data is required to verify it's > not thumbv7m. > > Do I need to submit patch against https://github.com/rust-lang/llvm or send > it to upstream? > > > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov > wrote: >> >> Hm, it seems to have precautions to stop mrc from materializing on Thumb1. >> I guess I need to take a better look into what's going wrong on my side. >> I'll see what I can do with that. >> >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton wrote: >>> >>> The split stack patches for ARM were recently upstreamed, and they >>> were modified when being upstreamed as well. Primarily the location of >>> the split stack is no longer at a magic address for thumb, but rather >>> it uses the same instruction as ARM (some thumb processors do indeed >>> have the coprocessor). More information is in the long thread starting >>> at the initial attempt to upstream [1]. >>> >>> For now you'll have to use no_split_stack because the thumb split >>> stack will always use a coprocessor, but I'm sure that the upstream >>> LLVM devs would be quite welcoming to tweaks to the slit-stack support >>> (I'd also be willing to help). You can find the initial commit for >>> support at rust-lang/llvm [2]. >>> >>> [1] - >>> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html >>> [2] - https://github.com/rust-lang/llvm/pull/4 >>> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov >>> wrote: >>> > Starting recently (no more than two weeks), rustc is generating a >>> > broken >>> > prologue for arm. Here's the sample assembly: >>> > 0x00000f44 <+0>: push {r4, r5} >>> > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} >>> > 0x00000f4a <+6>: mov r5, sp >>> > 0x00000f4c <+8>: b.n 0xa78 >>> > 0x00000f4e <+10>: ands r4, r0 >>> > 0x00000f50 <+12>: cmp r4, r5 >>> > 0x00000f52 <+14>: bcc.n 0xf66 >>> > >>> > <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> >>> > 0x00000f54 <+16>: movs r4, #16 >>> > 0x00000f56 <+18>: movs r5, #0 >>> > 0x00000f58 <+20>: push {lr} >>> > 0x00000f5a <+22>: bl 0x19d8 <__morestack> >>> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 >>> > 0x00000f62 <+30>: pop {r4, r5} >>> > 0x00000f64 <+32>: bx lr >>> > >>> > The problem is at 0x00000f46, where code tries to read from coprocessor >>> > 15 >>> > register 13, which is "process id register". Well, coprocessor 15 >>> > (actually, >>> > all of the coprocessors) are missing from my target thumbv7m-linux-eabi >>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be >>> > redundant >>> > anyway), so I'm getting hardfaults in every function that rust doesn't >>> > inline. >>> > >>> > Any ideas on what might be going wrong? I assume that this is actually >>> > llvm's fault, as llvm should not materialize machine code which is not >>> > available for target anyway. >>> > >>> > Wrapping everything in #[no_split_stack] is a temporary workaround and >>> > surely not a long-term strategy. >>> > >>> > -- >>> > Sincerely, >>> > Vladimir "Farcaller" Pouzanov >>> > http://farcaller.net/ >>> > >>> > _______________________________________________ >>> > Rust-dev mailing list >>> > Rust-dev at mozilla.org >>> > https://mail.mozilla.org/listinfo/rust-dev >>> > >> >> >> >> >> -- >> Sincerely, >> Vladimir "Farcaller" Pouzanov >> http://farcaller.net/ > > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- http://octayn.net/ From alex at crichton.co Tue Apr 22 01:00:06 2014 From: alex at crichton.co (Alex Crichton) Date: Tue, 22 Apr 2014 01:00:06 -0700 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: I agree with Corey, it's much better to send it upstream first. I'd be more than willing to help you out with writing tests or taking a peek at the patch if you want! I'm acrichto on IRC On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov wrote: > The problem is that mrc is generated unless target is thumb1, but cortex-m3 > is thumb2 that still doesn't support mrc: > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html, > so an additional check to ST->TargetTriple.Data is required to verify it's > not thumbv7m. > > Do I need to submit patch against https://github.com/rust-lang/llvm or send > it to upstream? > > > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov > wrote: >> >> Hm, it seems to have precautions to stop mrc from materializing on Thumb1. >> I guess I need to take a better look into what's going wrong on my side. >> I'll see what I can do with that. >> >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton wrote: >>> >>> The split stack patches for ARM were recently upstreamed, and they >>> were modified when being upstreamed as well. Primarily the location of >>> the split stack is no longer at a magic address for thumb, but rather >>> it uses the same instruction as ARM (some thumb processors do indeed >>> have the coprocessor). More information is in the long thread starting >>> at the initial attempt to upstream [1]. >>> >>> For now you'll have to use no_split_stack because the thumb split >>> stack will always use a coprocessor, but I'm sure that the upstream >>> LLVM devs would be quite welcoming to tweaks to the slit-stack support >>> (I'd also be willing to help). You can find the initial commit for >>> support at rust-lang/llvm [2]. >>> >>> [1] - >>> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html >>> [2] - https://github.com/rust-lang/llvm/pull/4 >>> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov >>> wrote: >>> > Starting recently (no more than two weeks), rustc is generating a >>> > broken >>> > prologue for arm. Here's the sample assembly: >>> > 0x00000f44 <+0>: push {r4, r5} >>> > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} >>> > 0x00000f4a <+6>: mov r5, sp >>> > 0x00000f4c <+8>: b.n 0xa78 >>> > 0x00000f4e <+10>: ands r4, r0 >>> > 0x00000f50 <+12>: cmp r4, r5 >>> > 0x00000f52 <+14>: bcc.n 0xf66 >>> > >>> > <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> >>> > 0x00000f54 <+16>: movs r4, #16 >>> > 0x00000f56 <+18>: movs r5, #0 >>> > 0x00000f58 <+20>: push {lr} >>> > 0x00000f5a <+22>: bl 0x19d8 <__morestack> >>> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 >>> > 0x00000f62 <+30>: pop {r4, r5} >>> > 0x00000f64 <+32>: bx lr >>> > >>> > The problem is at 0x00000f46, where code tries to read from coprocessor >>> > 15 >>> > register 13, which is "process id register". Well, coprocessor 15 >>> > (actually, >>> > all of the coprocessors) are missing from my target thumbv7m-linux-eabi >>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be >>> > redundant >>> > anyway), so I'm getting hardfaults in every function that rust doesn't >>> > inline. >>> > >>> > Any ideas on what might be going wrong? I assume that this is actually >>> > llvm's fault, as llvm should not materialize machine code which is not >>> > available for target anyway. >>> > >>> > Wrapping everything in #[no_split_stack] is a temporary workaround and >>> > surely not a long-term strategy. >>> > >>> > -- >>> > Sincerely, >>> > Vladimir "Farcaller" Pouzanov >>> > http://farcaller.net/ >>> > >>> > _______________________________________________ >>> > Rust-dev mailing list >>> > Rust-dev at mozilla.org >>> > https://mail.mozilla.org/listinfo/rust-dev >>> > >> >> >> >> >> -- >> Sincerely, >> Vladimir "Farcaller" Pouzanov >> http://farcaller.net/ > > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ From artella.coding at googlemail.com Tue Apr 22 02:25:55 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Tue, 22 Apr 2014 10:25:55 +0100 Subject: [rust-dev] Call for a "practical" Rust guide In-Reply-To: <5355A595.1060104@mozilla.com> References: <5355A595.1060104@mozilla.com> Message-ID: On the related matter of reference material, ClojureDocs seems quite good as a reference guide : http://clojuredocs.org/ http://clojuredocs.org/clojure_core/clojure.core/reduce and seems editable by the community. The std API guide : http://static.rust-lang.org/doc/master/std/index.html is similar, but it seems that the community cannot edit and add their own examples. p.s. I am finding the tutorial at http://static.rust-lang.org/doc/master/tutorial.html very useful. On Tue, Apr 22, 2014 at 12:11 AM, Brian Anderson wrote: > Hi. > > I've been convinced recently that Rust is missing crucial documentation of > a particular nature: using Rust in practice. I would like to have such a > standalone guide, and these are some ideas about what should be in it. > > This is a guide that runs through creating an entire Rust project from > installation, using the tools, writing code, through deployment, touching > on the practical aspects of coding Rust, not glossing over whatever ugly > bits are necessary to do real work. > > Some of the topics I might expect include: > > * Installation > * Running rustc > * lib.rs/bin.rs/mod.rs conventions > * Evolving a project from a single file to multi-file/mod/directory > * Picking the correct types for various problems > * Obtaining and using other crates > * Setting up a build system (not cargo to start, cargo when it's ready) > * Working with the compiler to find the correct algorithms. Show typical > ways you might concieve the solution incorrectly and how the compiler helps > guide you to the correct one. Particularly re: borrowck. > * Common Rust patterns (like?) > * Rust CI, other community resources? > * Using rust-bindgen to create bindings that don't already exist > * Error handling > * Practical corner cases and workarounds of various types, e.g. > - #[path], #[link_args]? > > There's some overlap here with the current tutorial, which I think is > good, since I want to find new homes for most of the content there. > > I've filed this as issue #13669, but have no plans to work on it > personally at this time. If anybody has an interest in taking it on, please > coordinate there. > > Finally, I'd like to update folks with a few words on how I'm currently > envisioning the Rust documentation story. > > I've become convinced that relatively small and self-contained guides are > our best format for producing standalone documentation about Rust. By being > small, they require minimal investment by any single individual, so we can > experiment quite freely with what docs are provided, what order they are > presented, and the schedule on which they are created. > > Right now I am aiming for three introductory guides, serving distinct > purposes: > > * "A 30-minute intro to Rust" - Very high-level, purely to excited > prospective users, let them know whether Rust is for them > * "The Philosophy of Rust" - Covers about a dozen subjects that are > crucial to understanding why Rust is like it is. It would be impossible to > do anything useful in Rust without understanding this material: stack vs. > heap, ownership, copying, moving, borrowing, lifetimes. Experienced devs > will also pick up a lot of basic syntax in passing. > * "Practical Rust" - Using Rust to build real software. > > After these, a new user should be well on their way to writing Rust, > especially after reading the various other guides on more focused topics. > > "The Philosophy of Rust" is a document that Sam Wright, Niko and I are > working on. The title will almost certainly change. Sam will have a new > pull request up soon. > > As to the existing tutorial, after the new docs mature I expect to demote > it to "The (old) Rust tutorial", then start looking for new homes for the > material there. This won't happen for a while, until the new docs are a > good enough substitute. > > Regards, > Brian > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From com.liigo at gmail.com Tue Apr 22 03:37:29 2014 From: com.liigo at gmail.com (Liigo Zhuang) Date: Tue, 22 Apr 2014 18:37:29 +0800 Subject: [rust-dev] Call for a "practical" Rust guide In-Reply-To: <5355A595.1060104@mozilla.com> References: <5355A595.1060104@mozilla.com> Message-ID: Along with the "A 30-minute intro to Rust", we also need a 1-minute and/or 5-minute intro, in rust-lang.org website. 2014?4?22? ??7:11? "Brian Anderson" ??? > Hi. > > I've been convinced recently that Rust is missing crucial documentation of > a particular nature: using Rust in practice. I would like to have such a > standalone guide, and these are some ideas about what should be in it. > > This is a guide that runs through creating an entire Rust project from > installation, using the tools, writing code, through deployment, touching > on the practical aspects of coding Rust, not glossing over whatever ugly > bits are necessary to do real work. > > Some of the topics I might expect include: > > * Installation > * Running rustc > * lib.rs/bin.rs/mod.rs conventions > * Evolving a project from a single file to multi-file/mod/directory > * Picking the correct types for various problems > * Obtaining and using other crates > * Setting up a build system (not cargo to start, cargo when it's ready) > * Working with the compiler to find the correct algorithms. Show typical > ways you might concieve the solution incorrectly and how the compiler helps > guide you to the correct one. Particularly re: borrowck. > * Common Rust patterns (like?) > * Rust CI, other community resources? > * Using rust-bindgen to create bindings that don't already exist > * Error handling > * Practical corner cases and workarounds of various types, e.g. > - #[path], #[link_args]? > > There's some overlap here with the current tutorial, which I think is > good, since I want to find new homes for most of the content there. > > I've filed this as issue #13669, but have no plans to work on it > personally at this time. If anybody has an interest in taking it on, please > coordinate there. > > Finally, I'd like to update folks with a few words on how I'm currently > envisioning the Rust documentation story. > > I've become convinced that relatively small and self-contained guides are > our best format for producing standalone documentation about Rust. By being > small, they require minimal investment by any single individual, so we can > experiment quite freely with what docs are provided, what order they are > presented, and the schedule on which they are created. > > Right now I am aiming for three introductory guides, serving distinct > purposes: > > * "A 30-minute intro to Rust" - Very high-level, purely to excited > prospective users, let them know whether Rust is for them > * "The Philosophy of Rust" - Covers about a dozen subjects that are > crucial to understanding why Rust is like it is. It would be impossible to > do anything useful in Rust without understanding this material: stack vs. > heap, ownership, copying, moving, borrowing, lifetimes. Experienced devs > will also pick up a lot of basic syntax in passing. > * "Practical Rust" - Using Rust to build real software. > > After these, a new user should be well on their way to writing Rust, > especially after reading the various other guides on more focused topics. > > "The Philosophy of Rust" is a document that Sam Wright, Niko and I are > working on. The title will almost certainly change. Sam will have a new > pull request up soon. > > As to the existing tutorial, after the new docs mature I expect to demote > it to "The (old) Rust tutorial", then start looking for new homes for the > material there. This won't happen for a while, until the new docs are a > good enough substitute. > > Regards, > Brian > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Tue Apr 22 06:45:40 2014 From: rusty.gates at icloud.com (Tommi) Date: Tue, 22 Apr 2014 16:45:40 +0300 Subject: [rust-dev] Private trait items In-Reply-To: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> References: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> Message-ID: No one? I understand that a part of the reason the RFC process is made so complex is that it filters out idiots like me. But I think this one is a pretty important design choice that Rust is about to get wrong. On 2014-04-18, at 6:27, Tommi wrote: > Could someone please commit this RFC for me, thank you: > > - Start Date: 2014-04-18 > - RFC PR #: > - Rust Issue #: > > # Summary > > I propose the ability to set trait items (i.e. just methods currently) private as well as public in order to expand the scope of possible use cases of provided methods (i.e. default trait method implementations). I also propose that trait items should be private by default. > > # Motivation > > Sometimes a trait may be able to provide a default implementation for a method iff it can use a certain method which only the type that implements the trait is in a position to provide a definition for. Often times such a feedback method is supposed to be only a tool for the trait to be able to define provided methods with, and as such, not supposed to become a part of the public interface of the trait or any type which implements the trait. Therefore such a feedback method should be made private. Trait items should be private by default so that we don't have the need to reintroduce the 'priv' keyword. If in future we get the ability to specify that a certain provided method in a trait is 'final' (i.e. not overridable by the type which implements the trait), then, together with private trait methods, we can use the Non-Virtual Interface (NVI) idiom coined and described here by Herb Sutter: http://www.gotw.ca/publications/mill18.htm > > # Detailed design > > One way of looking at private trait methods (or any private trait items) is to see them as private dialog between a trait and a type which implements the trait. This view could lead to a design where no-one else except the trait and the type which implements it is allowed access to such private feedback item. But given how Rust privacy rules work at module boundaries (and also extend access to submodules), it would make sense that access to a private trait item extended from just the trait or the type which implements it to the enclosing module and its submodules. By this logic I suggest the following privacy rules for private trait items: > > Given that: > 1) A trait ```Tr``` specifies a private item ```priv_item``` and is defined in module ```mod_tr``` > 3) A type ```Foo``` implements ```Tr``` and is defined in module ```mod_foo``` > 3) A type ```Bar``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` > 4) A type ```Baz``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` > > It follows that: > 1) ```priv_item``` is accessible from ```mod_tr``` and all its submodules. > 2) ```priv_item``` is accessible from ```mod_foo``` and all its submodules iff it is certain at compile-time that it refers to the ```Foo```'s implementation ```priv_item``` > 3) ```priv_item``` is accessible from ```mod_bar_and_baz``` and all its submodules iff it is certain at compile-time that it refers to either the ```Bar```'s or ```Baz```'s implementation of ```priv_item``` > > And ```priv_item``` is not accessible from anywhere else. > > Example: > ``` > // in mod_tr.rs > pub trait Tr { > priv fn priv_item(&self); > > pub fn do_stuff(&self) { > self.priv_item(); // OK > } > } > > pub fn do_other_stuff(a: &A) { > a.priv_item(); // OK > } > > // in mod_foo.rs > use mod_tr::Tr; > > pub struct Foo; > > impl Tr for Foo { > priv fn priv_item(&self) {} > } > > pub fn do_foo_stuff(foo: &Foo) { > foo.priv_item(); // OK > } > > pub fn do_incorrect_stuff(a: &A) { > a.priv_item(); // ERROR: "A private trait item Tr::priv_item not accessible from mod_foo" > } > ``` > > # Alternatives > > > > # Unresolved questions > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From flaper87 at gmail.com Tue Apr 22 06:52:36 2014 From: flaper87 at gmail.com (Flaper87) Date: Tue, 22 Apr 2014 15:52:36 +0200 Subject: [rust-dev] Private trait items In-Reply-To: References: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> Message-ID: 2014-04-22 15:45 GMT+02:00 Tommi : > No one? > > I understand that a part of the reason the RFC process is made so complex > is that it filters out idiots like me. But I think this one is a pretty > important design choice that Rust is about to get wrong. > > If the RFC process is complex, then I believe there's something we should probably make easier. The idea is not to filter folks out but to welcome them and make the collaboration process easier for everyone What parts of this process are complex? [0] What problems are you having with GitHub? Have you looked into this guide? [1] [0] https://github.com/rust-lang/rfcs/blob/master/active/0001-rfc-process.md [1] https://help.github.com/articles/using-pull-requests Flavio -- Flavio (@flaper87) Percoco http://www.flaper87.com http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Tue Apr 22 09:10:09 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Tue, 22 Apr 2014 17:10:09 +0100 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack Message-ID: This is the project I've been tinkering with for a good number of weekends ? zinc, the bare metal stack for rust is available at https://github.com/hackndev/zinc. I've just finished a major refactoring work for LPC1768 code, so STM32F4 is kind of broken yet, and LPC1114 is totally dropped, but I'll fix that soon. The current code supports GPIO operations, UART and SSP in SPI mode for NXP LPC1768, also featuring a driver for http://mbed.org/cookbook/mbed-application-board TFT LCD and for ILI9341-based TFT LCDs commonly found on ebay. My plan is to fix support for STM32F4, bring it to the level of NXP part and try to expand this to a small RTOS, which would be a nice demo of rust capabilities for embedded development. The code is licensed under Apache-2.0. There's no readme yet, but you can see the demo applications written with zinc here: https://github.com/hackndev/zinc/tree/master/apps. -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From douglas.linder at gmail.com Mon Apr 21 18:17:08 2014 From: douglas.linder at gmail.com (Doug) Date: Tue, 22 Apr 2014 09:17:08 +0800 Subject: [rust-dev] Call for a "practical" Rust guide In-Reply-To: <5355A595.1060104@mozilla.com> References: <5355A595.1060104@mozilla.com> Message-ID: Just my $0.02; totally agree; a proper guide to linking (specifically the 'right' way to link when you have a crate with external C library dependencies), and interacting directly with ffi (str <--> char * for example) would be extremely useful. I've been going through the process of doing that stuff the last week or two and there isn't really any good guidance on the topic other than 'don't look at the standard library as an example of how to do it'. ~ Doug. On Tue, Apr 22, 2014 at 7:11 AM, Brian Anderson wrote: > Hi. > > I've been convinced recently that Rust is missing crucial documentation of > a particular nature: using Rust in practice. I would like to have such a > standalone guide, and these are some ideas about what should be in it. > > This is a guide that runs through creating an entire Rust project from > installation, using the tools, writing code, through deployment, touching > on the practical aspects of coding Rust, not glossing over whatever ugly > bits are necessary to do real work. > > Some of the topics I might expect include: > > * Installation > * Running rustc > * lib.rs/bin.rs/mod.rs conventions > * Evolving a project from a single file to multi-file/mod/directory > * Picking the correct types for various problems > * Obtaining and using other crates > * Setting up a build system (not cargo to start, cargo when it's ready) > * Working with the compiler to find the correct algorithms. Show typical > ways you might concieve the solution incorrectly and how the compiler helps > guide you to the correct one. Particularly re: borrowck. > * Common Rust patterns (like?) > * Rust CI, other community resources? > * Using rust-bindgen to create bindings that don't already exist > * Error handling > * Practical corner cases and workarounds of various types, e.g. > - #[path], #[link_args]? > > There's some overlap here with the current tutorial, which I think is > good, since I want to find new homes for most of the content there. > > I've filed this as issue #13669, but have no plans to work on it > personally at this time. If anybody has an interest in taking it on, please > coordinate there. > > Finally, I'd like to update folks with a few words on how I'm currently > envisioning the Rust documentation story. > > I've become convinced that relatively small and self-contained guides are > our best format for producing standalone documentation about Rust. By being > small, they require minimal investment by any single individual, so we can > experiment quite freely with what docs are provided, what order they are > presented, and the schedule on which they are created. > > Right now I am aiming for three introductory guides, serving distinct > purposes: > > * "A 30-minute intro to Rust" - Very high-level, purely to excited > prospective users, let them know whether Rust is for them > * "The Philosophy of Rust" - Covers about a dozen subjects that are > crucial to understanding why Rust is like it is. It would be impossible to > do anything useful in Rust without understanding this material: stack vs. > heap, ownership, copying, moving, borrowing, lifetimes. Experienced devs > will also pick up a lot of basic syntax in passing. > * "Practical Rust" - Using Rust to build real software. > > After these, a new user should be well on their way to writing Rust, > especially after reading the various other guides on more focused topics. > > "The Philosophy of Rust" is a document that Sam Wright, Niko and I are > working on. The title will almost certainly change. Sam will have a new > pull request up soon. > > As to the existing tutorial, after the new docs mature I expect to demote > it to "The (old) Rust tutorial", then start looking for new homes for the > material there. This won't happen for a while, until the new docs are a > good enough substitute. > > Regards, > Brian > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Tue Apr 22 11:44:35 2014 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 22 Apr 2014 11:44:35 -0700 Subject: [rust-dev] Private trait items In-Reply-To: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> References: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> Message-ID: <5356B893.2010107@mozilla.com> I'm not sure what you are asking for here. Have you submitted this as a pull request to http://github.com/rust-lang/rfcs? I do realize that the RFC process takes time to get things approved, but some have been, and I expect the rate of approvals to continue steadily. On 04/17/2014 08:27 PM, Tommi wrote: > Could someone please commit this RFC for me, thank you: > > - Start Date: 2014-04-18 > - RFC PR #: > - Rust Issue #: > > # Summary > > I propose the ability to set trait items (i.e. just methods currently) private as well as public in order to expand the scope of possible use cases of provided methods (i.e. default trait method implementations). I also propose that trait items should be private by default. > > # Motivation > > Sometimes a trait may be able to provide a default implementation for a method iff it can use a certain method which only the type that implements the trait is in a position to provide a definition for. Often times such a feedback method is supposed to be only a tool for the trait to be able to define provided methods with, and as such, not supposed to become a part of the public interface of the trait or any type which implements the trait. Therefore such a feedback method should be made private. Trait items should be private by default so that we don't have the need to reintroduce the 'priv' keyword. If in future we get the ability to specify that a certain provided method in a trait is 'final' (i.e. not overridable by the type which implements the trait), then, together with private trait methods, we can use the Non-Virtual Interface (NVI) idiom coined and described here by Herb Sutter: http://www.gotw.ca/publications/mill18.htm > > # Detailed design > > One way of looking at private trait methods (or any private trait items) is to see them as private dialog between a trait and a type which implements the trait. This view could lead to a design where no-one else except the trait and the type which implements it is allowed access to such private feedback item. But given how Rust privacy rules work at module boundaries (and also extend access to submodules), it would make sense that access to a private trait item extended from just the trait or the type which implements it to the enclosing module and its submodules. By this logic I suggest the following privacy rules for private trait items: > > Given that: > 1) A trait ```Tr``` specifies a private item ```priv_item``` and is defined in module ```mod_tr``` > 3) A type ```Foo``` implements ```Tr``` and is defined in module ```mod_foo``` > 3) A type ```Bar``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` > 4) A type ```Baz``` implements ```Tr``` and is defined in module ```mod_bar_and_baz``` > > It follows that: > 1) ```priv_item``` is accessible from ```mod_tr``` and all its submodules. > 2) ```priv_item``` is accessible from ```mod_foo``` and all its submodules iff it is certain at compile-time that it refers to the ```Foo```'s implementation ```priv_item``` > 3) ```priv_item``` is accessible from ```mod_bar_and_baz``` and all its submodules iff it is certain at compile-time that it refers to either the ```Bar```'s or ```Baz```'s implementation of ```priv_item``` > > And ```priv_item``` is not accessible from anywhere else. > > Example: > ``` > // in mod_tr.rs > pub trait Tr { > priv fn priv_item(&self); > > pub fn do_stuff(&self) { > self.priv_item(); // OK > } > } > > pub fn do_other_stuff(a: &A) { > a.priv_item(); // OK > } > > // in mod_foo.rs > use mod_tr::Tr; > > pub struct Foo; > > impl Tr for Foo { > priv fn priv_item(&self) {} > } > > pub fn do_foo_stuff(foo: &Foo) { > foo.priv_item(); // OK > } > > pub fn do_incorrect_stuff(a: &A) { > a.priv_item(); // ERROR: "A private trait item Tr::priv_item not accessible from mod_foo" > } > ``` > > # Alternatives > > > > # Unresolved questions > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From banderson at mozilla.com Tue Apr 22 11:50:18 2014 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 22 Apr 2014 11:50:18 -0700 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: Message-ID: <5356B9EA.905@mozilla.com> This sounds very useful. Thanks for letting us know. On 04/22/2014 09:10 AM, Vladimir Pouzanov wrote: > This is the project I've been tinkering with for a good number of > weekends ? zinc, the bare metal stack for rust is available at > https://github.com/hackndev/zinc. > > I've just finished a major refactoring work for LPC1768 code, so STM32F4 > is kind of broken yet, and LPC1114 is totally dropped, but I'll fix that > soon. > > The current code supports GPIO operations, UART and SSP in SPI mode for > NXP LPC1768, also featuring a driver for > http://mbed.org/cookbook/mbed-application-board TFT LCD and for > ILI9341-based TFT LCDs commonly found on ebay. > > My plan is to fix support for STM32F4, bring it to the level of NXP part > and try to expand this to a small RTOS, which would be a nice demo of > rust capabilities for embedded development. > > The code is licensed under Apache-2.0. > > There's no readme yet, but you can see the demo applications written > with zinc here: https://github.com/hackndev/zinc/tree/master/apps. > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From rusty.gates at icloud.com Tue Apr 22 14:52:41 2014 From: rusty.gates at icloud.com (Tommi) Date: Wed, 23 Apr 2014 00:52:41 +0300 Subject: [rust-dev] Private trait items In-Reply-To: References: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> Message-ID: The complex part of the process is figuring out how GitHub works. The problem I'm having with GitHub (as far as I can tell) is either (1) creating a fork or (2) submitting a pull request of the fork I've created (I'm not sure). Creating the first fork of /rust-lang/rfcs was easy: I just clicked the "Fork" button on the website. But now that I'm trying to fork /rust-lang/rfcs for the second time, clicking that same "Fork" button just takes to my previous fork. I managed to maybe create another fork using this guide: http://adrianshort.org/2011/11/08/create-multiple-forks-of-a-github-repo/ but I can't create a pull request of the changes I've made to that fork (assuming the thing that I created is in fact a fork). Here's this second fork that I made (maybe): https://github.com/TommiT/private-trait-items Yes, I've read the guide [1] For completeness sake, here's the first fork (which I did manage to create and make the pull request in it, although the intermediate step of moving a file became part of the pull request when it shouldn't have): https://github.com/TommiT/rfcs On 2014-04-22, at 16:52, Flaper87 wrote: > > 2014-04-22 15:45 GMT+02:00 Tommi : > No one? > > I understand that a part of the reason the RFC process is made so complex is that it filters out idiots like me. But I think this one is a pretty important design choice that Rust is about to get wrong. > > > If the RFC process is complex, then I believe there's something we should probably make easier. The idea is not to filter folks out but to welcome them and make the collaboration process easier for everyone > > What parts of this process are complex? [0] > What problems are you having with GitHub? > Have you looked into this guide? [1] > > [0] https://github.com/rust-lang/rfcs/blob/master/active/0001-rfc-process.md > [1] https://help.github.com/articles/using-pull-requests > > Flavio > > > -- > Flavio (@flaper87) Percoco > http://www.flaper87.com > http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rusty.gates at icloud.com Tue Apr 22 14:57:36 2014 From: rusty.gates at icloud.com (Tommi) Date: Wed, 23 Apr 2014 00:57:36 +0300 Subject: [rust-dev] Private trait items In-Reply-To: <5356B893.2010107@mozilla.com> References: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> <5356B893.2010107@mozilla.com> Message-ID: <5AEB7055-3518-4189-B0B1-D97ED7C4F83C@icloud.com> On 2014-04-22, at 21:44, Brian Anderson wrote: > I'm not sure what you are asking for here. Have you submitted this as a pull request to http://github.com/rust-lang/rfcs? No, I haven't made the pull request, because I don't know how to do that (or perhaps I would know how to do that, if I knew how to create a fork for the second time of the same thing). I'm not even sure of what exactly it is that I'm not capable of doing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Tue Apr 22 17:22:04 2014 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Wed, 23 Apr 2014 02:22:04 +0200 Subject: [rust-dev] Private trait items In-Reply-To: <5AEB7055-3518-4189-B0B1-D97ED7C4F83C@icloud.com> References: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> <5356B893.2010107@mozilla.com> <5AEB7055-3518-4189-B0B1-D97ED7C4F83C@icloud.com> Message-ID: <5946DEC2-0624-4D73-A3C5-09C052BB3B24@mozilla.com> Tommi (cc'ing rust-dev)- I recommend you make a small fake github repository of your own, and learn the github workflow directly by forking that (perhaps with a separate fresh dummy github user account). I am not being facetious; I did a lot of that when I was first getting my bearings using github (as well as git itself). Of course, learning methodologies that worked for me may not work for everyone else, but that's my two cents. Cheers, -Felix On 22 Apr 2014, at 23:57, Tommi wrote: > On 2014-04-22, at 21:44, Brian Anderson wrote: > >> I'm not sure what you are asking for here. Have you submitted this as a pull request to http://github.com/rust-lang/rfcs? > > No, I haven't made the pull request, because I don't know how to do that (or perhaps I would know how to do that, if I knew how to create a fork for the second time of the same thing). I'm not even sure of what exactly it is that I'm not capable of doing. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Tue Apr 22 17:35:38 2014 From: thadguidry at gmail.com (Thad Guidry) Date: Tue, 22 Apr 2014 19:35:38 -0500 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: <5356B9EA.905@mozilla.com> References: <5356B9EA.905@mozilla.com> Message-ID: I would have named it ... "oxide" instead of zinc ;-) ... rust = iron oxide On Tue, Apr 22, 2014 at 1:50 PM, Brian Anderson wrote: > This sounds very useful. Thanks for letting us know. > > > On 04/22/2014 09:10 AM, Vladimir Pouzanov wrote: > >> This is the project I've been tinkering with for a good number of >> weekends ? zinc, the bare metal stack for rust is available at >> https://github.com/hackndev/zinc. >> >> I've just finished a major refactoring work for LPC1768 code, so STM32F4 >> is kind of broken yet, and LPC1114 is totally dropped, but I'll fix that >> soon. >> >> The current code supports GPIO operations, UART and SSP in SPI mode for >> NXP LPC1768, also featuring a driver for >> http://mbed.org/cookbook/mbed-application-board TFT LCD and for >> ILI9341-based TFT LCDs commonly found on ebay. >> >> My plan is to fix support for STM32F4, bring it to the level of NXP part >> and try to expand this to a small RTOS, which would be a nice demo of >> rust capabilities for embedded development. >> >> The code is licensed under Apache-2.0. >> >> There's no readme yet, but you can see the demo applications written >> with zinc here: https://github.com/hackndev/zinc/tree/master/apps. >> >> -- >> Sincerely, >> Vladimir "Farcaller" Pouzanov >> http://farcaller.net/ >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad +ThadGuidry Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From com.liigo at gmail.com Tue Apr 22 17:56:27 2014 From: com.liigo at gmail.com (Liigo Zhuang) Date: Wed, 23 Apr 2014 08:56:27 +0800 Subject: [rust-dev] Private trait items In-Reply-To: <5AEB7055-3518-4189-B0B1-D97ED7C4F83C@icloud.com> References: <948EDBC2-0C08-4E96-B034-C2B00E93692B@icloud.com> <5356B893.2010107@mozilla.com> <5AEB7055-3518-4189-B0B1-D97ED7C4F83C@icloud.com> Message-ID: It's easy to submit a pull request, for a git programmer. My difficulty is the weak of English level to write a so long rfc. 2014?4?23? ??5:57? "Tommi" ??? > On 2014-04-22, at 21:44, Brian Anderson wrote: > > I'm not sure what you are asking for here. Have you submitted this as a > pull request to http://github.com/rust-lang/rfcs? > > > No, I haven't made the pull request, because I don't know how to do that > (or perhaps I would know how to do that, if I knew how to create a fork for > the second time of the same thing). I'm not even sure of what exactly it is > that I'm not capable of doing. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at chrismorgan.info Tue Apr 22 19:05:39 2014 From: me at chrismorgan.info (Chris Morgan) Date: Wed, 23 Apr 2014 12:05:39 +1000 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: <5356B9EA.905@mozilla.com> Message-ID: On Wed, Apr 23, 2014 at 10:35 AM, Thad Guidry wrote: > I would have named it ... "oxide" instead of zinc ;-) ... rust = iron oxide Do you know how many projects written in Rust have already been named ?oxide?? From thadguidry at gmail.com Tue Apr 22 19:58:03 2014 From: thadguidry at gmail.com (Thad Guidry) Date: Tue, 22 Apr 2014 21:58:03 -0500 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: <5356B9EA.905@mozilla.com> Message-ID: Actually...I do not. :) On Tue, Apr 22, 2014 at 9:05 PM, Chris Morgan wrote: > On Wed, Apr 23, 2014 at 10:35 AM, Thad Guidry > wrote: > > I would have named it ... "oxide" instead of zinc ;-) ... rust = iron > oxide > Do you know how many projects written in Rust have already been named > ?oxide?? > -- -Thad +ThadGuidry Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From jurily at gmail.com Tue Apr 22 21:42:39 2014 From: jurily at gmail.com (=?UTF-8?Q?Gy=C3=B6rgy_Andrasek?=) Date: Wed, 23 Apr 2014 06:42:39 +0200 Subject: [rust-dev] Call for a "practical" Rust guide In-Reply-To: References: <5355A595.1060104@mozilla.com> Message-ID: There is a rather old repo at https://github.com/Jurily/rust-c-example I'll make it a full tutorial when I find the time. On Tue, Apr 22, 2014 at 3:17 AM, Doug wrote: > Just my $0.02; totally agree; a proper guide to linking (specifically the > 'right' way to link when you have a crate with external C library > dependencies), and interacting directly with ffi (str <--> char * for > example) would be extremely useful. > > I've been going through the process of doing that stuff the last week or two > and there isn't really any good guidance on the topic other than 'don't look > at the standard library as an example of how to do it'. > > ~ > Doug. From farcaller at gmail.com Wed Apr 23 00:21:14 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Wed, 23 Apr 2014 08:21:14 +0100 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: <5356B9EA.905@mozilla.com> Message-ID: Luckily enough, I had the concept for zinc even before I started coding in rust :-) And yes, there are lots of different oxides in rust world. On Wed, Apr 23, 2014 at 3:58 AM, Thad Guidry wrote: > Actually...I do not. :) > > > On Tue, Apr 22, 2014 at 9:05 PM, Chris Morgan wrote: > >> On Wed, Apr 23, 2014 at 10:35 AM, Thad Guidry >> wrote: >> > I would have named it ... "oxide" instead of zinc ;-) ... rust = iron >> oxide >> Do you know how many projects written in Rust have already been named >> ?oxide?? >> > > > > -- > -Thad > +ThadGuidry > Thad on LinkedIn > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From bgamari at gmail.com Wed Apr 23 07:47:33 2014 From: bgamari at gmail.com (Ben Gamari) Date: Wed, 23 Apr 2014 10:47:33 -0400 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: Message-ID: <87ioq0p0fu.fsf@gmail.com> Vladimir Pouzanov writes: > This is the project I've been tinkering with for a good number of > weekends zinc, the bare metal stack for rust is available at > https://github.com/hackndev/zinc. > > I've just finished a major refactoring work for LPC1768 code, so > STM32F4 is kind of broken yet, and LPC1114 is totally dropped, but > I'll fix that soon. > > The current code supports GPIO operations, UART and SSP in SPI mode > for NXP LPC1768, also featuring a driver for > http://mbed.org/cookbook/mbed-application-board TFT LCD and for > ILI9341-based TFT LCDs commonly found on ebay. > > My plan is to fix support for STM32F4, bring it to the level of NXP > part and try to expand this to a small RTOS, which would be a nice > demo of rust capabilities for embedded development. > > The code is licensed under Apache-2.0. > > There's no readme yet, but you can see the demo applications written > with zinc here: https://github.com/hackndev/zinc/tree/master/apps. > Thanks for the release! I've been looking forward to seeing this ever since your Reddit post a few weeks back as I too have been recently thinking about how Rust might be used in an embedded environment. Lately I've been contributing to the mchck[1] project, its associated library, and a project I've built on top of it[2]. One of the things that I feel the mchck library gets right is the ubiquitous use of asynchronous completion notification (e.g. [3]) instead of polling. In my experience asynchronous code both maps onto hardware more naturally and produces more composable user code. Unfortunately, C makes continuation passing very painful due to the broken up flow of control that results from the sea of callbacks and the boilerplate (e.g. passing and casting of `void*` pointers to structs of intermediate state) necessary for propagation of state between callbacks. As far as I can tell, there are two paths by which Rust might improve this situation. The most straightforward approach would be to implement continuation passing directly by passing around continuation `procs`. While this approach reduces the amount of boilerplate due to state propagation, it does not really resolve the broken flow of control due to explicit continuations. Another approach which addresses this latter issue is to use Rust's native tasks, allowing requests to peripherals to be treated as blocking. While this seems like this could be very convenient, I am a bit concerned that the memory footprint of multiple stacks and associated bookkeeping data structures might be asking too much of the typical MCU (the devices I work with typically have 16kByte of SRAM). This memory footprint issue is especially concerning due to Rust's[4] heavy dependence on stack allocation. I am very much accustomed to avoiding dynamic allocation at all costs on embedded platforms; I appreciate knowing at compile time whether my program will fit on my device (up to stack allocations, which in my C code are intentionally minimal). With the uncertainty of dynamic allocation against the stack and dynamic task creation, it seems one literally has no idea whether a program will fit without either static analysis, simulation, or trial on real hardware. However, it seems that one loses a great deal by reverting to static allocation in Rust (e.g. losing safety of ownership, memory model becomes burdensome), so perhaps dynamic allocation coupled with robust allocation analysis tools is a reasonable trade-off. I'd be very interested to hear what others have to say about these issues. Cheers, - Ben [1] http://github.com/mchck/mchck [3] http://github.com/bgamari/data-logger [3] https://github.com/mchck/mchck/blob/master/toolchain/lib/mchck/spi.h [4] or rather, ideomatic Rust code's -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 472 bytes Desc: not available URL: From farcaller at gmail.com Wed Apr 23 08:36:38 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Wed, 23 Apr 2014 16:36:38 +0100 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: <87ioq0p0fu.fsf@gmail.com> References: <87ioq0p0fu.fsf@gmail.com> Message-ID: There is a number of options on the memory side of things. I feel that stack usage could be estimated a bit more simply with rust and it's __morestack support, so that it would be possible to run a few threads with preemptive scheduling (__morestack also guarantees that no memory corruption would occur due to stack overflow). I'm totally against "unmanaged" heap support and ~T on embedded, that just doesn't work. It's a very big burden to support that reasonably in existing C/C++ RTOSes out there, so I don't want to spend lots of time trying to solve the same problems. Still, heap is really useful in some cases (as I've figured out while working on 802.15.4 stack for zinc). My current idea is to make dedicated pools that could hold a compile-time configurable number of objects of same size, e.g. an IncomingPacketPool that can hold up to 3 frames where one frame is 128 bytes long. This way no other running process can interfere with code that processes incoming packets and that code can offload incoming packets into the pool for later processing, but up to three, and it will act in user-defined fashion (drop packets) if the pool is full. The implementation of that would be quite simple, and I think that it might be possible to extend ~T ownership for something like that. On Wed, Apr 23, 2014 at 3:47 PM, Ben Gamari wrote: > Vladimir Pouzanov writes: > > > This is the project I've been tinkering with for a good number of > > weekends zinc, the bare metal stack for rust is available at > > https://github.com/hackndev/zinc. > > > > I've just finished a major refactoring work for LPC1768 code, so > > STM32F4 is kind of broken yet, and LPC1114 is totally dropped, but > > I'll fix that soon. > > > > The current code supports GPIO operations, UART and SSP in SPI mode > > for NXP LPC1768, also featuring a driver for > > http://mbed.org/cookbook/mbed-application-board TFT LCD and for > > ILI9341-based TFT LCDs commonly found on ebay. > > > > My plan is to fix support for STM32F4, bring it to the level of NXP > > part and try to expand this to a small RTOS, which would be a nice > > demo of rust capabilities for embedded development. > > > > The code is licensed under Apache-2.0. > > > > There's no readme yet, but you can see the demo applications written > > with zinc here: https://github.com/hackndev/zinc/tree/master/apps. > > > Thanks for the release! I've been looking forward to seeing this ever > since your Reddit post a few weeks back as I too have been recently > thinking about how Rust might be used in an embedded environment. > > Lately I've been contributing to the mchck[1] project, its associated > library, and a project I've built on top of it[2]. One of the things > that I feel the mchck library gets right is the ubiquitous use of > asynchronous completion notification (e.g. [3]) instead of polling. In > my experience asynchronous code both maps onto hardware more naturally > and produces more composable user code. Unfortunately, C makes > continuation passing very painful due to the broken up flow of control > that results from the sea of callbacks and the boilerplate (e.g. passing > and casting of `void*` pointers to structs of intermediate state) > necessary for propagation of state between callbacks. > > As far as I can tell, there are two paths by which Rust might improve > this situation. The most straightforward approach would be to implement > continuation passing directly by passing around continuation > `procs`. While this approach reduces the amount of boilerplate due to > state propagation, it does not really resolve the broken flow of control > due to explicit continuations. > > Another approach which addresses this latter issue is to use Rust's > native tasks, allowing requests to peripherals to be treated as > blocking. While this seems like this could be very convenient, I am a bit > concerned that the memory footprint of multiple stacks and associated > bookkeeping data structures might be asking too much of the typical > MCU (the devices I work with typically have 16kByte of SRAM). > > This memory footprint issue is especially concerning due to Rust's[4] > heavy dependence on stack allocation. I am very much accustomed to > avoiding dynamic allocation at all costs on embedded platforms; I > appreciate knowing at compile time whether my program will fit on my > device (up to stack allocations, which in my C code are intentionally > minimal). With the uncertainty of dynamic allocation against the stack > and dynamic task creation, it seems one literally has no idea whether a > program will fit without either static analysis, simulation, or trial on > real hardware. However, it seems that one loses a great deal by > reverting to static allocation in Rust (e.g. losing safety of ownership, > memory model becomes burdensome), so perhaps dynamic allocation coupled > with robust allocation analysis tools is a reasonable trade-off. > > I'd be very interested to hear what others have to say about these > issues. > > Cheers, > > - Ben > > > [1] http://github.com/mchck/mchck > [3] http://github.com/bgamari/data-logger > [3] https://github.com/mchck/mchck/blob/master/toolchain/lib/mchck/spi.h > [4] or rather, ideomatic Rust code's > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From ncm at cantrip.org Wed Apr 23 13:42:52 2014 From: ncm at cantrip.org (Nathan Myers) Date: Wed, 23 Apr 2014 13:42:52 -0700 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: <1458ec0a4e8.276e.335f4863ad3e7c521d63e242ab2886e0@cantrip.org> References: <5356B9EA.905@mozilla.com> Message-ID: <14590537600.276e.335f4863ad3e7c521d63e242ab2886e0@cantrip.org> Ruby is aluminum oxide. C is elemental carbon; C++, doubly ionized. Perl is mostly calcium carbonate. But there are better wordplay opportunities here than obscure chemistry references. On April 23, 2014 12:28:48 AM Vladimir Pouzanov wrote: > Luckily enough, I had the concept for zinc even before I started coding in > rust :-) And yes, there are lots of different oxides in rust world. > > > On Wed, Apr 23, 2014 at 3:58 AM, Thad Guidry wrote: > > > Actually...I do not. :) > > > > > > On Tue, Apr 22, 2014 at 9:05 PM, Chris Morgan wrote: > > > >> On Wed, Apr 23, 2014 at 10:35 AM, Thad Guidry > >> wrote: > >> > I would have named it ... "oxide" instead of zinc ;-) ... rust = iron > >> oxide > >> Do you know how many projects written in Rust have already been named > >> ?oxide?? > >> > > > > > > > > -- > > -Thad > > +ThadGuidry > > Thad on LinkedIn > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > > > > > -- Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ From pcwalton at mozilla.com Wed Apr 23 15:56:17 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Wed, 23 Apr 2014 15:56:17 -0700 Subject: [rust-dev] Optimizing pattern bindings to not copy anything at runtime Message-ID: <53584511.6000400@mozilla.com> Hi everyone, I believe that by-move pattern bindings don't actually have to perform any copying of bits for non-word-sized values. This applies to both `let` and `match`. It surprised me too, which is why I thought I'd send it to the mailing list first. A by-move pattern binding is any binding not denoted by `ref`: let x = Some(HashMap::new()); // ^ match x { None => ..., Some(map) => ... // ^^^ } You might think that, for each by-move pattern binding, we have to generate a slot on the stack with the size of the binding and copy in all the bytes that correspond to that stack slot. Indeed, this is what we generate today. So, for the above code, we would have two stack slots, each 88 bytes long. The match expression would generate a shallow memory copy from the stack to the stack. Since there are 88 bytes, that's a lot of bytes to copy. In fact, this function is 500-1000 bytes of x86-64 assembly code, even when optimized. I believe that we can eliminate this by converting non-word-sized (non-"immediate" in the compiler jargon) pattern bindings to references instead. Justification: 1. Every by-move pattern binding is moving out of something that can legally be moved out of in Rust. 2. The only things that can be moved out of in Rust are locals and rvalues. 3. Locals have stack slots already assigned to them. Since those stack slots are hoisted allocas, they will stick around for the lifetime of the pattern binding, since pattern bindings are locals. So it makes no sense to allocate a new slot for this. 4. Rvalues already have scratch space allocated for them (unless they are "destination-passing-style" rvalues--more on that later), so a similar argument applies. 5. We already treat non-word-sized values as pointers in codegen; we don't use LLVM first class aggregates. So all of the code that deals with aggregates in trans does not have to change. Combined with the zeroing out optimization, this should remove a lot of useless moves. The remaining, more difficult, issue is initialization of aggregate data structures via constructor functions, which still involves a bunch of moves, but I don't really see any way short of macros to optimize that at the moment. Thoughts? :) Patrick From niko at alum.mit.edu Wed Apr 23 19:09:10 2014 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 23 Apr 2014 22:09:10 -0400 Subject: [rust-dev] Optimizing pattern bindings to not copy anything at runtime In-Reply-To: <53584511.6000400@mozilla.com> References: <53584511.6000400@mozilla.com> Message-ID: <20140424020910.GE22072@Mr-Bennet> Ah, neat. I have been wanting to do this optimization for function parameters for a long time, but I hadn't thought about it for other kinds of bindings. Better yet, I think by-copy vs by-move is a red herring. The optimization applies equally well in both scenarios. That said, we do have to be a bit careful about mutability. Even just considering by-move locals, for example, it is possible to have code like the following: let mut x = something(); let y = x; x = something_else(); If we just made y a pointer to x, we'd be in trouble. Also, this statement isn't quite right: > 2. The only things that can be moved out of in Rust are locals and rvalues. You could e.g. move out of x.y.z. Moreover, I think we can support a lot more. As part of #5016 I plan to allow you to continue the parts of a struct that have not been moved out of. Better yet, if you replace the moved out fields, you can go back to using the struct again: let foo = ...; let a = foo.a; // moves out of foo.a let b = foo.b; // moves out of foo.b foo.a = ...; foo.b = ...; use(foo); This all basically falls out of the analysis we're currently doing, which tracks the precise deinitialized paths (e.g., foo.a, foo.b, etc). We're just being overly restrictive for legacy reasons. I'm working on a patch right now that should make it easy to change that. At some point, I think we could even enable moves out of &mut, as long as you replace the value before failure could occur. This would allow tree-maps and the like to do rotations just as you do in C. But I haven't tried to write formal rules for this yet. Niko From niko at alum.mit.edu Wed Apr 23 19:13:24 2014 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 23 Apr 2014 22:13:24 -0400 Subject: [rust-dev] Removing ~"foo" In-Reply-To: References: <534D6897.6080202@mozilla.com> Message-ID: <20140424021324.GF22072@Mr-Bennet> On Wed, Apr 16, 2014 at 12:21:20AM -0400, comex wrote: > If I have x: &[char, ..5], I can use ~*x to get an owned version > without a lot of typing. Would it be too insane to have that work for > &[char] or &str with DST? Something like this will work, yes. It'll probably look more like: Box::new(*x) This will be described in some of the RFCs that are coming up soon. Niko From ben.striegel at gmail.com Wed Apr 23 21:42:00 2014 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 24 Apr 2014 00:42:00 -0400 Subject: [rust-dev] Optimizing pattern bindings to not copy anything at runtime In-Reply-To: <20140424020910.GE22072@Mr-Bennet> References: <53584511.6000400@mozilla.com> <20140424020910.GE22072@Mr-Bennet> Message-ID: > We're just being overly restrictive for legacy reasons. This same sentiment appears in https://github.com/rust-lang/rfcs/pull/48 . How many more rules are we imposing that exist only for "legacy reasons"? Is addressing them all a priority for 1.0? On Wed, Apr 23, 2014 at 10:09 PM, Niko Matsakis wrote: > Ah, neat. I have been wanting to do this optimization for function > parameters for a long time, but I hadn't thought about it for other > kinds of bindings. Better yet, I think by-copy vs by-move is a red > herring. The optimization applies equally well in both scenarios. > > That said, we do have to be a bit careful about mutability. Even just > considering by-move locals, for example, it is possible to have code > like the following: > > let mut x = something(); > let y = x; > x = something_else(); > > If we just made y a pointer to x, we'd be in trouble. > > Also, this statement isn't quite right: > > > 2. The only things that can be moved out of in Rust are locals and > rvalues. > > You could e.g. move out of x.y.z. Moreover, I think we can support a > lot more. As part of #5016 I plan to allow you to continue the parts > of a struct that have not been moved out of. Better yet, if you > replace the moved out fields, you can go back to using the struct > again: > > let foo = ...; > let a = foo.a; // moves out of foo.a > let b = foo.b; // moves out of foo.b > foo.a = ...; > foo.b = ...; > use(foo); > > This all basically falls out of the analysis we're currently doing, > which tracks the precise deinitialized paths (e.g., foo.a, foo.b, > etc). We're just being overly restrictive for legacy reasons. I'm > working on a patch right now that should make it easy to change that. > > At some point, I think we could even enable moves out of &mut, as long > as you replace the value before failure could occur. This would allow > tree-maps and the like to do rotations just as you do in C. But I > haven't tried to write formal rules for this yet. > > > Niko > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcwalton at mozilla.com Wed Apr 23 23:22:07 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Wed, 23 Apr 2014 23:22:07 -0700 Subject: [rust-dev] Optimizing pattern bindings to not copy anything at runtime In-Reply-To: <20140424020910.GE22072@Mr-Bennet> References: <53584511.6000400@mozilla.com> <20140424020910.GE22072@Mr-Bennet> Message-ID: <5358AD8F.1070300@mozilla.com> On 4/23/14 7:09 PM, Niko Matsakis wrote: > If we just made y a pointer to x, we'd be in trouble. Well, not if the mutation to x is also done by making it a pointer to the scratch space occupied by `something_else()`. Patrick From bgamari at gmail.com Thu Apr 24 01:01:35 2014 From: bgamari at gmail.com (Ben Gamari) Date: Thu, 24 Apr 2014 04:01:35 -0400 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: <87ioq0p0fu.fsf@gmail.com> Message-ID: <87d2g7p34w.fsf@gmail.com> Vladimir Pouzanov writes: > There is a number of options on the memory side of things. I feel that > stack usage could be estimated a bit more simply with rust and it's > __morestack support, so that it would be possible to run a few threads with > preemptive scheduling (__morestack also guarantees that no memory > corruption would occur due to stack overflow). > Unfortunately this replaces the ugly possibility of unpredictable crashes with the slightly less ugly possiblity of unpredictable deadlocks if we run out of stack in the middle of execution. Perhaps threads could be annotated with their maximum expected stack size, allowing stack chunks to be allocated at spawn-time. > I'm totally against "unmanaged" heap support and ~T on embedded, that just > doesn't work. It's a very big burden to support that reasonably in existing > C/C++ RTOSes out there, so I don't want to spend lots of time trying to > solve the same problems. Still, heap is really useful in some cases (as > I've figured out while working on 802.15.4 stack for zinc). > Sure, I can't disagree with that. > My current idea is to make dedicated pools that could hold a compile-time > configurable number of objects of same size, e.g. an IncomingPacketPool > that can hold up to 3 frames where one frame is 128 bytes long. This way no > other running process can interfere with code that processes incoming > packets and that code can offload incoming packets into the pool for later > processing, but up to three, and it will act in user-defined fashion (drop > packets) if the pool is full. The implementation of that would be quite > simple, and I think that it might be possible to extend ~T ownership for > something like that. > I tried playing around[1] (warning: code written by new Rust-er, expect eye damage, feedback welcome) with a simple buffer pool implementation this morning; unfortunately I found that Rust's restrictions on function application in constant expressions makes static allocation quite difficult (impossible?), src/lib/pool.rs:47:73: 47:87 error: function calls in constants are limited to struct and enum constructors src/lib/pool.rs:47 static pool : Pool<'static, int> = Pool{ entries: [PoolEntry{ref_count: Unsafe::new(0), value: Unsafe::new(0)}, ..5] }; This despite the fact that the `Unsafe::new` function is underneath just a constructor application. Perhaps Rust would be well served by a attribute like C++11's `constexpr`? Perhaps the macro system provides a workable, if somewhat ugly, solution? The inability to hide pure constructor applications behind function calls severely limits the sorts of abstractions one can safely construct. It seems like this is a worthwhile restriction to lift, even outside of the embedded context. Cheers, - Ben [1] https://gist.github.com/bgamari/033379d82f179eac8688 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 472 bytes Desc: not available URL: From farcaller at gmail.com Thu Apr 24 01:47:09 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Thu, 24 Apr 2014 09:47:09 +0100 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: <87d2g7p34w.fsf@gmail.com> References: <87ioq0p0fu.fsf@gmail.com> <87d2g7p34w.fsf@gmail.com> Message-ID: On Thu, Apr 24, 2014 at 9:01 AM, Ben Gamari wrote: > Unfortunately this replaces the ugly possibility of unpredictable > crashes with the slightly less ugly possiblity of unpredictable > deadlocks if we run out of stack in the middle of execution. Perhaps > threads could be annotated with their maximum expected stack size, > allowing stack chunks to be allocated at spawn-time. > It wouldn't be allowed to grow, it's exactly that ? maximum expected stack size, task either fits in there or dies. -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From mario.sopena at gmail.com Thu Apr 24 02:19:22 2014 From: mario.sopena at gmail.com (Mario Sopena Novales) Date: Thu, 24 Apr 2014 11:19:22 +0200 Subject: [rust-dev] Self and self in trait definitions Message-ID: Hi everyone, I've been learning Rust for the last couple of weeks and I'm quite excited with it. My experience is mainly in C and Rust feels like a nice improvement. Thank you for the hard work! I've recently found this bit of the tutorial: http://static.rust-lang.org/doc/master/tutorial.html#type-parameterized-traits and it got me confused for a while because of the similarity between self and Self (just the 'S' in caps) even when they refer to completely different things. I would suggest to change the Self identifier to something less similar to self which also hints as to what it is like selfT, Tself, self_type or type(self). Maybe someone with more Rust experience can come up with better suggestions. I just think that self/Self is quite confusing and harder to parse for the eye. I'm happy to write a RFC if you think the idea has some merit. Mario -------------- next part -------------- An HTML attachment was scrubbed... URL: From bgamari at gmail.com Thu Apr 24 04:01:50 2014 From: bgamari at gmail.com (Ben Gamari) Date: Thu, 24 Apr 2014 07:01:50 -0400 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: <87ioq0p0fu.fsf@gmail.com> <87d2g7p34w.fsf@gmail.com> Message-ID: <8761lzoush.fsf@gmail.com> Vladimir Pouzanov writes: > On Thu, Apr 24, 2014 at 9:01 AM, Ben Gamari wrote: > >> Unfortunately this replaces the ugly possibility of unpredictable >> crashes with the slightly less ugly possiblity of unpredictable >> deadlocks if we run out of stack in the middle of execution. Perhaps >> threads could be annotated with their maximum expected stack size, >> allowing stack chunks to be allocated at spawn-time. >> > > It wouldn't be allowed to grow, it's exactly that ? maximum expected stack > size, task either fits in there or dies. > Ahh, I see now. For the record, my original interpretation of your suggestion was to maintain a pool of stack chunks, each new thread taking one chunk at spawn time. If a thread were to run out of stack, it would be allocated another chunk from the pool. If there were none left in the pool, it would be suspended until another thread frees up a chunk (which would happen on thread death and perhaps via a reclaim mechanism). While this scheme is arguably a bit more flexible it's not at all clear that this amount of fragile complexity is desirable here. I prefer the "you don't fit, you die" approach. You just need to ensure that the stack size is reasonable and that you have enough stacks for the maximum number of concurrent threads. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 472 bytes Desc: not available URL: From hsivonen at hsivonen.fi Thu Apr 24 04:16:54 2014 From: hsivonen at hsivonen.fi (Henri Sivonen) Date: Thu, 24 Apr 2014 14:16:54 +0300 Subject: [rust-dev] Rust .so that looks like a C .so Message-ID: The documentation for the FFI seems focused on using C code in a program whose main() is in Rust. Can Rust be used for implementing a shared library that implements a C ABI for use by programs whose main() is not in Rust (i.e. the caller sees a C ABI and doesn't know about Rust)? If yes, can a C program use multiple such libraries so that their Rust runtime bits don't conflict? Is there a tool for generating .h files for C-callable Rust functions and their argument data types? -- Henri Sivonen hsivonen at hsivonen.fi https://hsivonen.fi/ From stephane at wirtel.be Thu Apr 24 04:20:04 2014 From: stephane at wirtel.be (=?utf-8?q?St=C3=A9phane?= Wirtel) Date: Thu, 24 Apr 2014 13:20:04 +0200 Subject: [rust-dev] Rust .so that looks like a C .so In-Reply-To: References: Message-ID: On 24 Apr 2014, at 13:16, Henri Sivonen wrote: > The documentation for the FFI seems focused on using C code in a > program whose main() is in Rust. Can Rust be used for implementing a > shared library that implements a C ABI for use by programs whose > main() is not in Rust (i.e. the caller sees a C ABI and doesn't know > about Rust)? If yes, can a C program use multiple such libraries so > that their Rust runtime bits don't conflict? Is there a tool for > generating .h files for C-callable Rust functions and their argument > data types? Yes, normally you can create a shared lib with Rust and extern the code with the C convention ( sorry, I don't remember the right name). and via this convention, you can use your Rust lib in Python/Ruby or an other languages. Regards, Stephane -- St?phane Wirtel - http://wirtel.be - @matrixise From flaper87 at gmail.com Thu Apr 24 04:31:22 2014 From: flaper87 at gmail.com (Flaper87) Date: Thu, 24 Apr 2014 13:31:22 +0200 Subject: [rust-dev] Rust .so that looks like a C .so In-Reply-To: References: Message-ID: 2014-04-24 13:20 GMT+02:00 St?phane Wirtel : > On 24 Apr 2014, at 13:16, Henri Sivonen wrote: > > The documentation for the FFI seems focused on using C code in a >> program whose main() is in Rust. Can Rust be used for implementing a >> shared library that implements a C ABI for use by programs whose >> main() is not in Rust (i.e. the caller sees a C ABI and doesn't know >> about Rust)? If yes, can a C program use multiple such libraries so >> that their Rust runtime bits don't conflict? Is there a tool for >> generating .h files for C-callable Rust functions and their argument >> data types? >> > > Yes, normally you can create a shared lib with Rust and extern the code > with the C convention ( sorry, I don't remember the right name). > and via this convention, you can use your Rust lib in Python/Ruby or an > other languages. > > Here's a very tiny and simple example: https://github.com/FlaPer87/rust-asterisk-example Hope it helps, -- Flavio (@flaper87) Percoco http://www.flaper87.com http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jurily at gmail.com Thu Apr 24 05:46:27 2014 From: jurily at gmail.com (=?UTF-8?Q?Gy=C3=B6rgy_Andrasek?=) Date: Thu, 24 Apr 2014 14:46:27 +0200 Subject: [rust-dev] Rust .so that looks like a C .so In-Reply-To: References: Message-ID: https://github.com/Jurily/rust-c-example `#[no_mangle] extern "C" foo() { ... }` When you expose a C API, you need to observe the C rules: function names must be globally unique. You have to write the headers yourself. Taking and releasing ownership of C data needs some magic, but it's doable. Take special care to use the `c_` types correctly, this is not the area where Rust's error messages are strongest, and it's way too easy to confuse `int` and `c_int` for example. (Rust `int` is `ptrdiff_t`) From mahmutbulut0 at gmail.com Thu Apr 24 06:08:29 2014 From: mahmutbulut0 at gmail.com (Mahmut Bulut) Date: Thu, 24 Apr 2014 16:08:29 +0300 Subject: [rust-dev] Rust .so that looks like a C .so In-Reply-To: References: Message-ID: I think that on windows because of name manglings in __cdecl it is not possible? Or it is? ---- Mahmut Bulut > On 24 Apr 2014, at 14:16, Henri Sivonen wrote: > > The documentation for the FFI seems focused on using C code in a > program whose main() is in Rust. Can Rust be used for implementing a > shared library that implements a C ABI for use by programs whose > main() is not in Rust (i.e. the caller sees a C ABI and doesn't know > about Rust)? If yes, can a C program use multiple such libraries so > that their Rust runtime bits don't conflict? Is there a tool for > generating .h files for C-callable Rust functions and their argument > data types? > > -- > Henri Sivonen > hsivonen at hsivonen.fi > https://hsivonen.fi/ > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From jurily at gmail.com Thu Apr 24 07:07:29 2014 From: jurily at gmail.com (=?UTF-8?Q?Gy=C3=B6rgy_Andrasek?=) Date: Thu, 24 Apr 2014 16:07:29 +0200 Subject: [rust-dev] Rust .so that looks like a C .so In-Reply-To: References: Message-ID: http://static.rust-lang.org/doc/master/guide-ffi.html#foreign-calling-conventions I forgot about `extern "system"`, sorry :) From bill_myers at outlook.com Thu Apr 24 08:16:13 2014 From: bill_myers at outlook.com (Bill Myers) Date: Thu, 24 Apr 2014 15:16:13 +0000 Subject: [rust-dev] Optimizing pattern bindings to not copy anything at runtime In-Reply-To: <53584511.6000400@mozilla.com> References: <53584511.6000400@mozilla.com> Message-ID: Nice, but why isn't the LLVM optimizer removing the move? Is it lack of proper alias analysis? Sounds like that is a separate issue worth pursuing. > The remaining, more difficult, issue is initialization of > aggregate data structures via constructor functions, which still > involves a bunch of moves, but I don't really see any way short of > macros to optimize that at the moment. Wouldn't #[inline(always)] on the aggregate constructor fix that? (it's not great, but it's strictly better than a macro) At any rate, shouldn't LLVM inlining heuristics catch that automatically as well? If not, that sounds like another separate issue. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcwalton at mozilla.com Thu Apr 24 08:41:06 2014 From: pcwalton at mozilla.com (Patrick Walton) Date: Thu, 24 Apr 2014 08:41:06 -0700 Subject: [rust-dev] Optimizing pattern bindings to not copy anything at runtime In-Reply-To: References: <53584511.6000400@mozilla.com> Message-ID: <53593092.9070403@mozilla.com> On 4/24/14 8:16 AM, Bill Myers wrote: > Nice, but why isn't the LLVM optimizer removing the move? > Is it lack of proper alias analysis? > Sounds like that is a separate issue worth pursuing. LLVM's MemCpyOptimizer is pretty badly ordered in the pipeline and needs to be rewritten. In any case, I think it's worth doing even if LLVM fixes the problem, because it improves compilation time by reducing the amount of work LLVM has to do. Patrick From bill_myers at outlook.com Thu Apr 24 08:52:09 2014 From: bill_myers at outlook.com (Bill Myers) Date: Thu, 24 Apr 2014 15:52:09 +0000 Subject: [rust-dev] Removing ~"foo" In-Reply-To: <20140424021324.GF22072@Mr-Bennet> References: <534D6897.6080202@mozilla.com>, , <20140424021324.GF22072@Mr-Bennet> Message-ID: > Something like this will work, yes. It'll probably look more like: > > Box::new(*x) > > This will be described in some of the RFCs that are coming up soon. Awesome! We should really get rid of the ~T syntax in favor of Foo (where Foo = Box, Own, Heap, etc.), since it is deceptively simple for something that should in fact be rarely used. From cg.wowus.cg at gmail.com Thu Apr 24 08:53:23 2014 From: cg.wowus.cg at gmail.com (Clark Gaebel) Date: Thu, 24 Apr 2014 11:53:23 -0400 Subject: [rust-dev] Removing ~"foo" In-Reply-To: References: <534D6897.6080202@mozilla.com> <20140424021324.GF22072@Mr-Bennet> Message-ID: Bonus: Box, Own, Heap would play nicer with allocators (in terms of syntax) than ~T. On Thu, Apr 24, 2014 at 11:52 AM, Bill Myers wrote: > > Something like this will work, yes. It'll probably look more like: > > > > Box::new(*x) > > > > This will be described in some of the RFCs that are coming up soon. > > Awesome! > > We should really get rid of the ~T syntax in favor of Foo (where Foo = > Box, Own, Heap, etc.), since it is deceptively simple for something that > should in fact be rarely used. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Clark. Key ID : 0x78099922 Fingerprint: B292 493C 51AE F3AB D016 DD04 E5E3 C36F 5534 F907 -------------- next part -------------- An HTML attachment was scrubbed... URL: From philippe.delrieu at free.fr Thu Apr 24 13:23:57 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Thu, 24 Apr 2014 22:23:57 +0200 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match Message-ID: <535972DD.2010104@free.fr> Hello, I have a problem in my code and I can't find a solution. I develop a test case that generate the same error. Any idea? use std::vec::Vec; use std::rc::Rc; use std::cell::RefCell; struct Test; impl Test { fn match_fn<'a>(&'a self) ->Option<&'a Test> { None } fn test_mutable<'a>(&'a mut self, test: &'a Test) {} } fn TestMatchBorrow() { let mut viewList: Vec<~Test> = Vec::new(); for ref mut test in viewList.mut_iter() { match test.match_fn() { Some(mut borrow_test) => test.test_mutable(borrow_test), None => {}, } } } #[main] fn main() { TestMatchBorrow(); } The test struct can't be changed. If I don't put the borrow_test in test.test_mutable(borrow_test) it compile. The error : test_match.rs:22:38: 22:42 error: cannot borrow `***test` as mutable because it is also borrowed as immutable test_match.rs:22 Some(mut borrow_test) => test.test_mutable(borrow_test), ^~~~ test_match.rs:21:15: 21:19 note: previous borrow of `***test` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `***test` until the borrow ends test_match.rs:21 match test.match_fn() { ^~~~ test_match.rs:24:10: 24:10 note: previous borrow ends here test_match.rs:21 match test.match_fn() { test_match.rs:22 Some(mut borrow_test) => test.test_mutable(borrow_test), test_match.rs:23 None => {}, test_match.rs:24 } Philippe From artella.coding at googlemail.com Thu Apr 24 14:06:33 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Thu, 24 Apr 2014 22:06:33 +0100 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: <535972DD.2010104@free.fr> References: <535972DD.2010104@free.fr> Message-ID: Hi, the following modified program seems to work (I am using rustc 0.11-pre-nightly (d35804e 2014-04-18 00:01:22 -0700) : ********************************************************** use std::vec::Vec; use std::rc::Rc; use std::cell::RefCell; struct Test; impl Test { fn match_fn<'a>(&'a self) ->Option<&'a Test> { None } fn test_mutable<'a>(&'a mut self, test: &'a mut Test) {} } fn TestMatchBorrow() { let mut viewList: Vec<~Test> = Vec::new(); for ref mut test in viewList.mut_iter() { match test.match_fn() { Some(&mut borrow_test) => test.test_mutable(&mut borrow_test), None => {}, } } } #[main] fn main() { TestMatchBorrow(); } ********************************************************** On Thu, Apr 24, 2014 at 9:23 PM, Philippe Delrieu wrote: > Hello, > > I have a problem in my code and I can't find a solution. I develop a test > case that generate the same error. Any idea? > > use std::vec::Vec; > use std::rc::Rc; > use std::cell::RefCell; > > struct Test; > > impl Test { > fn match_fn<'a>(&'a self) ->Option<&'a Test> { > None > } > > fn test_mutable<'a>(&'a mut self, test: &'a Test) {} > } > > fn TestMatchBorrow() { > let mut viewList: Vec<~Test> = Vec::new(); > > for ref mut test in viewList.mut_iter() { > match test.match_fn() { > Some(mut borrow_test) => test.test_mutable(borrow_test), > None => {}, > } > } > > } > > #[main] > fn main() { > TestMatchBorrow(); > } > > The test struct can't be changed. > If I don't put the borrow_test in test.test_mutable(borrow_test) it > compile. > > The error : > test_match.rs:22:38: 22:42 error: cannot borrow `***test` as mutable > because it is also borrowed as immutable > test_match.rs:22 Some(mut borrow_test) => > test.test_mutable(borrow_test), > ^~~~ > test_match.rs:21:15: 21:19 note: previous borrow of `***test` occurs > here; the immutable borrow prevents subsequent moves or mutable borrows of > `***test` until the borrow ends > test_match.rs:21 match test.match_fn() { > ^~~~ > test_match.rs:24:10: 24:10 note: previous borrow ends here > test_match.rs:21 match test.match_fn() { > test_match.rs:22 Some(mut borrow_test) => > test.test_mutable(borrow_test), > test_match.rs:23 None => {}, > test_match.rs:24 } > > Philippe > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bgamari at gmail.com Thu Apr 24 15:37:05 2014 From: bgamari at gmail.com (Ben Gamari) Date: Thu, 24 Apr 2014 18:37:05 -0400 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: <87d2g7p34w.fsf@gmail.com> References: <87ioq0p0fu.fsf@gmail.com> <87d2g7p34w.fsf@gmail.com> Message-ID: <87k3aenylq.fsf@gmail.com> Ben Gamari writes: > Vladimir Pouzanov writes: > ... >> My current idea is to make dedicated pools that could hold a compile-time >> configurable number of objects of same size, e.g. an IncomingPacketPool >> that can hold up to 3 frames where one frame is 128 bytes long. This way no >> other running process can interfere with code that processes incoming >> packets and that code can offload incoming packets into the pool for later >> processing, but up to three, and it will act in user-defined fashion (drop >> packets) if the pool is full. The implementation of that would be quite >> simple, and I think that it might be possible to extend ~T ownership for >> something like that. >> > I tried playing around (warning: code written by new Rust-er, expect > eye damage, feedback welcome) with a simple buffer pool implementation > this morning; unfortunately I found that Rust's restrictions on function > application in constant expressions makes static allocation quite > difficult (impossible?), > Tonight I played around with using the macro system to work around the static initializer limitation. The result[1] isn't terrible, but it didn't take long for me to run into a mutability issue. In short, I was inadvertently declaring my static pool as immutable, causing it to end up in the data.rel.ro section, resulting in a segfault when I attempt to increment the reference count (held in an `Unsafe`). I thought the obvious way around this would be to declare the pool as `static mut` but this unfortunately makes things quite verbose as one must declare each point of usage as `unsafe`. Moreover, for reasons I don't quite yet understand it seems that some data is still being placed in a read-only section and therefore the crash reappears. Regardless, it seems that mutable statics might be another sticking point in embedded contexts where static allocation is often desirable. Anyone have any clever ideas for dealing with this? Cheers, - Ben [1] https://gist.github.com/bgamari/033379d82f179eac8688 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 472 bytes Desc: not available URL: From farcaller at gmail.com Fri Apr 25 00:15:15 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Fri, 25 Apr 2014 08:15:15 +0100 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: <87k3aenylq.fsf@gmail.com> References: <87ioq0p0fu.fsf@gmail.com> <87d2g7p34w.fsf@gmail.com> <87k3aenylq.fsf@gmail.com> Message-ID: A few ideas: * make a static P that manages *T storage inside it. *T could be statically pointed to heap block in ram, P will wrap the API to make it less verbose. * use Cell to make internals of immutable mutable back again. This would not work with statics, obviously, as they will land in .rodata, but we have #[link_section] to deal with that. * same as above, but use extern with further linker script placement (same way as I deal with ioregs in zinc). On Thu, Apr 24, 2014 at 11:37 PM, Ben Gamari wrote: > Ben Gamari writes: > > > Vladimir Pouzanov writes: > > > ... > > >> My current idea is to make dedicated pools that could hold a > compile-time > >> configurable number of objects of same size, e.g. an IncomingPacketPool > >> that can hold up to 3 frames where one frame is 128 bytes long. This > way no > >> other running process can interfere with code that processes incoming > >> packets and that code can offload incoming packets into the pool for > later > >> processing, but up to three, and it will act in user-defined fashion > (drop > >> packets) if the pool is full. The implementation of that would be quite > >> simple, and I think that it might be possible to extend ~T ownership for > >> something like that. > >> > > I tried playing around (warning: code written by new Rust-er, expect > > eye damage, feedback welcome) with a simple buffer pool implementation > > this morning; unfortunately I found that Rust's restrictions on function > > application in constant expressions makes static allocation quite > > difficult (impossible?), > > > Tonight I played around with using the macro system to work around the > static initializer limitation. The result[1] isn't terrible, but > it didn't take long for me to run into a mutability issue. In short, I > was inadvertently declaring my static pool as immutable, causing it to > end up in the data.rel.ro section, resulting in a segfault when I attempt > to increment the reference count (held in an `Unsafe`). > > I thought the obvious way around this would be to declare the pool as > `static mut` but > this unfortunately makes things quite verbose as one must declare each > point of usage as `unsafe`. Moreover, for reasons I don't quite yet > understand it seems that some data is still being placed in a read-only > section and therefore the crash reappears. Regardless, it seems that > mutable statics might be another sticking point in embedded contexts > where static allocation is often desirable. > > Anyone have any clever ideas for dealing with this? > > Cheers, > > - Ben > > > [1] https://gist.github.com/bgamari/033379d82f179eac8688 > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From philippe.delrieu at free.fr Fri Apr 25 00:55:10 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Fri, 25 Apr 2014 09:55:10 +0200 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: References: <535972DD.2010104@free.fr> Message-ID: <535A14DE.3060503@free.fr> Thanks for your help. It works on the test but not in my main program. I'll try to update the test to make it works like the main program but I have not yet found what make the base code different. Philippe Le 24/04/2014 23:06, Artella Coding a ?crit : > Hi, the following modified program seems to work (I am using rustc > 0.11-pre-nightly (d35804e 2014-04-18 00:01:22 -0700) : > > > ********************************************************** > use std::vec::Vec; > use std::rc::Rc; > use std::cell::RefCell; > > struct Test; > > impl Test { > fn match_fn<'a>(&'a self) ->Option<&'a Test> { > None > } > > fn test_mutable<'a>(&'a mut self, test: &'a mut Test) {} > } > > fn TestMatchBorrow() { > let mut viewList: Vec<~Test> = Vec::new(); > > for ref mut test in viewList.mut_iter() { > match test.match_fn() { > Some(&mut borrow_test) => test.test_mutable(&mut borrow_test), > None => {}, > } > } > > } > > #[main] > fn main() { > TestMatchBorrow(); > } > ********************************************************** > > > > On Thu, Apr 24, 2014 at 9:23 PM, Philippe Delrieu > > wrote: > > Hello, > > I have a problem in my code and I can't find a solution. I develop > a test case that generate the same error. Any idea? > > use std::vec::Vec; > use std::rc::Rc; > use std::cell::RefCell; > > struct Test; > > impl Test { > fn match_fn<'a>(&'a self) ->Option<&'a Test> { > None > } > > fn test_mutable<'a>(&'a mut self, test: &'a Test) {} > } > > fn TestMatchBorrow() { > let mut viewList: Vec<~Test> = Vec::new(); > > for ref mut test in viewList.mut_iter() { > match test.match_fn() { > Some(mut borrow_test) => test.test_mutable(borrow_test), > None => {}, > } > } > > } > > #[main] > fn main() { > TestMatchBorrow(); > } > > The test struct can't be changed. > If I don't put the borrow_test in test.test_mutable(borrow_test) > it compile. > > The error : > test_match.rs:22:38: 22:42 error: cannot borrow `***test` as > mutable because it is also borrowed as immutable > test_match.rs:22 Some(mut > borrow_test) => test.test_mutable(borrow_test), > ^~~~ > test_match.rs:21:15: 21:19 note: previous borrow of `***test` > occurs here; the immutable borrow prevents subsequent moves or > mutable borrows of `***test` until the borrow ends > test_match.rs:21 match > test.match_fn() { > ^~~~ > test_match.rs:24:10: 24:10 note: previous borrow ends here > test_match.rs:21 match > test.match_fn() { > test_match.rs:22 Some(mut > borrow_test) => test.test_mutable(borrow_test), > test_match.rs:23 None => {}, > test_match.rs:24 } > > Philippe > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bgamari at gmail.com Fri Apr 25 03:12:26 2014 From: bgamari at gmail.com (Ben Gamari) Date: Fri, 25 Apr 2014 06:12:26 -0400 Subject: [rust-dev] A small announcement for zinc, the bare metal rust stack In-Reply-To: References: <87ioq0p0fu.fsf@gmail.com> <87d2g7p34w.fsf@gmail.com> <87k3aenylq.fsf@gmail.com> Message-ID: <87k3adogz9.fsf@gmail.com> Vladimir Pouzanov writes: > A few ideas: > Thanks! > * make a static P that manages *T storage inside it. *T could be > statically pointed to heap block in ram, P will wrap the API to make it > less verbose. > * use Cell to make internals of immutable mutable back again. This would > not work with statics, obviously, as they will land in .rodata, but we > have #[link_section] to deal with that. This was my reason for keeping the reference count in an `Unsafe`. I would have just used a `Cell` but unfortunately it's a bit painful to do this due to the static initializer issue. The `link_section` suggestion is a good one. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 472 bytes Desc: not available URL: From farcaller at gmail.com Fri Apr 25 08:14:00 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Fri, 25 Apr 2014 16:14:00 +0100 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: I have a side question related to the same code. Currently __STACK_LIMIT is constant, but I would like the preamble to verify stack overflow for multithreaded context, i.e. __STACK_LIMIT will depend on the current running thread. Is there any reason, why it's not a function? Any objections if I do some refactoring and make it a function? For a simple case that could be a weak symbol that returns a constant. On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton wrote: > I agree with Corey, it's much better to send it upstream first. I'd be > more than willing to help you out with writing tests or taking a peek > at the patch if you want! I'm acrichto on IRC > > On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov > wrote: > > The problem is that mrc is generated unless target is thumb1, but > cortex-m3 > > is thumb2 that still doesn't support mrc: > > > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html > , > > so an additional check to ST->TargetTriple.Data is required to verify > it's > > not thumbv7m. > > > > Do I need to submit patch against https://github.com/rust-lang/llvm or > send > > it to upstream? > > > > > > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov > > wrote: > >> > >> Hm, it seems to have precautions to stop mrc from materializing on > Thumb1. > >> I guess I need to take a better look into what's going wrong on my side. > >> I'll see what I can do with that. > >> > >> > >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton > wrote: > >>> > >>> The split stack patches for ARM were recently upstreamed, and they > >>> were modified when being upstreamed as well. Primarily the location of > >>> the split stack is no longer at a magic address for thumb, but rather > >>> it uses the same instruction as ARM (some thumb processors do indeed > >>> have the coprocessor). More information is in the long thread starting > >>> at the initial attempt to upstream [1]. > >>> > >>> For now you'll have to use no_split_stack because the thumb split > >>> stack will always use a coprocessor, but I'm sure that the upstream > >>> LLVM devs would be quite welcoming to tweaks to the slit-stack support > >>> (I'd also be willing to help). You can find the initial commit for > >>> support at rust-lang/llvm [2]. > >>> > >>> [1] - > >>> > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html > >>> [2] - https://github.com/rust-lang/llvm/pull/4 > >>> > >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov < > farcaller at gmail.com> > >>> wrote: > >>> > Starting recently (no more than two weeks), rustc is generating a > >>> > broken > >>> > prologue for arm. Here's the sample assembly: > >>> > 0x00000f44 <+0>: push {r4, r5} > >>> > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} > >>> > 0x00000f4a <+6>: mov r5, sp > >>> > 0x00000f4c <+8>: b.n 0xa78 > >>> > 0x00000f4e <+10>: ands r4, r0 > >>> > 0x00000f50 <+12>: cmp r4, r5 > >>> > 0x00000f52 <+14>: bcc.n 0xf66 > >>> > > >>> > > <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> > >>> > 0x00000f54 <+16>: movs r4, #16 > >>> > 0x00000f56 <+18>: movs r5, #0 > >>> > 0x00000f58 <+20>: push {lr} > >>> > 0x00000f5a <+22>: bl 0x19d8 <__morestack> > >>> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 > >>> > 0x00000f62 <+30>: pop {r4, r5} > >>> > 0x00000f64 <+32>: bx lr > >>> > > >>> > The problem is at 0x00000f46, where code tries to read from > coprocessor > >>> > 15 > >>> > register 13, which is "process id register". Well, coprocessor 15 > >>> > (actually, > >>> > all of the coprocessors) are missing from my target > thumbv7m-linux-eabi > >>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be > >>> > redundant > >>> > anyway), so I'm getting hardfaults in every function that rust > doesn't > >>> > inline. > >>> > > >>> > Any ideas on what might be going wrong? I assume that this is > actually > >>> > llvm's fault, as llvm should not materialize machine code which is > not > >>> > available for target anyway. > >>> > > >>> > Wrapping everything in #[no_split_stack] is a temporary workaround > and > >>> > surely not a long-term strategy. > >>> > > >>> > -- > >>> > Sincerely, > >>> > Vladimir "Farcaller" Pouzanov > >>> > http://farcaller.net/ > >>> > > >>> > _______________________________________________ > >>> > Rust-dev mailing list > >>> > Rust-dev at mozilla.org > >>> > https://mail.mozilla.org/listinfo/rust-dev > >>> > > >> > >> > >> > >> > >> -- > >> Sincerely, > >> Vladimir "Farcaller" Pouzanov > >> http://farcaller.net/ > > > > > > > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Fri Apr 25 09:20:41 2014 From: alex at crichton.co (Alex Crichton) Date: Fri, 25 Apr 2014 09:20:41 -0700 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: The prologue is run on every single function executed in a program, so I believe that in the hopes of keeping it as light as possible it never makes any function calls. I do agree though, that it's at tricky situation in that case. How does TLS otherwise work for that platform? On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov wrote: > I have a side question related to the same code. > > Currently __STACK_LIMIT is constant, but I would like the preamble to verify > stack overflow for multithreaded context, i.e. __STACK_LIMIT will depend on > the current running thread. Is there any reason, why it's not a function? > Any objections if I do some refactoring and make it a function? For a simple > case that could be a weak symbol that returns a constant. > > > On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton wrote: >> >> I agree with Corey, it's much better to send it upstream first. I'd be >> more than willing to help you out with writing tests or taking a peek >> at the patch if you want! I'm acrichto on IRC >> >> On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov >> wrote: >> > The problem is that mrc is generated unless target is thumb1, but >> > cortex-m3 >> > is thumb2 that still doesn't support mrc: >> > >> > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html, >> > so an additional check to ST->TargetTriple.Data is required to verify >> > it's >> > not thumbv7m. >> > >> > Do I need to submit patch against https://github.com/rust-lang/llvm or >> > send >> > it to upstream? >> > >> > >> > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov >> > wrote: >> >> >> >> Hm, it seems to have precautions to stop mrc from materializing on >> >> Thumb1. >> >> I guess I need to take a better look into what's going wrong on my >> >> side. >> >> I'll see what I can do with that. >> >> >> >> >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton >> >> wrote: >> >>> >> >>> The split stack patches for ARM were recently upstreamed, and they >> >>> were modified when being upstreamed as well. Primarily the location of >> >>> the split stack is no longer at a magic address for thumb, but rather >> >>> it uses the same instruction as ARM (some thumb processors do indeed >> >>> have the coprocessor). More information is in the long thread starting >> >>> at the initial attempt to upstream [1]. >> >>> >> >>> For now you'll have to use no_split_stack because the thumb split >> >>> stack will always use a coprocessor, but I'm sure that the upstream >> >>> LLVM devs would be quite welcoming to tweaks to the slit-stack support >> >>> (I'd also be willing to help). You can find the initial commit for >> >>> support at rust-lang/llvm [2]. >> >>> >> >>> [1] - >> >>> >> >>> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html >> >>> [2] - https://github.com/rust-lang/llvm/pull/4 >> >>> >> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov >> >>> >> >>> wrote: >> >>> > Starting recently (no more than two weeks), rustc is generating a >> >>> > broken >> >>> > prologue for arm. Here's the sample assembly: >> >>> > 0x00000f44 <+0>: push {r4, r5} >> >>> > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} >> >>> > 0x00000f4a <+6>: mov r5, sp >> >>> > 0x00000f4c <+8>: b.n 0xa78 >> >>> > 0x00000f4e <+10>: ands r4, r0 >> >>> > 0x00000f50 <+12>: cmp r4, r5 >> >>> > 0x00000f52 <+14>: bcc.n 0xf66 >> >>> > >> >>> > >> >>> > <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> >> >>> > 0x00000f54 <+16>: movs r4, #16 >> >>> > 0x00000f56 <+18>: movs r5, #0 >> >>> > 0x00000f58 <+20>: push {lr} >> >>> > 0x00000f5a <+22>: bl 0x19d8 <__morestack> >> >>> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 >> >>> > 0x00000f62 <+30>: pop {r4, r5} >> >>> > 0x00000f64 <+32>: bx lr >> >>> > >> >>> > The problem is at 0x00000f46, where code tries to read from >> >>> > coprocessor >> >>> > 15 >> >>> > register 13, which is "process id register". Well, coprocessor 15 >> >>> > (actually, >> >>> > all of the coprocessors) are missing from my target >> >>> > thumbv7m-linux-eabi >> >>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be >> >>> > redundant >> >>> > anyway), so I'm getting hardfaults in every function that rust >> >>> > doesn't >> >>> > inline. >> >>> > >> >>> > Any ideas on what might be going wrong? I assume that this is >> >>> > actually >> >>> > llvm's fault, as llvm should not materialize machine code which is >> >>> > not >> >>> > available for target anyway. >> >>> > >> >>> > Wrapping everything in #[no_split_stack] is a temporary workaround >> >>> > and >> >>> > surely not a long-term strategy. >> >>> > >> >>> > -- >> >>> > Sincerely, >> >>> > Vladimir "Farcaller" Pouzanov >> >>> > http://farcaller.net/ >> >>> > >> >>> > _______________________________________________ >> >>> > Rust-dev mailing list >> >>> > Rust-dev at mozilla.org >> >>> > https://mail.mozilla.org/listinfo/rust-dev >> >>> > >> >> >> >> >> >> >> >> >> >> -- >> >> Sincerely, >> >> Vladimir "Farcaller" Pouzanov >> >> http://farcaller.net/ >> > >> > >> > >> > >> > -- >> > Sincerely, >> > Vladimir "Farcaller" Pouzanov >> > http://farcaller.net/ > > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ From farcaller at gmail.com Fri Apr 25 10:33:19 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Fri, 25 Apr 2014 18:33:19 +0100 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: AFAIK, it's emulated in software with __tls_get_addr. Mind that Cortex-M MCUs that I'm toying with aren't usually compatible with any "full-blown" OS, and all the RTOSes out there have different implementations of multithreading and TLS, utilising the "none" OS target of gcc. The best way to deal with this would be to specify "arm-none-eabi" ABI for llvm, that would include tls behaviour amongst other things, but that sounds like a very complex task. On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton wrote: > The prologue is run on every single function executed in a program, so > I believe that in the hopes of keeping it as light as possible it > never makes any function calls. > > I do agree though, that it's at tricky situation in that case. How > does TLS otherwise work for that platform? > > On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov > wrote: > > I have a side question related to the same code. > > > > Currently __STACK_LIMIT is constant, but I would like the preamble to > verify > > stack overflow for multithreaded context, i.e. __STACK_LIMIT will depend > on > > the current running thread. Is there any reason, why it's not a function? > > Any objections if I do some refactoring and make it a function? For a > simple > > case that could be a weak symbol that returns a constant. > > > > > > On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton wrote: > >> > >> I agree with Corey, it's much better to send it upstream first. I'd be > >> more than willing to help you out with writing tests or taking a peek > >> at the patch if you want! I'm acrichto on IRC > >> > >> On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov < > farcaller at gmail.com> > >> wrote: > >> > The problem is that mrc is generated unless target is thumb1, but > >> > cortex-m3 > >> > is thumb2 that still doesn't support mrc: > >> > > >> > > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html > , > >> > so an additional check to ST->TargetTriple.Data is required to verify > >> > it's > >> > not thumbv7m. > >> > > >> > Do I need to submit patch against https://github.com/rust-lang/llvmor > >> > send > >> > it to upstream? > >> > > >> > > >> > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov < > farcaller at gmail.com> > >> > wrote: > >> >> > >> >> Hm, it seems to have precautions to stop mrc from materializing on > >> >> Thumb1. > >> >> I guess I need to take a better look into what's going wrong on my > >> >> side. > >> >> I'll see what I can do with that. > >> >> > >> >> > >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton > >> >> wrote: > >> >>> > >> >>> The split stack patches for ARM were recently upstreamed, and they > >> >>> were modified when being upstreamed as well. Primarily the location > of > >> >>> the split stack is no longer at a magic address for thumb, but > rather > >> >>> it uses the same instruction as ARM (some thumb processors do indeed > >> >>> have the coprocessor). More information is in the long thread > starting > >> >>> at the initial attempt to upstream [1]. > >> >>> > >> >>> For now you'll have to use no_split_stack because the thumb split > >> >>> stack will always use a coprocessor, but I'm sure that the upstream > >> >>> LLVM devs would be quite welcoming to tweaks to the slit-stack > support > >> >>> (I'd also be willing to help). You can find the initial commit for > >> >>> support at rust-lang/llvm [2]. > >> >>> > >> >>> [1] - > >> >>> > >> >>> > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html > >> >>> [2] - https://github.com/rust-lang/llvm/pull/4 > >> >>> > >> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov > >> >>> > >> >>> wrote: > >> >>> > Starting recently (no more than two weeks), rustc is generating a > >> >>> > broken > >> >>> > prologue for arm. Here's the sample assembly: > >> >>> > 0x00000f44 <+0>: push {r4, r5} > >> >>> > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} > >> >>> > 0x00000f4a <+6>: mov r5, sp > >> >>> > 0x00000f4c <+8>: b.n 0xa78 > >> >>> > 0x00000f4e <+10>: ands r4, r0 > >> >>> > 0x00000f50 <+12>: cmp r4, r5 > >> >>> > 0x00000f52 <+14>: bcc.n 0xf66 > >> >>> > > >> >>> > > >> >>> > > <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> > >> >>> > 0x00000f54 <+16>: movs r4, #16 > >> >>> > 0x00000f56 <+18>: movs r5, #0 > >> >>> > 0x00000f58 <+20>: push {lr} > >> >>> > 0x00000f5a <+22>: bl 0x19d8 <__morestack> > >> >>> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 > >> >>> > 0x00000f62 <+30>: pop {r4, r5} > >> >>> > 0x00000f64 <+32>: bx lr > >> >>> > > >> >>> > The problem is at 0x00000f46, where code tries to read from > >> >>> > coprocessor > >> >>> > 15 > >> >>> > register 13, which is "process id register". Well, coprocessor 15 > >> >>> > (actually, > >> >>> > all of the coprocessors) are missing from my target > >> >>> > thumbv7m-linux-eabi > >> >>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be > >> >>> > redundant > >> >>> > anyway), so I'm getting hardfaults in every function that rust > >> >>> > doesn't > >> >>> > inline. > >> >>> > > >> >>> > Any ideas on what might be going wrong? I assume that this is > >> >>> > actually > >> >>> > llvm's fault, as llvm should not materialize machine code which is > >> >>> > not > >> >>> > available for target anyway. > >> >>> > > >> >>> > Wrapping everything in #[no_split_stack] is a temporary workaround > >> >>> > and > >> >>> > surely not a long-term strategy. > >> >>> > > >> >>> > -- > >> >>> > Sincerely, > >> >>> > Vladimir "Farcaller" Pouzanov > >> >>> > http://farcaller.net/ > >> >>> > > >> >>> > _______________________________________________ > >> >>> > Rust-dev mailing list > >> >>> > Rust-dev at mozilla.org > >> >>> > https://mail.mozilla.org/listinfo/rust-dev > >> >>> > > >> >> > >> >> > >> >> > >> >> > >> >> -- > >> >> Sincerely, > >> >> Vladimir "Farcaller" Pouzanov > >> >> http://farcaller.net/ > >> > > >> > > >> > > >> > > >> > -- > >> > Sincerely, > >> > Vladimir "Farcaller" Pouzanov > >> > http://farcaller.net/ > > > > > > > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From japaric at linux.com Fri Apr 25 19:25:13 2014 From: japaric at linux.com (Jorge Aparicio) Date: Fri, 25 Apr 2014 21:25:13 -0500 Subject: [rust-dev] Rust by example Message-ID: <20140426022513.GA5314@ideapad.lan> Hello fellow Rusticans, I'm pleased to announce the Rust by example website [1], which is a Rust version of the Go by example website [2], aimed at explaining rustic concepts and giving an overview of the Rust distribution libraries with examples. Although the website is still a WIP, it already contains 30+ examples ranging from the classic Hello World to a simple client server program, covering core concepts like ownership, borrowing, generics, traits, tasks, etc. Be sure to drop by the main repo [3], and let me know what you think and/or of any idea you have to improve it! Cheers, Jorge Aparicio [1] http://japaric.github.io/rust-by-example [2] https://gobyexample.com [3] https://github.com/japaric/rust-by-example From banderson at mozilla.com Fri Apr 25 19:32:51 2014 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 25 Apr 2014 19:32:51 -0700 Subject: [rust-dev] Rust by example In-Reply-To: <20140426022513.GA5314@ideapad.lan> References: <20140426022513.GA5314@ideapad.lan> Message-ID: <535B1AD3.6030002@mozilla.com> This is amazing! I added it to the wiki https://github.com/mozilla/rust/wiki/Doc-examples On 04/25/2014 07:25 PM, Jorge Aparicio wrote: > Hello fellow Rusticans, > > I'm pleased to announce the Rust by example website [1], which is a Rust > version of the Go by example website [2], aimed at explaining rustic concepts > and giving an overview of the Rust distribution libraries with examples. > > Although the website is still a WIP, it already contains 30+ examples ranging > from the classic Hello World to a simple client server program, covering core > concepts like ownership, borrowing, generics, traits, tasks, etc. > > Be sure to drop by the main repo [3], and let me know what you think and/or of > any idea you have to improve it! > > Cheers, > > Jorge Aparicio > > [1] http://japaric.github.io/rust-by-example > [2] https://gobyexample.com > [3] https://github.com/japaric/rust-by-example > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From dnfagnan at gmail.com Fri Apr 25 19:51:41 2014 From: dnfagnan at gmail.com (Daniel Fagnan) Date: Fri, 25 Apr 2014 20:51:41 -0600 Subject: [rust-dev] Rust by example In-Reply-To: <20140426022513.GA5314@ideapad.lan> References: <20140426022513.GA5314@ideapad.lan> Message-ID: <64BD32F2-B2B9-454A-A3C0-2A2991229907@gmail.com> Awesome work! I actually had an initial rust by example site going (http://rustbyexample.github.io/), but I just forgot about it and didn?t continue it. This version looks so much better! I?d be happy to give you the organization github `rustbyexamples` if you want. Cheers, Daniel On Apr 25, 2014, at 8:25 PM, Jorge Aparicio wrote: > Hello fellow Rusticans, > > I'm pleased to announce the Rust by example website [1], which is a Rust > version of the Go by example website [2], aimed at explaining rustic concepts > and giving an overview of the Rust distribution libraries with examples. > > Although the website is still a WIP, it already contains 30+ examples ranging > from the classic Hello World to a simple client server program, covering core > concepts like ownership, borrowing, generics, traits, tasks, etc. > > Be sure to drop by the main repo [3], and let me know what you think and/or of > any idea you have to improve it! > > Cheers, > > Jorge Aparicio > > [1] http://japaric.github.io/rust-by-example > [2] https://gobyexample.com > [3] https://github.com/japaric/rust-by-example > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From daimrod at gmail.com Fri Apr 25 20:23:06 2014 From: daimrod at gmail.com (Daimrod) Date: Sat, 26 Apr 2014 12:23:06 +0900 Subject: [rust-dev] Rust by example In-Reply-To: <20140426022513.GA5314@ideapad.lan> (Jorge Aparicio's message of "Fri, 25 Apr 2014 21:25:13 -0500") References: <20140426022513.GA5314@ideapad.lan> Message-ID: <87vbtwvko5.fsf@tanger.home> Jorge Aparicio writes: > Hello fellow Rusticans, > > I'm pleased to announce the Rust by example website [1], which is a Rust > version of the Go by example website [2], aimed at explaining rustic concepts > and giving an overview of the Rust distribution libraries with examples. > > Although the website is still a WIP, it already contains 30+ examples ranging > from the classic Hello World to a simple client server program, covering core > concepts like ownership, borrowing, generics, traits, tasks, etc. Awesome job! > Be sure to drop by the main repo [3], and let me know what you think and/or of > any idea you have to improve it! It would be cool if the output of the code blocks were displayed. > Cheers, > > Jorge Aparicio > > [1] http://japaric.github.io/rust-by-example > [2] https://gobyexample.com > [3] https://github.com/japaric/rust-by-example -- Daimrod/Greg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 835 bytes Desc: not available URL: From japaric at linux.com Fri Apr 25 20:41:08 2014 From: japaric at linux.com (Jorge Aparicio) Date: Fri, 25 Apr 2014 22:41:08 -0500 Subject: [rust-dev] Rust by example In-Reply-To: <64BD32F2-B2B9-454A-A3C0-2A2991229907@gmail.com> References: <20140426022513.GA5314@ideapad.lan> <64BD32F2-B2B9-454A-A3C0-2A2991229907@gmail.com> Message-ID: <20140426034108.GB5314@ideapad.lan> Hi Daniel, It would be great to have the site under (http://rustbyexample.github.io)! I got two questions though: * Would I need to transfer the repo to the organization for this? (I suppose yes) * Could/should we make the original site redirect to the organization site? (I wouldn't want people to hit 404 errors) (First time dealing with github pages and github organizations) On Fri, Apr 25, 2014 at 08:51:41PM -0600, Daniel Fagnan wrote: > Awesome work! I actually had an initial rust by example site going (http://rustbyexample.github.io/), but I just forgot about it and didn?t continue it. This version looks so much better! I?d be happy to give you the organization github `rustbyexamples` if you want. > > Cheers, > Daniel > > On Apr 25, 2014, at 8:25 PM, Jorge Aparicio wrote: > > > Hello fellow Rusticans, > > > > I'm pleased to announce the Rust by example website [1], which is a Rust > > version of the Go by example website [2], aimed at explaining rustic concepts > > and giving an overview of the Rust distribution libraries with examples. > > > > Although the website is still a WIP, it already contains 30+ examples ranging > > from the classic Hello World to a simple client server program, covering core > > concepts like ownership, borrowing, generics, traits, tasks, etc. > > > > Be sure to drop by the main repo [3], and let me know what you think and/or of > > any idea you have to improve it! > > > > Cheers, > > > > Jorge Aparicio > > > > [1] http://japaric.github.io/rust-by-example > > [2] https://gobyexample.com > > [3] https://github.com/japaric/rust-by-example > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > From eg1290 at gmail.com Fri Apr 25 20:50:38 2014 From: eg1290 at gmail.com (Evan G) Date: Fri, 25 Apr 2014 22:50:38 -0500 Subject: [rust-dev] Rust by example In-Reply-To: <20140426034108.GB5314@ideapad.lan> References: <20140426022513.GA5314@ideapad.lan> <64BD32F2-B2B9-454A-A3C0-2A2991229907@gmail.com> <20140426034108.GB5314@ideapad.lan> Message-ID: You could just do a quick js redirect... It'd be used for like 2 days, as people read this thread before scrolling down to the bottom. On Apr 25, 2014 10:41 PM, "Jorge Aparicio" wrote: > Hi Daniel, > > It would be great to have the site under (http://rustbyexample.github.io)! > I > got two questions though: > > * Would I need to transfer the repo to the organization for this? (I > suppose > yes) > * Could/should we make the original site redirect to the organization > site? (I > wouldn't want people to hit 404 errors) > > (First time dealing with github pages and github organizations) > > On Fri, Apr 25, 2014 at 08:51:41PM -0600, Daniel Fagnan wrote: > > Awesome work! I actually had an initial rust by example site going ( > http://rustbyexample.github.io/), but I just forgot about it and didn?t > continue it. This version looks so much better! I?d be happy to give you > the organization github `rustbyexamples` if you want. > > > > Cheers, > > Daniel > > > > On Apr 25, 2014, at 8:25 PM, Jorge Aparicio wrote: > > > > > Hello fellow Rusticans, > > > > > > I'm pleased to announce the Rust by example website [1], which is a > Rust > > > version of the Go by example website [2], aimed at explaining rustic > concepts > > > and giving an overview of the Rust distribution libraries with > examples. > > > > > > Although the website is still a WIP, it already contains 30+ examples > ranging > > > from the classic Hello World to a simple client server program, > covering core > > > concepts like ownership, borrowing, generics, traits, tasks, etc. > > > > > > Be sure to drop by the main repo [3], and let me know what you think > and/or of > > > any idea you have to improve it! > > > > > > Cheers, > > > > > > Jorge Aparicio > > > > > > [1] http://japaric.github.io/rust-by-example > > > [2] https://gobyexample.com > > > [3] https://github.com/japaric/rust-by-example > > > _______________________________________________ > > > Rust-dev mailing list > > > Rust-dev at mozilla.org > > > https://mail.mozilla.org/listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From japaric at linux.com Fri Apr 25 20:50:57 2014 From: japaric at linux.com (Jorge Aparicio) Date: Fri, 25 Apr 2014 22:50:57 -0500 Subject: [rust-dev] Rust by example In-Reply-To: <87vbtwvko5.fsf@tanger.home> References: <20140426022513.GA5314@ideapad.lan> <87vbtwvko5.fsf@tanger.home> Message-ID: <20140426035057.GC5314@ideapad.lan> On Sat, Apr 26, 2014 at 12:23:06PM +0900, Daimrod wrote: > Jorge Aparicio writes: > > > Hello fellow Rusticans, > > > > I'm pleased to announce the Rust by example website [1], which is a Rust > > version of the Go by example website [2], aimed at explaining rustic concepts > > and giving an overview of the Rust distribution libraries with examples. > > > > Although the website is still a WIP, it already contains 30+ examples ranging > > from the classic Hello World to a simple client server program, covering core > > concepts like ownership, borrowing, generics, traits, tasks, etc. > > Awesome job! > > > Be sure to drop by the main repo [3], and let me know what you think and/or of > > any idea you have to improve it! > > It would be cool if the output of the code blocks were displayed. > Thanks for the feedback! A few examples have the output at the end, but yes I think it would be better if all the examples displayed the output. Will do, thanks again. > > Cheers, > > > > Jorge Aparicio > > > > [1] http://japaric.github.io/rust-by-example > > [2] https://gobyexample.com > > [3] https://github.com/japaric/rust-by-example > > -- > Daimrod/Greg > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From dnfagnan at gmail.com Fri Apr 25 20:55:29 2014 From: dnfagnan at gmail.com (Daniel Fagnan) Date: Fri, 25 Apr 2014 21:55:29 -0600 Subject: [rust-dev] Rust by example In-Reply-To: <20140426034108.GB5314@ideapad.lan> References: <20140426022513.GA5314@ideapad.lan> <64BD32F2-B2B9-454A-A3C0-2A2991229907@gmail.com> <20140426034108.GB5314@ideapad.lan> Message-ID: > It would be great to have the site under (http://rustbyexample.github.io) Awesome. I added you as an owner to the organization. > Would I need to transfer the repo to the organization for this? (I suppose yes) Yes. I deleted my previous repo there, so you can just transfer it to a `rustbyexample.github.io` repo (it has to be that name for Github to pick it up). > Could/should we make the original site redirect to the organization site? (I wouldn't want people to hit 404 errors) You could just redirect it to the new site afterwards. Shouldn?t be a big deal. Let me know if you have any questions, Daniel On Apr 25, 2014, at 9:41 PM, Jorge Aparicio wrote: > Hi Daniel, > > It would be great to have the site under (http://rustbyexample.github.io)! I > got two questions though: > > * Would I need to transfer the repo to the organization for this? (I suppose > yes) > * Could/should we make the original site redirect to the organization site? (I > wouldn't want people to hit 404 errors) > > (First time dealing with github pages and github organizations) > > On Fri, Apr 25, 2014 at 08:51:41PM -0600, Daniel Fagnan wrote: >> Awesome work! I actually had an initial rust by example site going (http://rustbyexample.github.io/), but I just forgot about it and didn?t continue it. This version looks so much better! I?d be happy to give you the organization github `rustbyexamples` if you want. >> >> Cheers, >> Daniel >> >> On Apr 25, 2014, at 8:25 PM, Jorge Aparicio wrote: >> >>> Hello fellow Rusticans, >>> >>> I'm pleased to announce the Rust by example website [1], which is a Rust >>> version of the Go by example website [2], aimed at explaining rustic concepts >>> and giving an overview of the Rust distribution libraries with examples. >>> >>> Although the website is still a WIP, it already contains 30+ examples ranging >>> from the classic Hello World to a simple client server program, covering core >>> concepts like ownership, borrowing, generics, traits, tasks, etc. >>> >>> Be sure to drop by the main repo [3], and let me know what you think and/or of >>> any idea you have to improve it! >>> >>> Cheers, >>> >>> Jorge Aparicio >>> >>> [1] http://japaric.github.io/rust-by-example >>> [2] https://gobyexample.com >>> [3] https://github.com/japaric/rust-by-example >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >> From japaric at linux.com Fri Apr 25 21:53:52 2014 From: japaric at linux.com (Jorge Aparicio) Date: Fri, 25 Apr 2014 23:53:52 -0500 Subject: [rust-dev] Rust by example In-Reply-To: References: <20140426022513.GA5314@ideapad.lan> <64BD32F2-B2B9-454A-A3C0-2A2991229907@gmail.com> <20140426034108.GB5314@ideapad.lan> Message-ID: <20140426045352.GD5314@ideapad.lan> OK guys, I managed to get the site on (http://rustbyexample.github.io) \o/. The original site is a duplicate for now, I'll look into the js redirection thing tomorrow (time to hit to sack). P.S. Everyone thank Daniel for providing the new site. On Fri, Apr 25, 2014 at 09:55:29PM -0600, Daniel Fagnan wrote: > > It would be great to have the site under (http://rustbyexample.github.io) > > Awesome. I added you as an owner to the organization. > > > Would I need to transfer the repo to the organization for this? (I suppose yes) > > Yes. I deleted my previous repo there, so you can just transfer it to a `rustbyexample.github.io` repo (it has to be that name for Github to pick it up). > > > Could/should we make the original site redirect to the organization site? (I wouldn't want people to hit 404 errors) > > You could just redirect it to the new site afterwards. Shouldn?t be a big deal. > > Let me know if you have any questions, > Daniel > > On Apr 25, 2014, at 9:41 PM, Jorge Aparicio wrote: > > > Hi Daniel, > > > > It would be great to have the site under (http://rustbyexample.github.io)! I > > got two questions though: > > > > * Would I need to transfer the repo to the organization for this? (I suppose > > yes) > > * Could/should we make the original site redirect to the organization site? (I > > wouldn't want people to hit 404 errors) > > > > (First time dealing with github pages and github organizations) > > > > On Fri, Apr 25, 2014 at 08:51:41PM -0600, Daniel Fagnan wrote: > >> Awesome work! I actually had an initial rust by example site going (http://rustbyexample.github.io/), but I just forgot about it and didn?t continue it. This version looks so much better! I?d be happy to give you the organization github `rustbyexamples` if you want. > >> > >> Cheers, > >> Daniel > >> > >> On Apr 25, 2014, at 8:25 PM, Jorge Aparicio wrote: > >> > >>> Hello fellow Rusticans, > >>> > >>> I'm pleased to announce the Rust by example website [1], which is a Rust > >>> version of the Go by example website [2], aimed at explaining rustic concepts > >>> and giving an overview of the Rust distribution libraries with examples. > >>> > >>> Although the website is still a WIP, it already contains 30+ examples ranging > >>> from the classic Hello World to a simple client server program, covering core > >>> concepts like ownership, borrowing, generics, traits, tasks, etc. > >>> > >>> Be sure to drop by the main repo [3], and let me know what you think and/or of > >>> any idea you have to improve it! > >>> > >>> Cheers, > >>> > >>> Jorge Aparicio > >>> > >>> [1] http://japaric.github.io/rust-by-example > >>> [2] https://gobyexample.com > >>> [3] https://github.com/japaric/rust-by-example > >>> _______________________________________________ > >>> Rust-dev mailing list > >>> Rust-dev at mozilla.org > >>> https://mail.mozilla.org/listinfo/rust-dev > >> > From japaric at linux.com Fri Apr 25 21:57:20 2014 From: japaric at linux.com (Jorge Aparicio) Date: Fri, 25 Apr 2014 23:57:20 -0500 Subject: [rust-dev] Rust by example In-Reply-To: References: <20140426022513.GA5314@ideapad.lan> Message-ID: <20140426045720.GE5314@ideapad.lan> On Fri, Apr 25, 2014 at 11:56:00PM -0400, Ashish Myles wrote: Nice catch, will fix. Thanks! > Nice work! > > RE: the Function example. > The description isn't exactly right. Rust only returns the last expression > (without a return statement) *if* it is not terminated by a semicolon. > > > On Fri, Apr 25, 2014 at 10:25 PM, Jorge Aparicio wrote: > > > Hello fellow Rusticans, > > > > I'm pleased to announce the Rust by example website [1], which is a Rust > > version of the Go by example website [2], aimed at explaining rustic > > concepts > > and giving an overview of the Rust distribution libraries with examples. > > > > Although the website is still a WIP, it already contains 30+ examples > > ranging > > from the classic Hello World to a simple client server program, covering > > core > > concepts like ownership, borrowing, generics, traits, tasks, etc. > > > > Be sure to drop by the main repo [3], and let me know what you think > > and/or of > > any idea you have to improve it! > > > > Cheers, > > > > Jorge Aparicio > > > > [1] http://japaric.github.io/rust-by-example > > [2] https://gobyexample.com > > [3] https://github.com/japaric/rust-by-example > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > From kevin at sb.org Sat Apr 26 01:37:36 2014 From: kevin at sb.org (Kevin Ballard) Date: Sat, 26 Apr 2014 01:37:36 -0700 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: <535A14DE.3060503@free.fr> References: <535972DD.2010104@free.fr> <535A14DE.3060503@free.fr> Message-ID: <39BE8908-4371-416C-A856-71D3490202EA@sb.org> This "fixed" code is wrong. Instead of taking a reference to the borrow, it actually destructs it and copies the referenced Test. Since it's not keeping a reference anymore, that's why it works. The issue with the original code is test.match_fn() borrow test, and Some(mut borrow_test) keeps that borrow alive in the borrow_test binding. Since it's used in the match arm, that means the borrow is alive, which prevents test.test_mutable() from being called. I don't know how to fix this code when I have no idea what you're actually trying to accomplish here. -Kevin On Apr 25, 2014, at 12:55 AM, Philippe Delrieu wrote: > Thanks for your help. It works on the test but not in my main program. > > I'll try to update the test to make it works like the main program but I have not yet found what make the base code different. > > Philippe > > Le 24/04/2014 23:06, Artella Coding a ?crit : >> Hi, the following modified program seems to work (I am using rustc 0.11-pre-nightly (d35804e 2014-04-18 00:01:22 -0700) : >> >> >> ********************************************************** >> use std::vec::Vec; >> use std::rc::Rc; >> use std::cell::RefCell; >> >> struct Test; >> >> impl Test { >> fn match_fn<'a>(&'a self) ->Option<&'a Test> { >> None >> } >> >> fn test_mutable<'a>(&'a mut self, test: &'a mut Test) {} >> } >> >> fn TestMatchBorrow() { >> let mut viewList: Vec<~Test> = Vec::new(); >> >> for ref mut test in viewList.mut_iter() { >> match test.match_fn() { >> Some(&mut borrow_test) => test.test_mutable(&mut borrow_test), >> None => {}, >> } >> } >> >> } >> >> #[main] >> fn main() { >> TestMatchBorrow(); >> } >> ********************************************************** >> >> >> >> On Thu, Apr 24, 2014 at 9:23 PM, Philippe Delrieu wrote: >> Hello, >> >> I have a problem in my code and I can't find a solution. I develop a test case that generate the same error. Any idea? >> >> use std::vec::Vec; >> use std::rc::Rc; >> use std::cell::RefCell; >> >> struct Test; >> >> impl Test { >> fn match_fn<'a>(&'a self) ->Option<&'a Test> { >> None >> } >> >> fn test_mutable<'a>(&'a mut self, test: &'a Test) {} >> } >> >> fn TestMatchBorrow() { >> let mut viewList: Vec<~Test> = Vec::new(); >> >> for ref mut test in viewList.mut_iter() { >> match test.match_fn() { >> Some(mut borrow_test) => test.test_mutable(borrow_test), >> None => {}, >> } >> } >> >> } >> >> #[main] >> fn main() { >> TestMatchBorrow(); >> } >> >> The test struct can't be changed. >> If I don't put the borrow_test in test.test_mutable(borrow_test) it compile. >> >> The error : >> test_match.rs:22:38: 22:42 error: cannot borrow `***test` as mutable because it is also borrowed as immutable >> test_match.rs:22 Some(mut borrow_test) => test.test_mutable(borrow_test), >> ^~~~ >> test_match.rs:21:15: 21:19 note: previous borrow of `***test` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `***test` until the borrow ends >> test_match.rs:21 match test.match_fn() { >> ^~~~ >> test_match.rs:24:10: 24:10 note: previous borrow ends here >> test_match.rs:21 match test.match_fn() { >> test_match.rs:22 Some(mut borrow_test) => test.test_mutable(borrow_test), >> test_match.rs:23 None => {}, >> test_match.rs:24 } >> >> Philippe >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Sat Apr 26 02:28:17 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Sat, 26 Apr 2014 10:28:17 +0100 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: <39BE8908-4371-416C-A856-71D3490202EA@sb.org> References: <535972DD.2010104@free.fr> <535A14DE.3060503@free.fr> <39BE8908-4371-416C-A856-71D3490202EA@sb.org> Message-ID: To be honest I didn't try to understand what the code was doing. Just fiddled with it until it compiled:) On Sat, Apr 26, 2014 at 9:37 AM, Kevin Ballard wrote: > This "fixed" code is wrong. Instead of taking a reference to the borrow, > it actually destructs it and copies the referenced Test. Since it's not > keeping a reference anymore, that's why it works. > > The issue with the original code is test.match_fn() borrow test, and > Some(mut borrow_test) keeps that borrow alive in the borrow_test binding. > Since it's used in the match arm, that means the borrow is alive, which > prevents test.test_mutable() from being called. > > I don't know how to fix this code when I have no idea what you're actually > trying to accomplish here. > > -Kevin > > On Apr 25, 2014, at 12:55 AM, Philippe Delrieu > wrote: > > Thanks for your help. It works on the test but not in my main program. > > I'll try to update the test to make it works like the main program but I > have not yet found what make the base code different. > > Philippe > > Le 24/04/2014 23:06, Artella Coding a ?crit : > > Hi, the following modified program seems to work (I am using rustc > 0.11-pre-nightly (d35804e 2014-04-18 00:01:22 -0700) : > > > ********************************************************** > use std::vec::Vec; > use std::rc::Rc; > use std::cell::RefCell; > > struct Test; > > impl Test { > fn match_fn<'a>(&'a self) ->Option<&'a Test> { > None > } > > fn test_mutable<'a>(&'a mut self, test: &'a mut Test) {} > } > > fn TestMatchBorrow() { > let mut viewList: Vec<~Test> = Vec::new(); > > for ref mut test in viewList.mut_iter() { > match test.match_fn() { > Some(&mut borrow_test) => test.test_mutable(&mut borrow_test), > None => {}, > } > } > > } > > #[main] > fn main() { > TestMatchBorrow(); > } > ********************************************************** > > > > On Thu, Apr 24, 2014 at 9:23 PM, Philippe Delrieu < > philippe.delrieu at free.fr> wrote: > >> Hello, >> >> I have a problem in my code and I can't find a solution. I develop a test >> case that generate the same error. Any idea? >> >> use std::vec::Vec; >> use std::rc::Rc; >> use std::cell::RefCell; >> >> struct Test; >> >> impl Test { >> fn match_fn<'a>(&'a self) ->Option<&'a Test> { >> None >> } >> >> fn test_mutable<'a>(&'a mut self, test: &'a Test) {} >> } >> >> fn TestMatchBorrow() { >> let mut viewList: Vec<~Test> = Vec::new(); >> >> for ref mut test in viewList.mut_iter() { >> match test.match_fn() { >> Some(mut borrow_test) => test.test_mutable(borrow_test), >> None => {}, >> } >> } >> >> } >> >> #[main] >> fn main() { >> TestMatchBorrow(); >> } >> >> The test struct can't be changed. >> If I don't put the borrow_test in test.test_mutable(borrow_test) it >> compile. >> >> The error : >> test_match.rs:22:38: 22:42 error: cannot borrow `***test` as mutable >> because it is also borrowed as immutable >> test_match.rs:22 Some(mut borrow_test) => >> test.test_mutable(borrow_test), >> ^~~~ >> test_match.rs:21:15: 21:19 note: previous borrow of `***test` occurs >> here; the immutable borrow prevents subsequent moves or mutable borrows of >> `***test` until the borrow ends >> test_match.rs:21 match test.match_fn() { >> ^~~~ >> test_match.rs:24:10: 24:10 note: previous borrow ends here >> test_match.rs:21 match test.match_fn() { >> test_match.rs:22 Some(mut borrow_test) => >> test.test_mutable(borrow_test), >> test_match.rs:23 None => {}, >> test_match.rs:24 } >> >> Philippe >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jon.mb at proinbox.com Sat Apr 26 03:26:42 2014 From: jon.mb at proinbox.com (John Mija) Date: Sat, 26 Apr 2014 11:26:42 +0100 Subject: [rust-dev] Cryptol, the language of cryptography Message-ID: <535B89E2.30608@proinbox.com> The cryptography library was removed from the standard library because there was not way to verify the possible issues in the algorithms implementations. But luckly, there is already a DSL designed for such task: http://cryptol.net/index.html https://news.ycombinator.com/item?id=7642434 http://2012.sharcs.org/slides/hurd.pdf In summary, Cryptol helps to implement existing known crypto algorithms correctly, but also to design new crypto algorithms. So, please review the inclusion of crypto. library in the standard lib. From mozilla at mcpherrin.ca Sat Apr 26 04:15:31 2014 From: mozilla at mcpherrin.ca (Matthew McPherrin) Date: Sat, 26 Apr 2014 04:15:31 -0700 Subject: [rust-dev] Self and self in trait definitions In-Reply-To: References: Message-ID: Thanks for your input! It's important to take a critical eye to the language, especially from newcomers. However, I think the self value and its type, Self, are a quite natural pairing. The Rust convention of making types in UpperCamelCase should visually cue what the difference is. Also, they appear different places in the syntax, so I think there's not much danger of mis-reading one from the other once you know the difference. Misusing one for the other by a user who doesn't will just result in a compilation error, and so a confused user could quickly get help on what's wrong. All of your other suggestions feel much more un-natural to me in the context of Rust. I don't think you will have much support in this cause, unfortunately. On Thu, Apr 24, 2014 at 2:19 AM, Mario Sopena Novales wrote: > Hi everyone, > > I've been learning Rust for the last couple of weeks and I'm quite excited > with it. My experience is mainly in C and Rust feels like a nice > improvement. Thank you for the hard work! > > I've recently found this bit of the tutorial: > http://static.rust-lang.org/doc/master/tutorial.html#type-parameterized-traits > > and it got me confused for a while because of the similarity between self > and Self (just the 'S' in caps) even when they refer to completely different > things. > > I would suggest to change the Self identifier to something less similar to > self which also hints as to what it is like selfT, Tself, self_type or > type(self). Maybe someone with more Rust experience can come up with better > suggestions. > > I just think that self/Self is quite confusing and harder to parse for the > eye. > > I'm happy to write a RFC if you think the idea has some merit. > > Mario > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From steve at steveklabnik.com Sat Apr 26 06:21:52 2014 From: steve at steveklabnik.com (Steve Klabnik) Date: Sat, 26 Apr 2014 06:21:52 -0700 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: <535B89E2.30608@proinbox.com> References: <535B89E2.30608@proinbox.com> Message-ID: I think the bigger issue is that we really need someone who lives and breathes cryptography before we feel okay about shipping crypto code. Bugs with crypto don't often happen because of poorly implemented primitives: they happen when you combine those primitives in bad ways. Formal analysis doesn't help there. From steve at steveklabnik.com Sat Apr 26 06:23:15 2014 From: steve at steveklabnik.com (Steve Klabnik) Date: Sat, 26 Apr 2014 06:23:15 -0700 Subject: [rust-dev] Rust by example In-Reply-To: <20140426045720.GE5314@ideapad.lan> References: <20140426022513.GA5314@ideapad.lan> <20140426045720.GE5314@ideapad.lan> Message-ID: If you move a repo, GitHub will automatically redirect it. https://github.com/blog/1508-repository-redirects-are-here So just delete the new one, then transfer the old one. :magic: From eg1290 at gmail.com Sat Apr 26 06:31:11 2014 From: eg1290 at gmail.com (Evan G) Date: Sat, 26 Apr 2014 08:31:11 -0500 Subject: [rust-dev] Rust by example In-Reply-To: References: <20140426022513.GA5314@ideapad.lan> <20140426045720.GE5314@ideapad.lan> Message-ID: > There is one caveat with the new > redirect support worth noting: > GitHub Pages sites are not > automatically redirected when their > repositories are renamed at this > time. Renaming a Pages repository > will continue to break any existing > links to content hosted on the > github.io domain or custom domains On Apr 26, 2014 8:23 AM, "Steve Klabnik" wrote: > If you move a repo, GitHub will automatically redirect it. > https://github.com/blog/1508-repository-redirects-are-here > > So just delete the new one, then transfer the old one. :magic: > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From geo.couprie at gmail.com Sat Apr 26 09:39:22 2014 From: geo.couprie at gmail.com (Geoffroy Couprie) Date: Sat, 26 Apr 2014 18:39:22 +0200 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: References: <535B89E2.30608@proinbox.com> Message-ID: On Sat, Apr 26, 2014 at 3:21 PM, Steve Klabnik wrote: > I think the bigger issue is that we really need someone who lives and > breathes cryptography before we feel okay about shipping crypto code. > > Bugs with crypto don't often happen because of poorly implemented > primitives: they happen when you combine those primitives in bad ways. > Formal analysis doesn't help there. Before writing production ready crypto code, some things must be tested carefully, like the ability to write constant time code, or a "secure" buffer implementation (wiped before freeing it). Constant time code is possible in theory (the Rust-crypto has an AES implementation with precautions for that), but I do not know what could be messed up by LLVM optimizations there. Still, with the possibility of dropping some assembly directly where it is needed, it is a great platform for crypto experimentation. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jens at nockert.se Sat Apr 26 09:55:09 2014 From: jens at nockert.se (Jens Nockert) Date: Sat, 26 Apr 2014 18:55:09 +0200 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: References: <535B89E2.30608@proinbox.com> Message-ID: <0E0510E8-5941-49E5-8D90-BFAC86367C21@nockert.se> On 26 Apr 2014, at 18:39, Geoffroy Couprie wrote: > Constant time code is possible in theory As long as you don?t do memory accesses, branches, division, floating-point, etc. Some x86 processors even have variable-time multiplication. Writing constant-time code is essentially impossible. -------------- next part -------------- An HTML attachment was scrubbed... URL: From geo.couprie at gmail.com Sat Apr 26 10:04:39 2014 From: geo.couprie at gmail.com (Geoffroy Couprie) Date: Sat, 26 Apr 2014 19:04:39 +0200 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: <0E0510E8-5941-49E5-8D90-BFAC86367C21@nockert.se> References: <535B89E2.30608@proinbox.com> <0E0510E8-5941-49E5-8D90-BFAC86367C21@nockert.se> Message-ID: On Sat, Apr 26, 2014 at 6:55 PM, Jens Nockert wrote: > On 26 Apr 2014, at 18:39, Geoffroy Couprie wrote: > > Constant time code is possible in theory > > > As long as you don?t do memory accesses, branches, division, > floating-point, etc. Some x86 processors even have variable-time > multiplication. > > Writing constant-time code is essentially impossible. > Like most software problems, they're hard in the general case, but doable in specific cases. Yes, that requires taking into account cache lines, counting CPU cycles for every instruction, making sure you do not branch depending on secret information, be wary of concurrent use of the processor, and adapt all of that to the specific processor you target. Yet it has been done for some algorithms and processors. It is insanely hard, few are able to do it correctly, but it is still a worthwhile target. -------------- next part -------------- An HTML attachment was scrubbed... URL: From fw at deneb.enyo.de Sat Apr 26 10:13:42 2014 From: fw at deneb.enyo.de (Florian Weimer) Date: Sat, 26 Apr 2014 19:13:42 +0200 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: (Steve Klabnik's message of "Sat, 26 Apr 2014 06:21:52 -0700") References: <535B89E2.30608@proinbox.com> Message-ID: <87eh0k6mk9.fsf@mid.deneb.enyo.de> * Steve Klabnik: > Bugs with crypto don't often happen because of poorly implemented > primitives: they happen when you combine those primitives in bad ways. > Formal analysis doesn't help there. That's exactly where formal analysis does help. However, real-world protocols are quite difficult to model, and programmers expect interfaces which make parts of the application part of the model. From corey at octayn.net Sat Apr 26 11:46:13 2014 From: corey at octayn.net (Corey Richardson) Date: Sat, 26 Apr 2014 14:46:13 -0400 Subject: [rust-dev] This Week in Rust (26 April 2014) Message-ID: Hey all. I accidentally broke everything with a recent Ruby upgrade (I didn't have rbenv setup right), so going back to the good ole mailing list for publishing. Hello and welcome to another issue of *This Week in Rust*! [Rust](http://rust-lang.org) is a systems language pursuing the trifecta: safe, concurrent, and fast. This is a weekly summary of its progress and community. Want something mentioned? [Send me an email!](mailto:corey at octayn.net?subject=This%20Week%20in%20Rust%20Suggestion) Want to get involved? [We love contributions](https://github.com/mozilla/rust/wiki/Note-guide-for-new-contributors). This issue combines this week and last, since I was very busy with school last week, and did not have time to write. # What's cooking on master? 153 pull requests were merged in the last two weeks. ## Breaking Changes - Auto-rooting of `@` [has been removed](https://github.com/mozilla/rust/pull/13559). The exact fallout of this isn't obvious to me, but presumably this makes some uses of `@` not work. - `std::task::task` [has been renamed](https://github.com/mozilla/rust/pull/13675) to `TaskBuilder::new`. - Closures can [no longer be applied](https://github.com/mozilla/rust/pull/13686) through a `&`-pointer. This fixes some memory unsafety. - The `Round` trait [has been removed](https://github.com/mozilla/rust/pull/13597), and is now part of `Float`, and `Float` now takes things by-value. - `Unsafe` [is now always `Share`](https://github.com/mozilla/rust/pull/13583), regardless of whether or not the contained type is `Share`. - Modulo (`%` operator) on float types [has been removed](https://github.com/mozilla/rust/pull/13410), use the `rem` method instead. - `~[T]` [is no longer growable](https://github.com/mozilla/rust/pull/13588). - Some `Bitv` method names [have changed](https://github.com/mozilla/rust/pull/13572). - The `priv` keyword [is no longer used](https://github.com/mozilla/rust/pull/13547), but is still reserved. - Some cases where destructors were not run [have been fixed](https://github.com/mozilla/rust/pull/13390). - `unwrap` and `unwrap_err` on `Result` [now require the wrapper type to implement `Show`](https://github.com/mozilla/rust/pull/13479). - Some return types in `std::comm` [have been made consistent](https://github.com/mozilla/rust/pull/13448). ## Other Changes - There is now a [pure-Rust regular expression library](https://github.com/mozilla/rust/pull/13700) in the standard library. As I've come to expect from burntsushi, the docs are fantastic. - [Unix sockets](https://github.com/mozilla/rust/pull/13723) and [TCP sockets](https://github.com/mozilla/rust/pull/13688) now support accept with a timeout. [TcpStream::connect](https://github.com/mozilla/rust/pull/13604) can also take a timeout. - [64-bit Windows is now partially supported](https://github.com/mozilla/rust/pull/13692). Unwinding still doesn't work. - `&&` [is now parsed as `& &`](https://github.com/mozilla/rust/pull/13576) when appropriate. - Errors about use of moved values [are much nicer now](https://github.com/mozilla/rust/pull/13418). - Cloning vectors [is now much much faster](https://github.com/mozilla/rust/pull/13539). - SipHash [has also been optimized](https://github.com/mozilla/rust/pull/13522). - Steve Klabnik's 30 minute introduction to Rust [has been added as official documentation](https://github.com/mozilla/rust/pull/13416). ## New Contributors - Aaron Turon - Adolfo Ochagav?a - Andrew Gallant - Brandon Waskiewicz - Brendan McLoughlin - Chris Shea - Jacob Hegna - James Sanders - John Fresco - John Simon - Manish Goregaokar - Meyer S. Jacobs - Michael Fairley - Richo Healey - Ryan Mulligan - R?diger Sonderfeld - Thomas Backman - iancormac84 - mdinger # Weekly Meeting - [Two weeks ago](https://github.com/mozilla/rust/wiki/Meeting-weekly-2014-04-15), a bunch of RFCs were discussed, as well as a breaking change log. - [Last week], some more RFCs were discussed, notably the regex crate, numeric type inference, and disableable asserts. # RFCs - [Linker placement attribute](https://github.com/rust-lang/rfcs/pull/44) - [Avoiding integer overflow](https://github.com/rust-lang/rfcs/pull/45) - [Writer size hints](https://github.com/rust-lang/rfcs/pull/46) - [Revised trait matching](https://github.com/rust-lang/rfcs/pull/48) - [Disableable assertions](https://github.com/rust-lang/rfcs/pull/50) - [Macro name resolution](https://github.com/rust-lang/rfcs/pull/51) - [Private trait items](https://github.com/rust-lang/rfcs/pull/52) - [Coroutines](https://github.com/rust-lang/rfcs/pull/53) # Community Updates - For all Mac users, there is now [dash-rust](https://github.com/indirect/dash-rust/), for Rust API docs in Dash. - Another [Rust By Example](http://rustbyexample.github.io/) has been created. This one is much more complete and also looks pretty nice. - [Teepee](http://chrismorgan.info/blog/introducing-teepee.html) has been announced, the successor to `rust-http`. - [zinc](https://mail.mozilla.org/pipermail/rust-dev/2014-April/009618.html), a bare-metal Rust stack. - [An IntelliJ Rust plugin](https://github.com/Vektah/idea-rust). - [Rust for C++ Programmers](http://featherweightmusings.blogspot.co.nz/search/label/rust-for-c). - [A very fast n-queens solver](https://github.com/reem/rust-n-queens). # This Week in Servo Servo is a web browser engine written in Rust and is one of the primary test cases for the Rust language. In the last week, we landed 29 PRs. There are several very large PRs waiting to land behind an impending Rust upgrade, which will bring us April 10th. ## Notable additions - Matt Brubeck worked around a long-standing issue causing Servo to look crunched on HIDPI displays in [#2224](https://github.com/mozilla/servo/pull/2224) - Harry Maclean made `Node.Normalize()` work on all its descendants in [#2221](https://github.com/mozilla/servo/pull/2221) - jgraham cleaned up the Web Platform Tests integration in [#2216](https://github.com/mozilla/servo/pull/2216) - ms2ger, among many other things, added support for the `Any` type in dictionaries in [#2225](https://github.com/mozilla/servo/pull/2225) - Tetsuharu Ohzeki added helpers that significantly cleaned up script's layout queries in [#2210](https://github.com/mozilla/servo/pull/2210) - jdm brought back the "I tried" star for failed pages in [#2200](https://github.com/mozilla/servo/pull/2200) - Peiyong Lin implemented `Element.localName` in [#2209](https://github.com/mozilla/servo/pull/2209) - Tom Schuster implemented `ParentNode.children` in [#2192](https://github.com/mozilla/servo/pull/2192) - jdm also added a basic browser context in [#2111](https://github.com/mozilla/servo/pull/2111) - Manish Goregaokar added support for tracking the WPT manifest in [#2187](https://github.com/mozilla/servo/pull/2187) - Sankha Guria implemented `Element.prefix` in [#2199](https://github.com/mozilla/servo/pull/2199) - Bruno Abinader implemented `createDocument` in [#2072](https://github.com/mozilla/servo/pull/2072) ## New Contributors - Harry Maclean (hazz) ## Meetings and Notes In this week's [meeting](https://github.com/mozilla/servo/wiki/Meeting-2014-04-21) we went over the Rust upgrade status, some medium-sized project brainstorming we've been doing, the Web Platform Tests support in Servo, and fixing iframes. # This Week in Servo Servo is a web browser engine written in Rust and is one of the primary test cases for the Rust language. In the last week, we landed 39 PRs. ## Notable additions - Manish Goregaokar landed support of the Web Platform Tests in [#2089](https://github.com/mozilla/servo/pull/2089) - ms2ger improved the integration of WPT with our build system in [#2162](https://github.com/mozilla/servo/pull/2162) and [#2180](https://github.com/mozilla/servo/pull/2180) - Philip Horger handled treating HTTPS request as a network error in [#2166](https://github.com/mozilla/servo/pull/2166) - Peiyong Lin cleaned up some parser code in [#2157](https://github.com/mozilla/servo/pull/2157) - James Sanders associated ResourceTask with URLProvenance in [#2152](https://github.com/mozilla/servo/pull/2152) - Josh Matthews added `Traceable` and `Untraceable` types to clean up rooting in [#2147](https://github.com/mozilla/servo/pull/2147) - Lars Bergstrom changed the default rendering mode to CPU on Android [#2148](https://github.com/mozilla/servo/pull/2148) - Simon Sapin removed some unnecessary `unsafe` code in [#2145](https://github.com/mozilla/servo/pull/2145) - Matthew Brubeck fixed some terrible bugs in [#2135](https://github.com/mozilla/servo/pull/2135) and [#2134](https://github.com/mozilla/servo/pull/2134) and [#2130](https://github.com/mozilla/servo/pull/2130) - Sanhka Guria added attribute setters and getters for `HTMLImageElement` in [#2054](https://github.com/mozilla/servo/pull/2054) ## Meetings and Notes In this week's [meeting](https://github.com/mozilla/servo/wiki/Meeting-2014-04-14) we went over our Rust upgrade strategy, linking, embedding, rooting, Android support, and the commit we missed landing in one submodule for Acid2. -- http://octayn.net/ From danielmicay at gmail.com Sat Apr 26 12:44:21 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Sat, 26 Apr 2014 15:44:21 -0400 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: References: <535B89E2.30608@proinbox.com> <0E0510E8-5941-49E5-8D90-BFAC86367C21@nockert.se> Message-ID: <535C0C95.9000909@gmail.com> On 26/04/14 01:04 PM, Geoffroy Couprie wrote: > > counting CPU cycles for every instruction This isn't possible. A modern CPU has a long pipeline and the OS is also doing preemptive context switches. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From flaper87 at gmail.com Sat Apr 26 14:09:23 2014 From: flaper87 at gmail.com (Flaper87) Date: Sat, 26 Apr 2014 23:09:23 +0200 Subject: [rust-dev] This Week in Rust (26 April 2014) In-Reply-To: References: Message-ID: 2014-04-26 20:46 GMT+02:00 Corey Richardson : [snip] > > # What's cooking on master? > > 153 pull requests were merged in the last two weeks. > > ## Breaking Changes > > - Auto-rooting of `@` [has been > removed](https://github.com/mozilla/rust/pull/13559). The exact fallout > of > this isn't obvious to me, but presumably this makes some uses of `@` not > work. > The gist of this change is that there's no more special rooting for `@` pointers. Instead, `@`-pointers de-referencing basically follows the same rules as `~`-pointers do. The fallout will likely be that some usages of `@`-pointers may need explicit references to avoid lifetime issues. (See the fallout commits in the PR for more info) Hope this clears things a bit more. [snip] -- Flavio (@flaper87) Percoco http://www.flaper87.com http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From gmaxwell at gmail.com Sat Apr 26 14:42:44 2014 From: gmaxwell at gmail.com (Gregory Maxwell) Date: Sat, 26 Apr 2014 14:42:44 -0700 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: References: <535B89E2.30608@proinbox.com> Message-ID: On Sat, Apr 26, 2014 at 9:39 AM, Geoffroy Couprie wrote: > Before writing production ready crypto code, some things must be tested > carefully, like the ability to write constant time code, or a "secure" > buffer implementation (wiped before freeing it). Constant time code is > possible in theory (the Rust-crypto has an AES implementation with > precautions for that), but I do not know what could be messed up by LLVM > optimizations there. > > Still, with the possibility of dropping some assembly directly where it is > needed, it is a great platform for crypto experimentation. Even in plain C it is very hard to make any guarantees from the source code level. The C abstract machine doesn't promise how much time things take and the compiler is free to make optimizations that change the timing, though at the moment doing 'the obvious thing' for constant timeness seems to mostly not get broken by the optimizer there really are no promises, and an upgraded toolchain could change the behavior? which is especially bad because its difficult to construct reliable tests for constant-timeness. And all this before you start worrying about how the cpu pipeline might leak timing information even if all the instructions are supposed to be constant time, or the leakage from power analysis which seem impossible to close without specially constructed hardware. One of the things that is less hopeless and may inform the language spec (and library) is writing code that can keep all data structures that keep secret keys in mlocked and zeroed-after-use memory that comes along with doing crypto but which aren't the crypto themselves. From danielmicay at gmail.com Sat Apr 26 16:48:05 2014 From: danielmicay at gmail.com (Daniel Micay) Date: Sat, 26 Apr 2014 19:48:05 -0400 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: References: <535B89E2.30608@proinbox.com> Message-ID: <535C45B5.4090609@gmail.com> On 26/04/14 05:42 PM, Gregory Maxwell wrote: > > One of the things that is less hopeless and may inform the language > spec (and library) is writing code that can keep all data structures > that keep secret keys in mlocked and zeroed-after-use memory that > comes along with doing crypto but which aren't the crypto themselves. You should really just be doing it in another process at that point. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: From philippe.delrieu at free.fr Sun Apr 27 03:28:25 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Sun, 27 Apr 2014 12:28:25 +0200 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: <39BE8908-4371-416C-A856-71D3490202EA@sb.org> References: <535972DD.2010104@free.fr> <535A14DE.3060503@free.fr> <39BE8908-4371-416C-A856-71D3490202EA@sb.org> Message-ID: <535CDBC9.9070908@free.fr> I try to implement a sort of zoom UI. The UI components are organized in a tree. To update a component in the UI I use a search function (match_fn() in the example) which take a closure as search criteria and if it returns something I use an update function (test_mutable) with a closure to do the update part. The update part only need an Id and the closure. So returning the found component is not mandatory. If the search function return only a copy of the component id it solves the borrow error but I would like to have the found component. I return a reference (Option<&'a Inside>) to avoid object copy. A component can have a large sub tree. If I change and return a copy in the search function (Option) It works. Logic the Inside life time start at the Some level (as I understand). Perhaps you'll have a better idea to do this. I use this pattern (search and update function) for this reasons: * no multiple owned objects. All object are only owned in the tree. * maintain most immutability I put a new version of the test code nearer to my main code. use std::vec::Vec; use std::task; pub enum UINode { DrawableNode(Container), ContainerNode(Inside), } struct Inside { layout: fn(&Inside) -> uint, } impl Inside { fn get_id(&self) -> uint {1} } trait Trait {} struct ListInside { tt: ~Trait: Send, list: Vec<~UINode>, } struct Container { inside:~ListInside, } impl ListInside { fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option<&'a Inside>) ->Option<&'a Inside> { for inside in self.list.iter() { match (*filter)(*inside) { Some(found) => return Some(found), None => {}, }; } None } fn test_mutable<'a>(&'a mut self, id: uint, update: &'a|component: &'a mut Inside|) {} } fn TestMatchBorrow() { let task = task::task(); task.spawn (proc() { let mut viewList: Vec<~Container> = Vec::new(); for ref mut container in viewList.mut_iter() { //let &mut my_var = &mut *(container.inside); match container.inside.match_fn(&|inside: &UINode| -> Option<&Inside> {None}) { Some(inside) => container.inside.test_mutable(inside.get_id(), &|component: &mut Inside| {}), None => {}, } } }); } #[main] fn main() { TestMatchBorrow(); } From geo.couprie at gmail.com Sun Apr 27 04:16:20 2014 From: geo.couprie at gmail.com (Geoffroy Couprie) Date: Sun, 27 Apr 2014 13:16:20 +0200 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: <535C45B5.4090609@gmail.com> References: <535B89E2.30608@proinbox.com> <535C45B5.4090609@gmail.com> Message-ID: On Sun, Apr 27, 2014 at 1:48 AM, Daniel Micay wrote: > On 26/04/14 05:42 PM, Gregory Maxwell wrote: >> >> One of the things that is less hopeless and may inform the language >> spec (and library) is writing code that can keep all data structures >> that keep secret keys in mlocked and zeroed-after-use memory that >> comes along with doing crypto but which aren't the crypto themselves. > > You should really just be doing it in another process at that point. > Unfortunately, that's not a common solution, look at most webservers right now... So, because fixing timing leaks is very hard in reduced cases and impossible to do in the general case, it means that we should not even try? Do I have to worry about power analysis on a server? Can I write assembly myself to make sure the compiler will not optimize stuff away? The current solutions are not pretty and do not solve everything, but they reduce the risk. From artella.coding at googlemail.com Sun Apr 27 04:29:12 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Sun, 27 Apr 2014 12:29:12 +0100 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: <535CDBC9.9070908@free.fr> References: <535972DD.2010104@free.fr> <535A14DE.3060503@free.fr> <39BE8908-4371-416C-A856-71D3490202EA@sb.org> <535CDBC9.9070908@free.fr> Message-ID: Hi Philippe, The following modification of your code compiles. Not sure if it achieves what you want. ****************************************************************************** ****************************************************************************** use std::vec::Vec; use std::task; pub enum UINode { DrawableNode(Container), ContainerNode(Inside), } struct Inside { layout: fn(&Inside) -> uint, } impl Inside { fn get_id(&self) -> uint {1} } trait Trait {} struct ListInside { tt: ~Trait: Send, list: Vec<~UINode>, } struct Container { inside:~ListInside, } impl ListInside { fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option<&'a Inside>) ->Option<&'a Inside> { for inside in self.list.iter() { match (*filter)(*inside) { Some(found) => return Some(found), None => {}, }; } None } fn test_mutable<'a>(&'a mut self, id: uint, update: &'a|component: &'a mut Inside|) {} } fn TestMatchBorrow() { let task = task::task(); task.spawn (proc() { let mut viewList: Vec<~Container> = Vec::new(); for ref mut container in viewList.mut_iter() { /* //Original code //let &mut my_var = &mut *(container.inside); match container.inside.match_fn(&|inside: &UINode| -> Option<&Inside> {None}) { Some(inside) => container.inside.test_mutable(inside.get_id(), &|component: &mut Inside| {}), None => {}, } */ //modified code let mut dotest = false; fn dummy(arg: &Inside) -> uint { 1 } let mut ins: Inside = Inside {layout:dummy}; match container.inside.match_fn(&|uinside: &UINode| -> Option<&Inside> {None}) { Some(inside) => { dotest = true; ins= *inside;} None => {}, } if(dotest == true){ container.inside.test_mutable(ins.get_id(), &|component: &mut Inside| {}); } } }); } #[main] fn main() { TestMatchBorrow(); } ****************************************************************************** ****************************************************************************** On Sun, Apr 27, 2014 at 11:28 AM, Philippe Delrieu wrote: > I try to implement a sort of zoom UI. The UI components are organized in a > tree. To update a component in the UI I use a search function (match_fn() > in the example) which take a closure as search criteria and if it returns > something I use an update function (test_mutable) with a closure to do the > update part. The update part only need an Id and the closure. So returning > the found component is not mandatory. If the search function return only a > copy of the component id it solves the borrow error but I would like to > have the found component. > > I return a reference (Option<&'a Inside>) to avoid object copy. A > component can have a large sub tree. If I change and return a copy in the > search function (Option) It works. Logic the Inside life time start > at the Some level (as I understand). > > Perhaps you'll have a better idea to do this. I use this pattern (search > and update function) for this reasons: > * no multiple owned objects. All object are only owned in the tree. > * maintain most immutability > > I put a new version of the test code nearer to my main code. > > > use std::vec::Vec; > use std::task; > > pub enum UINode { > DrawableNode(Container), > ContainerNode(Inside), > } > > struct Inside { > layout: fn(&Inside) -> uint, > } > > impl Inside { > fn get_id(&self) -> uint {1} > } > > trait Trait {} > > struct ListInside { > tt: ~Trait: Send, > list: Vec<~UINode>, > } > > struct Container { > inside:~ListInside, > } > > impl ListInside { > fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option<&'a > Inside>) ->Option<&'a Inside> { > for inside in self.list.iter() { > match (*filter)(*inside) { > Some(found) => return Some(found), > None => {}, > }; > } > None > } > > fn test_mutable<'a>(&'a mut self, id: uint, update: &'a|component: &'a > mut Inside|) {} > } > > fn TestMatchBorrow() { > let task = task::task(); > task.spawn (proc() { > > let mut viewList: Vec<~Container> = Vec::new(); > > for ref mut container in viewList.mut_iter() { > //let &mut my_var = &mut *(container.inside); > match container.inside.match_fn(&|inside: &UINode| -> > Option<&Inside> {None}) { > Some(inside) => container.inside.test_mutable(inside.get_id(), > &|component: &mut Inside| {}), > None => {}, > } > } > }); > > > } > > #[main] > fn main() { > TestMatchBorrow(); > } > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From philippe.delrieu at free.fr Sun Apr 27 09:59:48 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Sun, 27 Apr 2014 18:59:48 +0200 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: References: <535972DD.2010104@free.fr> <535A14DE.3060503@free.fr> <39BE8908-4371-416C-A856-71D3490202EA@sb.org> <535CDBC9.9070908@free.fr> Message-ID: <535D3784.9000103@free.fr> Thank you for your help. It the same as returning a copy of Inside during the last return call of the search function. I think I'll change the search function to return an id (simple to copy) and provide another function that take an id and return a copy of the component without the component sub tree in case of the component data is needed. Philippe Le 27/04/2014 13:29, Artella Coding a ?crit : > Hi Philippe, > > The following modification of your code compiles. Not sure if it > achieves what you want. > > ****************************************************************************** > ****************************************************************************** > > use std::vec::Vec; > use std::task; > > pub enum UINode { > DrawableNode(Container), > ContainerNode(Inside), > } > > struct Inside { > layout: fn(&Inside) -> uint, > } > > impl Inside { > fn get_id(&self) -> uint {1} > } > > trait Trait {} > > struct ListInside { > tt: ~Trait: Send, > list: Vec<~UINode>, > } > > struct Container { > inside:~ListInside, > } > > impl ListInside { > fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option<&'a > Inside>) ->Option<&'a Inside> { > for inside in self.list.iter() { > match (*filter)(*inside) { > Some(found) => return Some(found), > None => {}, > }; > } > None > } > > fn test_mutable<'a>(&'a mut self, id: uint, update: &'a|component: > &'a mut Inside|) {} > } > > fn TestMatchBorrow() { > let task = task::task(); > task.spawn (proc() { > > let mut viewList: Vec<~Container> = Vec::new(); > > for ref mut container in viewList.mut_iter() { > /* > //Original code > //let &mut my_var = &mut *(container.inside); > match container.inside.match_fn(&|inside: &UINode| -> > Option<&Inside> {None}) { > Some(inside) => > container.inside.test_mutable(inside.get_id(), &|component: &mut Inside| > {}), > None => {}, > } > */ > > //modified code > let mut dotest = false; > fn dummy(arg: &Inside) -> uint { > 1 > } > let mut ins: Inside = Inside {layout:dummy}; > match container.inside.match_fn(&|uinside: &UINode| -> > Option<&Inside> {None}) { > Some(inside) => { dotest = true; ins= *inside;} > None => {}, > } > if(dotest == true){ > container.inside.test_mutable(ins.get_id(), > &|component: &mut Inside| {}); > } > > } > }); > > } > > #[main] > fn main() { > TestMatchBorrow(); > } > > ****************************************************************************** > ****************************************************************************** > > > > On Sun, Apr 27, 2014 at 11:28 AM, Philippe Delrieu > > wrote: > > I try to implement a sort of zoom UI. The UI components are > organized in a tree. To update a component in the UI I use a > search function (match_fn() in the example) which take a closure > as search criteria and if it returns something I use an update > function (test_mutable) with a closure to do the update part. The > update part only need an Id and the closure. So returning the > found component is not mandatory. If the search function return > only a copy of the component id it solves the borrow error but I > would like to have the found component. > > I return a reference (Option<&'a Inside>) to avoid object copy. A > component can have a large sub tree. If I change and return a copy > in the search function (Option) It works. Logic the Inside > life time start at the Some level (as I understand). > > Perhaps you'll have a better idea to do this. I use this pattern > (search and update function) for this reasons: > * no multiple owned objects. All object are only owned in the tree. > * maintain most immutability > > I put a new version of the test code nearer to my main code. > > > use std::vec::Vec; > use std::task; > > pub enum UINode { > DrawableNode(Container), > ContainerNode(Inside), > } > > struct Inside { > layout: fn(&Inside) -> uint, > } > > impl Inside { > fn get_id(&self) -> uint {1} > } > > trait Trait {} > > struct ListInside { > tt: ~Trait: Send, > list: Vec<~UINode>, > } > > struct Container { > inside:~ListInside, > } > > impl ListInside { > fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> > Option<&'a Inside>) ->Option<&'a Inside> { > for inside in self.list.iter() { > match (*filter)(*inside) { > Some(found) => return Some(found), > None => {}, > }; > } > None > } > > fn test_mutable<'a>(&'a mut self, id: uint, update: > &'a|component: &'a mut Inside|) {} > } > > fn TestMatchBorrow() { > let task = task::task(); > task.spawn (proc() { > > let mut viewList: Vec<~Container> = Vec::new(); > > for ref mut container in viewList.mut_iter() { > //let &mut my_var = &mut *(container.inside); > match container.inside.match_fn(&|inside: &UINode| -> > Option<&Inside> {None}) { > Some(inside) => > container.inside.test_mutable(inside.get_id(), &|component: &mut > Inside| {}), > None => {}, > } > } > }); > > > } > > #[main] > fn main() { > TestMatchBorrow(); > } > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bill_myers at outlook.com Sun Apr 27 13:41:27 2014 From: bill_myers at outlook.com (Bill Myers) Date: Sun, 27 Apr 2014 20:41:27 +0000 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: References: <535B89E2.30608@proinbox.com>, , , <0E0510E8-5941-49E5-8D90-BFAC86367C21@nockert.se>, Message-ID: There is nothing hard about it, assuming you are using a decent language. Just add a Crypto type that wraps integers and booleans and that doesn't allow any non-constant time operations nor implicit conversion to anything that is not Crypto (which of course means you can't index memory or do branches based on it). If the optimizer can screw up things, implement the Crypto operations in assembly. From bascule at gmail.com Sun Apr 27 14:14:53 2014 From: bascule at gmail.com (Tony Arcieri) Date: Sun, 27 Apr 2014 14:14:53 -0700 Subject: [rust-dev] Cryptol, the language of cryptography In-Reply-To: <535B89E2.30608@proinbox.com> References: <535B89E2.30608@proinbox.com> Message-ID: On Sat, Apr 26, 2014 at 3:26 AM, John Mija wrote: > In summary, Cryptol helps to implement existing known crypto algorithms > correctly, but also to design new crypto algorithms. > Cryptol isn't some kind of magic silver bullet for implementing crypto correctly. While it can help keep crypto implementations closer to their mathematical descriptions, and help formally verify them, that's only half the battle. So, please review the inclusion of crypto. library in the standard lib. As far as I'm concerned, Cryptol changes nothing when it comes to including crypto in Rust's standard library. For starters, Cryptol seems to be something of a self-contained crypto ecosystem, and it's not clear at least to me how it can be applied to verifying crypto implementations in other languages. Even if it could, crypto implementations still need to be verified by security auditors, preferably by multiple, independent auditors. Having crypto in the standard library limits agility around shipping security updates, since now you must update the entire standard library, and not just one library. -- Tony Arcieri -------------- next part -------------- An HTML attachment was scrubbed... URL: From japaric at linux.com Sun Apr 27 14:28:56 2014 From: japaric at linux.com (Jorge Aparicio) Date: Sun, 27 Apr 2014 16:28:56 -0500 Subject: [rust-dev] Rust by example In-Reply-To: References: <20140426022513.GA5314@ideapad.lan> <20140426045720.GE5314@ideapad.lan> Message-ID: <20140427212856.GD627@ideapad.lan> Everyone, I got contacted by Jonathan [1] and he offered me the (rustbyexample.com) domain name, which I have taken. And now Rust by Example is available at (http://rustbyexample.com)! Furthermore, I'm now keeping both the source code (master branch) and the built site (gh-pages branch) at my rust-by-example repo [2]. So, if you are watching that repo, you'll get notified of updates to built site. Cheers, Jorge Aparicio [1] https://github.com/titanous [2] https://github.com/japaric/rust-by-example From axel.viala at darnuria.eu Sun Apr 27 17:29:54 2014 From: axel.viala at darnuria.eu (Axel Viala) Date: Mon, 28 Apr 2014 02:29:54 +0200 Subject: [rust-dev] Rust meetup Paris #04: Special Servo Message-ID: <535DA102.7070604@darnuria.eu> Hii! This time we will try to focus on servo. By making a little informal presentation for the project. And hopefully trying to improve it! Important informations here: https://reps.mozilla.org/e/meetup-rust-paris-04/ Inscriptions: https://etherpad.mozilla.org/remo-meetup-rust-paris-04 Thanks! @pnkfelix, nical: I forgot something? :) From philippe.delrieu at free.fr Mon Apr 28 11:25:35 2014 From: philippe.delrieu at free.fr (Philippe Delrieu) Date: Mon, 28 Apr 2014 20:25:35 +0200 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: <535D3784.9000103@free.fr> References: <535972DD.2010104@free.fr> <535A14DE.3060503@free.fr> <39BE8908-4371-416C-A856-71D3490202EA@sb.org> <535CDBC9.9070908@free.fr> <535D3784.9000103@free.fr> Message-ID: <535E9D1F.7040400@free.fr> Hello, I've updated my sample code to reflect what I'll do in my main program. I put it back on the list because it can help as a pattern to manage a tree of polymorph object. It compile and works. I have some question too because I'm not sure I've done it the right way: * I cross the tree recursively and return Option in each call. To manage recursion I put the call in a match and end with this sort of boilerplate code: match obj.call_fn_recusive() { Some(ret) => {return Some(ret);}, None => {}, } Is there a way to avoid this line: Some(ret) => {return Some(ret);}, * It's very hard to manage reference and borrowing of object. I spend some time to make it compile and change my algorithm several time. That's why I think examples and patterns can be very useful because you can't do what you want in rust. In other works there is no easy shortcut, you have to find the right way. * closure indentation. Is there a good way to indent closure in function call to make it readable easily. It's very hard to find the begin/end of the closure code from the function and match call (see code). Some world about the pattern : I use an enum to define a type that manage all my polymorph object (enum UINode). It's the simplest way I found to have a collection a different objects that implement part of the same trait. I don't want to use unsafe code and low memory management. Perhaps there is a better pattern. The object can only be retrieve or modified with search function that use a closure to do the job. It's work well to avoid to know how the tree is organized and to avoid object reference outside the tree. The mutable part is restricted to one function too. The code: use std::vec::Vec; pub enum UINode { DrawableNode(Inside), ContainerNode(ListInside), } //common trait for all object trait Component { fn get_width(&self) -> uint; fn get_id(&self) -> uint; } //first struct. derive clone because it can be return as a copy. //base component. #[deriving(Clone)] pub struct Inside { id: uint, width: uint, } impl Component for Inside{ fn get_id(&self) -> uint {self.id} fn get_width(&self) -> uint { self.width } } //the container that is a component and a container of components. pub struct ListInside { id: uint, width: uint, list: Vec<~UINode>, } impl Component for ListInside{ fn get_id(&self) -> uint {self.id} fn get_width(&self) -> uint { self.width } } //some container function and the search and modify function. impl ListInside { fn addInside(&mut self, inside: Inside) { self.list.push(~DrawableNode(inside)); } fn addList(&mut self, list: ListInside) { self.list.push(~ContainerNode(list)); } // search for a UINode using the closure filter to find the right. Return the node Id. fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option) ->Option { for inside in self.list.iter() { match (*filter)(*inside) { Some(found) => return Some(found), None => {}, }; //try on sub tree match **inside { DrawableNode(_) => {}, ContainerNode(ref list_inside) => { match list_inside.match_fn(filter) { Some(ret) => {return Some(ret);} None => {} } }, } } None } //modify using the specified closure the Component with specified id. fn test_mutable<'a>(&'a mut self, id: uint, update: &'a|&'a mut Inside|) { for node in self.list.mut_iter() { match **node { DrawableNode(ref mut inside) => {if inside.get_id() == id {(*update)(inside)}}, ContainerNode(ref mut list_inside) => list_inside.test_mutable(id, update), } } } //return a copy of the Component with specified id. Doesn't return container, only Inside. fn search_node<'a>(&'a self, id: uint) -> Option<~Component> { for node in self.list.iter() { match **node { DrawableNode(ref inside) => if inside.get_id() == id { return Some((~inside.clone()) as ~Component);}, ContainerNode(ref list_inside) => { match list_inside.search_node(id) { Some(elem) => {return Some(elem);}, None => {}, }}, } } None } } fn TestTreeSearchModify() { let mut list_inside = ListInside{ id: 0, width: 10, list: Vec::new(), }; let mut list2 = ListInside{ id: 3, width: 30, list: Vec::new(), }; let inside1 = Inside { id: 1, width: 21, }; let inside2 = Inside { id: 2, width: 22, }; list_inside.addInside(inside1); list2.addInside(inside2); list_inside.addList(list2); let search_id = 2; let new_width:uint = 122u; match list_inside.match_fn(&|inside: &UINode| -> Option { println!("Inside match closure node:{:?}", inside); match *inside { //search for id 2; DrawableNode(ref inside) => if inside.get_id() == search_id { return Some(inside.get_id());}, ContainerNode(ref list_inside) => if list_inside.get_id() == search_id { return Some(list_inside.get_id());}, } None }) { Some(found_id) => { match list_inside.search_node(found_id) { Some(compo) => println!("Found component with id {0} and width {1}", compo.get_id(), compo.get_width()), None => {println!("Search_node deosn't work first");} }; list_inside.test_mutable(found_id, &|component: &mut Inside| { component.width = new_width; }); match list_inside.search_node(found_id) { Some(compo) => println!("Found updated component with id {0} and width {1}", compo.get_id(), compo.get_width()), None => {println!("Search_node deosn't work bis");} }; }, None => {println!("Match_fn deosn't work first");}, } } #[main] fn main() { TestMatchBorrow(); } Philippe From artella.coding at googlemail.com Mon Apr 28 12:18:42 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Mon, 28 Apr 2014 20:18:42 +0100 Subject: [rust-dev] Error: cannot borrow `***test` as mutable because it is also borrowed as immutable in match In-Reply-To: <535E9D1F.7040400@free.fr> References: <535972DD.2010104@free.fr> <535A14DE.3060503@free.fr> <39BE8908-4371-416C-A856-71D3490202EA@sb.org> <535CDBC9.9070908@free.fr> <535D3784.9000103@free.fr> <535E9D1F.7040400@free.fr> Message-ID: Regarding your question : "Is there a way to avoid this line: Some(ret) => {return Some(ret);}," You could do : **************************************** fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option) ->Option { let mut result: Option = None; for inside in self.list.iter() { match (*filter)(*inside) { Some(found) => {result = Some(found); break;}, None => {}, }; //try on sub tree match **inside { DrawableNode(_) => {}, ContainerNode(ref list_inside) => { match list_inside.match_fn(filter) { Some(ret) => {result = Some(ret); break;} None => {} } }, } } result } **************************************** The "break" ensures that as soon as a result is found, the for loop is exited. On Mon, Apr 28, 2014 at 7:25 PM, Philippe Delrieu wrote: > Hello, > > I've updated my sample code to reflect what I'll do in my main program. I > put it back on the list because it can help as a pattern to manage a tree > of polymorph object. > It compile and works. > I have some question too because I'm not sure I've done it the right way: > * I cross the tree recursively and return Option in each call. To > manage recursion I put the call in a match and end with this sort of > boilerplate code: > match obj.call_fn_recusive() { > Some(ret) => {return Some(ret);}, > None => {}, > } > Is there a way to avoid this line: Some(ret) => {return > Some(ret);}, > * It's very hard to manage reference and borrowing of object. I spend > some time to make it compile and change my algorithm several time. That's > why I think examples and patterns can be very useful because you can't do > what you want in rust. In other works there is no easy shortcut, you have > to find the right way. > * closure indentation. Is there a good way to indent closure in function > call to make it readable easily. It's very hard to find the begin/end of > the closure code from the function and match call (see code). > > Some world about the pattern : > I use an enum to define a type that manage all my polymorph object (enum > UINode). It's the simplest way I found to have a collection a different > objects that implement part of the same trait. I don't want to use unsafe > code and low memory management. Perhaps there is a better pattern. > The object can only be retrieve or modified with search function that use > a closure to do the job. It's work well to avoid to know how the tree is > organized and to avoid object reference outside the tree. The mutable part > is restricted to one function too. > > The code: > > use std::vec::Vec; > > pub enum UINode { > DrawableNode(Inside), > ContainerNode(ListInside), > } > > //common trait for all object > trait Component { > fn get_width(&self) -> uint; > fn get_id(&self) -> uint; > } > > //first struct. derive clone because it can be return as a copy. > //base component. > #[deriving(Clone)] > pub struct Inside { > id: uint, > width: uint, > } > > impl Component for Inside{ > fn get_id(&self) -> uint {self.id} > fn get_width(&self) -> uint { > self.width > } > } > > //the container that is a component and a container of components. > pub struct ListInside { > id: uint, > width: uint, > list: Vec<~UINode>, > } > > > impl Component for ListInside{ > fn get_id(&self) -> uint {self.id} > fn get_width(&self) -> uint { > self.width > } > } > > //some container function and the search and modify function. > impl ListInside { > fn addInside(&mut self, inside: Inside) { > self.list.push(~DrawableNode(inside)); > } > > fn addList(&mut self, list: ListInside) { > self.list.push(~ContainerNode(list)); > } > > // search for a UINode using the closure filter to find the right. > Return the node Id. > fn match_fn<'a>(&'a self, filter: &'a |&'a UINode| -> Option) > ->Option { > > for inside in self.list.iter() { > match (*filter)(*inside) { > Some(found) => return Some(found), > None => {}, > }; > //try on sub tree > match **inside { > DrawableNode(_) => {}, > ContainerNode(ref list_inside) => { > match list_inside.match_fn(filter) { > Some(ret) => {return Some(ret);} > None => {} > } > }, > } > } > None > } > > //modify using the specified closure the Component with specified id. > fn test_mutable<'a>(&'a mut self, id: uint, update: &'a|&'a mut > Inside|) { > for node in self.list.mut_iter() { > match **node { > DrawableNode(ref mut inside) => {if inside.get_id() == id > {(*update)(inside)}}, > ContainerNode(ref mut list_inside) => > list_inside.test_mutable(id, update), > } > } > } > > //return a copy of the Component with specified id. Doesn't return > container, only Inside. > fn search_node<'a>(&'a self, id: uint) -> Option<~Component> { > for node in self.list.iter() { > match **node { > DrawableNode(ref inside) => if inside.get_id() == id { > return Some((~inside.clone()) as ~Component);}, > ContainerNode(ref list_inside) => { match > list_inside.search_node(id) { > Some(elem) => {return Some(elem);}, > None => {}, > }}, > } > } > None > } > } > > fn TestTreeSearchModify() { > let mut list_inside = ListInside{ > id: 0, > width: 10, > list: Vec::new(), > }; > > let mut list2 = ListInside{ > id: 3, > width: 30, > list: Vec::new(), > }; > > let inside1 = Inside { > id: 1, > width: 21, > }; > > let inside2 = Inside { > id: 2, > width: 22, > }; > > list_inside.addInside(inside1); > list2.addInside(inside2); > list_inside.addList(list2); > > let search_id = 2; > let new_width:uint = 122u; > > match list_inside.match_fn(&|inside: &UINode| -> Option { > println!("Inside match closure node:{:?}", inside); > match *inside { //search for id 2; > DrawableNode(ref inside) => if inside.get_id() == search_id { > return Some(inside.get_id());}, > ContainerNode(ref list_inside) => if list_inside.get_id() == > search_id { return Some(list_inside.get_id());}, > } > None > > }) { > Some(found_id) => { > match list_inside.search_node(found_id) { > Some(compo) => println!("Found component with id {0} and > width {1}", compo.get_id(), compo.get_width()), > None => {println!("Search_node deosn't work first");} > }; > list_inside.test_mutable(found_id, &|component: &mut Inside| { > component.width = new_width; > }); > match list_inside.search_node(found_id) { > Some(compo) => println!("Found updated component with id > {0} and width {1}", compo.get_id(), compo.get_width()), > None => {println!("Search_node deosn't work bis");} > }; > }, > None => {println!("Match_fn deosn't work first");}, > > } > } > > #[main] > fn main() { > TestMatchBorrow(); > } > > > Philippe > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hastebrot at gmail.com Mon Apr 28 17:23:14 2014 From: hastebrot at gmail.com (Benjamin Gudehus) Date: Tue, 29 Apr 2014 02:23:14 +0200 Subject: [rust-dev] Make use of the LLVM ExecutionEngine Message-ID: Hi! Will there be a way to make usage of ExecutionEngine and call LLVM functions via a TypeRef to them? I saw there is even a LLVMDisposeExecutionEngine in rustc::lib::llvm::llvm. pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef); --Benjamin -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Mon Apr 28 17:49:56 2014 From: alex at crichton.co (Alex Crichton) Date: Mon, 28 Apr 2014 17:49:56 -0700 Subject: [rust-dev] Make use of the LLVM ExecutionEngine In-Reply-To: References: Message-ID: This used to be present for the JIT support that the old rusti provided, but the internal support for this has been removed. You may be able to resurrect it outside the compiler with these LLVM apis, but it may also require exposing more LLVM details from the compiler itself. There is currently no plan to bring a rust interpreter back before 1.0 On Mon, Apr 28, 2014 at 5:23 PM, Benjamin Gudehus wrote: > Hi! > > Will there be a way to make usage of ExecutionEngine and call LLVM functions > via a TypeRef to them? > > I saw there is even a LLVMDisposeExecutionEngine in rustc::lib::llvm::llvm. > > pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef); > > --Benjamin > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From hastebrot at gmail.com Mon Apr 28 18:15:20 2014 From: hastebrot at gmail.com (Benjamin Gudehus) Date: Tue, 29 Apr 2014 03:15:20 +0200 Subject: [rust-dev] Make use of the LLVM ExecutionEngine In-Reply-To: References: Message-ID: Hi Alex! Thanks for the answer. I see it was removed in [1]. There once was llvm::LLVMRustBuildJIT() [2] to create an ExecutionEngine. Hopefully there will be plans to provide a complete binding for LLVM in Rust, a convenient object-oriented API for usage of LLVM (like llvm-py) and a Rust REPL [3] after 1.0. :D [1] https://github.com/mozilla/rust/issues/9818 [2] https://github.com/mozilla/rust/blob/c92f2168d4/src/librustc/back/link.rs#L144 [3] https://github.com/mozilla/rust/issues/9898 --Benjamin On Tue, Apr 29, 2014 at 2:49 AM, Alex Crichton wrote: > This used to be present for the JIT support that the old rusti > provided, but the internal support for this has been removed. You may > be able to resurrect it outside the compiler with these LLVM apis, but > it may also require exposing more LLVM details from the compiler > itself. > > There is currently no plan to bring a rust interpreter back before 1.0 > > On Mon, Apr 28, 2014 at 5:23 PM, Benjamin Gudehus > wrote: > > Hi! > > > > Will there be a way to make usage of ExecutionEngine and call LLVM > functions > > via a TypeRef to them? > > > > I saw there is even a LLVMDisposeExecutionEngine in > rustc::lib::llvm::llvm. > > > > pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef); > > > > --Benjamin > > > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hastebrot at gmail.com Mon Apr 28 18:39:31 2014 From: hastebrot at gmail.com (Benjamin Gudehus) Date: Tue, 29 Apr 2014 03:39:31 +0200 Subject: [rust-dev] Make use of the LLVM ExecutionEngine In-Reply-To: References: Message-ID: Is it possible to link to the missing LLVM methods from a custom rust file by defining the external methods? The external LLVM methods are linked with `#[link(name = "rustllvm", kind = "static")]` in librustc and I suppose that LLVM is linked statically into the rustc library, e.g. rustc.dll (on Windows). And since `llvm/ExecutionEngine/JIT.h` is included in `rustllvm.h` I suppose that this method is also available in rustc.dll. On Tue, Apr 29, 2014 at 3:15 AM, Benjamin Gudehus wrote: > Hi Alex! > > Thanks for the answer. I see it was removed in [1]. There once was > llvm::LLVMRustBuildJIT() [2] to create an ExecutionEngine. > > Hopefully there will be plans to provide a complete binding for LLVM in > Rust, a convenient > object-oriented API for usage of LLVM (like llvm-py) and a Rust REPL [3] > after 1.0. :D > > [1] https://github.com/mozilla/rust/issues/9818 > [2] > https://github.com/mozilla/rust/blob/c92f2168d4/src/librustc/back/link.rs#L144 > [3] https://github.com/mozilla/rust/issues/9898 > > --Benjamin > > > > On Tue, Apr 29, 2014 at 2:49 AM, Alex Crichton wrote: > >> This used to be present for the JIT support that the old rusti >> provided, but the internal support for this has been removed. You may >> be able to resurrect it outside the compiler with these LLVM apis, but >> it may also require exposing more LLVM details from the compiler >> itself. >> >> There is currently no plan to bring a rust interpreter back before 1.0 >> >> On Mon, Apr 28, 2014 at 5:23 PM, Benjamin Gudehus >> wrote: >> > Hi! >> > >> > Will there be a way to make usage of ExecutionEngine and call LLVM >> functions >> > via a TypeRef to them? >> > >> > I saw there is even a LLVMDisposeExecutionEngine in >> rustc::lib::llvm::llvm. >> > >> > pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef); >> > >> > --Benjamin >> > >> > >> > _______________________________________________ >> > Rust-dev mailing list >> > Rust-dev at mozilla.org >> > https://mail.mozilla.org/listinfo/rust-dev >> > >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mneumann at ntecs.de Tue Apr 29 11:27:39 2014 From: mneumann at ntecs.de (Michael Neumann) Date: Tue, 29 Apr 2014 20:27:39 +0200 Subject: [rust-dev] PipeStream.by_ref() - Multiple applicable methods problem Message-ID: <535FEF1B.908@ntecs.de> Hi, I don't know how to figure out calling by_ref() for a PipeStream: use std::io::Process; use std::io::BufferedReader; fn main() { let mut child = match Process::new("/usr/bin/xzcat", ["test.log.xz".to_owned()]) { Ok(child) => child, Err(e) => fail!("failed to execute child: {}", e), }; let inp = child.stdout.get_mut_ref(); // ERROR occurs here let mut rdr = BufferedReader::new(inp.by_ref()); for line in rdr.lines() { print!("{}", line.unwrap()); } assert!(child.wait().success()); } This is the error output: test.rs:13:37: 13:49 error: multiple applicable methods in scope test.rs:13 let mut rdr = BufferedReader::new(inp.by_ref()); ^~~~~~~~~~~~ test.rs:13:37: 13:49 note: candidate #1 is `std::io::Writer::by_ref` test.rs:13 let mut rdr = BufferedReader::new(inp.by_ref()); ^~~~~~~~~~~~ test.rs:13:37: 13:49 note: candidate #2 is `std::io::Reader::by_ref` test.rs:13 let mut rdr = BufferedReader::new(inp.by_ref()); ^~~~~~~~~~~~ test.rs:13:17: 13:36 error: failed to find an implementation of trait std::io::Reader for std::io::RefWriter<,std::io::pipe::PipeStream> test.rs:13 let mut rdr = BufferedReader::new(inp.by_ref()); ^~~~~~~~~~~~~~~~~~~ Any hints? Actually what I want to accomplish is to iterate line by line over a PipeStream. Regards, Michael From alex at crichton.co Tue Apr 29 13:51:22 2014 From: alex at crichton.co (Alex Crichton) Date: Tue, 29 Apr 2014 13:51:22 -0700 Subject: [rust-dev] PipeStream.by_ref() - Multiple applicable methods problem In-Reply-To: <535FEF1B.908@ntecs.de> References: <535FEF1B.908@ntecs.de> Message-ID: The by_ref() method exists on both the Reader and the Writer trait, and you're working with a stream which implements both Reader and Writer (hence the confusion by the compiler). You could work around it with something like: fn rdr<'a, T: Reader>(t: &'a mut T) -> RefReader<'a, T> { t.by_ref() } Eventually, with UFCS, you'll be able to do something like: let rdr = Reader::by_ref(&mut inp); (hopefully soon!) From banderson at mozilla.com Tue Apr 29 17:15:21 2014 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 29 Apr 2014 17:15:21 -0700 Subject: [rust-dev] New moderation policy Message-ID: <53604099.9020600@mozilla.com> Hey! This is a new section for our development policy covering moderation guidelines. It tells both community members and moderators the mechanics of when and how a conversation should be moderated. This involves no changes to the Rust Code of Conduct; it is making explicit the informal process that is already in place for dealing with violations. It is posted on the wiki: https://github.com/mozilla/rust/wiki/Note-development-policy#moderation ## Moderation These are the policies for upholding our community's standards of conduct in our communication channels, most notably in Rust-related IRC channels. 1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) 2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. 3. Moderators will first respond to such remarks with a warning. 4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. 5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. 6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. 7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. 8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. And if someone takes issue you with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better ? remember that it's your responsibility to make your fellow Rustians comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. *Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling)* From rustphil at phildawes.net Wed Apr 30 00:00:29 2014 From: rustphil at phildawes.net (Phil Dawes) Date: Wed, 30 Apr 2014 08:00:29 +0100 Subject: [rust-dev] rust block comments Message-ID: Hello! Could somebody clarify the block comments structure in rust please? The manual says 'Comments in Rust code follow the general C++ style of line and block-comment forms, with no nesting of block-comment delimiters.' http://static.rust-lang.org/doc/master/rust.html#comments However the grammar looks like it parses nesting of block comment delimiters, and e.g. the following compiles: fn main() { /* /* */ */ println!("YEAH!"); } Is the manual wrong or have I mis-understood it? (racer performs comment cleaning which is why I'm interested) Thanks, Phil -------------- next part -------------- An HTML attachment was scrubbed... URL: From noamraph at gmail.com Wed Apr 30 00:33:11 2014 From: noamraph at gmail.com (Noam Yorav-Raphael) Date: Wed, 30 Apr 2014 10:33:11 +0300 Subject: [rust-dev] Another idea on requiring "mut" prefix at call site Message-ID: Hi, I had a bug caused by a function mutating its arguments, and it had occurred to me that it may be a good idea if rust would require a "mut" prefix in that case. I asked on reddit, and was referred to this thread: https://mail.mozilla.org/pipermail/rust-dev/2014-January/007670.html In the above message, Patrick shows a few examples which show that it's hard to come up with rules on which arguments should be prefixed by "mut" that will be sound and complete. I have an idea which may be. The idea is to not look at function arguments but at uses of a variable. Here's a rule: Whenever a variable which was declared with "let mut" is being used in a way that would have been illegal have it not been declared with "let mut", it should be prefixed by "mut", unless it's obvious from the context that it has to be mutable. I think it's quite simple and says exactly what should be the rules in Patrick's examples. What's not well-defined is the "obvious from the context" part. Certainly when a variable is on the left hand side of an assignment there would be no need for "mut" annotation, as well as when it's being prefixed by "&mut". I don't know if there are other cases. (If you're interested in the bug: I had to use a function solve(A, b) which gets a matrix A and a vector b and returns a vector x such that Ax=b. It does Gauss elimination, and for efficiency it modified A and b instead of allocating new arrays. I used it like x = solve(A, b) and then used A again. It was in Fortran, so the arguments A and b were annotated as being "in out", but of course it didn't stop my perfectly looking function from having a hidden bug.) What do you think? Noam -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Wed Apr 30 01:28:49 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Wed, 30 Apr 2014 09:28:49 +0100 Subject: [rust-dev] Another idea on requiring "mut" prefix at call site In-Reply-To: References: Message-ID: Hi, do you have a link to the reddit article, so I can have a read? Thanks On Wed, Apr 30, 2014 at 8:33 AM, Noam Yorav-Raphael wrote: > Hi, > > I had a bug caused by a function mutating its arguments, and it had > occurred to me that it may be a good idea if rust would require a "mut" > prefix in that case. I asked on reddit, and was referred to this thread: > https://mail.mozilla.org/pipermail/rust-dev/2014-January/007670.html > > In the above message, Patrick shows a few examples which show that it's > hard to come up with rules on which arguments should be prefixed by "mut" > that will be sound and complete. I have an idea which may be. The idea is > to not look at function arguments but at uses of a variable. Here's a rule: > > Whenever a variable which was declared with "let mut" is being used in a > way that would have been illegal have it not been declared with "let mut", > it should be prefixed by "mut", unless it's obvious from the context that > it has to be mutable. > > I think it's quite simple and says exactly what should be the rules in > Patrick's examples. What's not well-defined is the "obvious from the > context" part. Certainly when a variable is on the left hand side of an > assignment there would be no need for "mut" annotation, as well as when > it's being prefixed by "&mut". I don't know if there are other cases. > > (If you're interested in the bug: I had to use a function solve(A, b) > which gets a matrix A and a vector b and returns a vector x such that Ax=b. > It does Gauss elimination, and for efficiency it modified A and b instead > of allocating new arrays. I used it like x = solve(A, b) and then used A > again. It was in Fortran, so the arguments A and b were annotated as being > "in out", but of course it didn't stop my perfectly looking function from > having a hidden bug.) > > What do you think? > Noam > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Wed Apr 30 01:34:31 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Wed, 30 Apr 2014 09:34:31 +0100 Subject: [rust-dev] Another idea on requiring "mut" prefix at call site In-Reply-To: References: Message-ID: Ah think I found it : http://www.reddit.com/r/rust/comments/24afw8/would_it_be_a_good_idea_to_require_mut_when/ On Wed, Apr 30, 2014 at 9:28 AM, Artella Coding < artella.coding at googlemail.com> wrote: > Hi, do you have a link to the reddit article, so I can have a read? Thanks > > > On Wed, Apr 30, 2014 at 8:33 AM, Noam Yorav-Raphael wrote: > >> Hi, >> >> I had a bug caused by a function mutating its arguments, and it had >> occurred to me that it may be a good idea if rust would require a "mut" >> prefix in that case. I asked on reddit, and was referred to this thread: >> https://mail.mozilla.org/pipermail/rust-dev/2014-January/007670.html >> >> In the above message, Patrick shows a few examples which show that it's >> hard to come up with rules on which arguments should be prefixed by "mut" >> that will be sound and complete. I have an idea which may be. The idea is >> to not look at function arguments but at uses of a variable. Here's a rule: >> >> Whenever a variable which was declared with "let mut" is being used in a >> way that would have been illegal have it not been declared with "let mut", >> it should be prefixed by "mut", unless it's obvious from the context that >> it has to be mutable. >> >> I think it's quite simple and says exactly what should be the rules in >> Patrick's examples. What's not well-defined is the "obvious from the >> context" part. Certainly when a variable is on the left hand side of an >> assignment there would be no need for "mut" annotation, as well as when >> it's being prefixed by "&mut". I don't know if there are other cases. >> >> (If you're interested in the bug: I had to use a function solve(A, b) >> which gets a matrix A and a vector b and returns a vector x such that Ax=b. >> It does Gauss elimination, and for efficiency it modified A and b instead >> of allocating new arrays. I used it like x = solve(A, b) and then used A >> again. It was in Fortran, so the arguments A and b were annotated as being >> "in out", but of course it didn't stop my perfectly looking function from >> having a hidden bug.) >> >> What do you think? >> Noam >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Wed Apr 30 02:38:18 2014 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 30 Apr 2014 05:38:18 -0400 Subject: [rust-dev] rust block comments In-Reply-To: References: Message-ID: Originally, ancient versions of Rust allowed you to nest block comments. Then we decided this was too surprising and too hard to parse, so we took it out. Then we decided that this was too useful to exclude so we added it back in, but apparently this time we forgot to update the manual. Just another day in the life of Rust! :) On Wed, Apr 30, 2014 at 3:00 AM, Phil Dawes wrote: > Hello! > > Could somebody clarify the block comments structure in rust please? The > manual says 'Comments in Rust code follow the general C++ style of line and > block-comment forms, with no nesting of block-comment delimiters.' > http://static.rust-lang.org/doc/master/rust.html#comments > > However the grammar looks like it parses nesting of block comment > delimiters, and e.g. the following compiles: > > fn main() { > /* /* */ */ println!("YEAH!"); > } > > Is the manual wrong or have I mis-understood it? (racer performs comment > cleaning which is why I'm interested) > > Thanks, > > Phil > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Wed Apr 30 03:08:19 2014 From: artella.coding at googlemail.com (Artella Coding) Date: Wed, 30 Apr 2014 11:08:19 +0100 Subject: [rust-dev] Another idea on requiring "mut" prefix at call site In-Reply-To: References: Message-ID: A problem might arise when trying to prototype new ideas in an existing codebase. Suppose I have a sequence of pure operations f0,f1,f2,f3,f4 (note these functions are only pure for the example below). Then both you and rust would be aligned with the following code : ****************************** fn f0(x: &mut int) -> int { f1(x) } fn f1(x: &mut int) -> int { f2(x) } fn f2(x: &mut int) -> int { f3(x) } fn f3(x: &mut int) -> int { f4(x) } fn f4(x: &mut int) -> int { *x + 2 } fn main() { let mut x = ~1i; let y = f0(x); println!("{} {}", x, y);// 1 3 } ****************************** Then deep within my code if I wanted, as a test, to mutate a variable (such a motivation is lacking for the code above, but just imagine), thus breaking the purity of f0,f1,f2,f3,f4, then under your proposal we would have to annotate the code with 5 new "mut" keywords as follows : ****************************** fn f0(x: &mut int) -> int { f1(mut x) } fn f1(x: &mut int) -> int { f2(mut x) } fn f2(x: &mut int) -> int { f3(mut x) } fn f3(x: &mut int) -> int { f4(mut x) } fn f4(x: &mut int) -> int { *x = 2; 3 } fn main() { let mut x = ~1i; let y = f0(mut x); println!("{} {}", x, y);// 2 3 } ****************************** Inserting all these new annotations simply for the purposes of testing out a new idea might be quite cumbersome. If your rule was implemented, then maybe having some sort of additional mechanism analogous to Haskell's unsafeIO, to mask the mutation, would be useful : http://www.haskell.org/haskellwiki/Avoiding_IO "The method of last resort is unsafePerformIO. When you apply it, think about how to reduce its use and how you can encapsulate it in a library with a well chosen interface. Since unsafePerformIO makes functions look like non-IO functions, they should also behave like non-IO functions. E.g. file access must not be hidden in unsafePerformIO, whereas careful memory manipulation may be safe ? see for instance the Data.ByteString module." However I do agree with you that it would be nice to have some annotation in your reddit example. On Wed, Apr 30, 2014 at 8:33 AM, Noam Yorav-Raphael wrote: > Hi, > > I had a bug caused by a function mutating its arguments, and it had > occurred to me that it may be a good idea if rust would require a "mut" > prefix in that case. I asked on reddit, and was referred to this thread: > https://mail.mozilla.org/pipermail/rust-dev/2014-January/007670.html > > In the above message, Patrick shows a few examples which show that it's > hard to come up with rules on which arguments should be prefixed by "mut" > that will be sound and complete. I have an idea which may be. The idea is > to not look at function arguments but at uses of a variable. Here's a rule: > > Whenever a variable which was declared with "let mut" is being used in a > way that would have been illegal have it not been declared with "let mut", > it should be prefixed by "mut", unless it's obvious from the context that > it has to be mutable. > > I think it's quite simple and says exactly what should be the rules in > Patrick's examples. What's not well-defined is the "obvious from the > context" part. Certainly when a variable is on the left hand side of an > assignment there would be no need for "mut" annotation, as well as when > it's being prefixed by "&mut". I don't know if there are other cases. > > (If you're interested in the bug: I had to use a function solve(A, b) > which gets a matrix A and a vector b and returns a vector x such that Ax=b. > It does Gauss elimination, and for efficiency it modified A and b instead > of allocating new arrays. I used it like x = solve(A, b) and then used A > again. It was in Fortran, so the arguments A and b were annotated as being > "in out", but of course it didn't stop my perfectly looking function from > having a hidden bug.) > > What do you think? > Noam > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From n.krishnaswami at cs.bham.ac.uk Wed Apr 30 03:44:52 2014 From: n.krishnaswami at cs.bham.ac.uk (Neelakantan Krishnaswami) Date: Wed, 30 Apr 2014 11:44:52 +0100 Subject: [rust-dev] Call for talk proposals: HOPE'14 (Workshop on Higher-Order Programming with Effects, affiliated with ICFP'14) Message-ID: <5360D424.6070901@cs.bham.ac.uk> ---------------------------------------------------------------------- CALL FOR TALK PROPOSALS HOPE 2014 The 3rd ACM SIGPLAN Workshop on Higher-Order Programming with Effects August 31, 2014 Gothenburg, Sweden (the day before ICFP 2014) https://www.mpi-sws.org/~neelk/hope2014/ ---------------------------------------------------------------------- HOPE 2014 aims at bringing together researchers interested in the design, semantics, implementation, and verification of higher-order effectful programs. It will be *informal*, consisting of invited talks, contributed talks on work in progress, and open-ended discussion sessions. --------------------- Goals of the Workshop --------------------- A recurring theme in many papers at ICFP, and in the research of many ICFP attendees, is the interaction of higher-order programming with various kinds of effects: storage effects, I/O, control effects, concurrency, etc. While effects are of critical importance in many applications, they also make it hard to build, maintain, and reason about one's code. Higher-order languages (both functional and object-oriented) provide a variety of abstraction mechanisms to help "tame" or "encapsulate" effects (e.g. monads, ADTs, ownership types, typestate, first-class events, transactions, Hoare Type Theory, session types, substructural and region-based type systems), and a number of different semantic models and verification technologies have been developed in order to codify and exploit the benefits of this encapsulation (e.g. bisimulations, step-indexed Kripke logical relations, higher-order separation logic, game semantics, various modal logics). But there remain many open problems, and the field is highly active. The goal of the HOPE workshop is to bring researchers from a variety of different backgrounds and perspectives together to exchange new and exciting ideas concerning the design, semantics, implementation, and verification of higher-order effectful programs. We want HOPE to be as informal and interactive as possible. The program will thus involve a combination of invited talks, contributed talks about work in progress, and open-ended discussion sessions. There will be no published proceedings, but participants will be invited to submit working documents, talk slides, etc. to be posted on this website. ----------------------- Call for Talk Proposals ----------------------- We solicit proposals for contributed talks. Proposals should be at most 2 pages, in either plain text or PDF format, and should specify how long a talk the speaker wishes to give. By default, contributed talks will be 30 minutes long, but proposals for shorter or longer talks will also be considered. Speakers may also submit supplementary material (e.g. a full paper, talk slides) if they desire, which PC members are free (but not expected) to read. We are interested in talks on all topics related to the interaction of higher-order programming and computational effects. Talks about work in progress are particularly encouraged. If you have any questions about the relevance of a particular topic, please contact the PC chairs at the address hope2014 AT mpi-sws.org. Deadline for talk proposals: June 13, 2014 (Friday) Notification of acceptance: July 4, 2014 (Friday) Workshop: August 31, 2014 (Sunday) The submission website is now open: https://www.easychair.org/conferences/?conf=hope2014 --------------------- Workshop Organization --------------------- Program Co-Chairs: Neel Krishnaswami (University of Birmingham) Hongseok Yang (University of Oxford) Program Committee: Zena Ariola (University of Oregon) Ohad Kammar (University of Cambridge) Ioannis Kassios (ETH Zurich) Naoki Kobayashi (University of Tokyo) Paul Blain Levy (University of Birmingham) Aleks Nanevski (IMDEA) Scott Owens (University of Kent) Sam Staton (Radboud University Nijmegen) Steve Zdancewic (University of Pennsylvania) From mneumann at ntecs.de Wed Apr 30 03:54:11 2014 From: mneumann at ntecs.de (Michael Neumann) Date: Wed, 30 Apr 2014 12:54:11 +0200 Subject: [rust-dev] PipeStream.by_ref() - Multiple applicable methods problem In-Reply-To: References: <535FEF1B.908@ntecs.de> Message-ID: <5360D653.9050205@ntecs.de> Am 29.04.2014 22:51, schrieb Alex Crichton: > The by_ref() method exists on both the Reader and the Writer trait, > and you're working with a stream which implements both Reader and > Writer (hence the confusion by the compiler). > > You could work around it with something like: > > fn rdr<'a, T: Reader>(t: &'a mut T) -> RefReader<'a, T> { > t.by_ref() > } > > Eventually, with UFCS, you'll be able to do something like: > > let rdr = Reader::by_ref(&mut inp); > > (hopefully soon!) Thanks so much! This works! Actually I was trying to explicitly specify the type as in: let rdr: RefReader = t.by_ref(); and was wondering why it failed. Regards, Michael From noamraph at gmail.com Wed Apr 30 05:31:35 2014 From: noamraph at gmail.com (Noam Yorav-Raphael) Date: Wed, 30 Apr 2014 15:31:35 +0300 Subject: [rust-dev] Another idea on requiring "mut" prefix at call site In-Reply-To: References: Message-ID: Actually I realize that my suggestion doesn't solve any real problem. The example at reddit was quite strange, and as Patrick wrote, avoiding autoborrow of ~ to & would solve it. The real place where such an annotation would help is where, like in Artella's example, a function gets a &mut reference and passes it to another function. Then it's not clear whether the other function expects a non-mutable reference or is it going to mutate the variable. Then a solution might be to require writing "mut" before the name of a &mut reference that can't be replaced with a non-mut reference. That is, in this example: fn mut_it(x: &mut int) { *x += 1; } fn print_it(x: &int) { println!("{}", x); } fn f(x: &mut int) { mut_it(x); print_it(x); } fn main() { let mut x = 1i; f(&mut x); } You'll have to replace "mut_it(x)" with "mut_it(mut x)" On Wed, Apr 30, 2014 at 10:33 AM, Noam Yorav-Raphael wrote: > Hi, > > I had a bug caused by a function mutating its arguments, and it had occurred > to me that it may be a good idea if rust would require a "mut" prefix in > that case. I asked on reddit, and was referred to this thread: > https://mail.mozilla.org/pipermail/rust-dev/2014-January/007670.html > > In the above message, Patrick shows a few examples which show that it's hard > to come up with rules on which arguments should be prefixed by "mut" that > will be sound and complete. I have an idea which may be. The idea is to not > look at function arguments but at uses of a variable. Here's a rule: > > Whenever a variable which was declared with "let mut" is being used in a way > that would have been illegal have it not been declared with "let mut", it > should be prefixed by "mut", unless it's obvious from the context that it > has to be mutable. > > I think it's quite simple and says exactly what should be the rules in > Patrick's examples. What's not well-defined is the "obvious from the > context" part. Certainly when a variable is on the left hand side of an > assignment there would be no need for "mut" annotation, as well as when it's > being prefixed by "&mut". I don't know if there are other cases. > > (If you're interested in the bug: I had to use a function solve(A, b) which > gets a matrix A and a vector b and returns a vector x such that Ax=b. It > does Gauss elimination, and for efficiency it modified A and b instead of > allocating new arrays. I used it like x = solve(A, b) and then used A again. > It was in Fortran, so the arguments A and b were annotated as being "in > out", but of course it didn't stop my perfectly looking function from having > a hidden bug.) > > What do you think? > Noam From farcaller at gmail.com Wed Apr 30 06:27:16 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Wed, 30 Apr 2014 14:27:16 +0100 Subject: [rust-dev] morestack prologue contains broken machine code In-Reply-To: References: Message-ID: I guess I've misread how __STACK_LIMIT works, it seems that I can change it's value on context switch so that it keeps track of the current running task. Works flawlessly, so I'm going to proceed with my original patch now. On Fri, Apr 25, 2014 at 6:33 PM, Vladimir Pouzanov wrote: > AFAIK, it's emulated in software with __tls_get_addr. Mind that Cortex-M > MCUs that I'm toying with aren't usually compatible with any "full-blown" > OS, and all the RTOSes out there have different implementations of > multithreading and TLS, utilising the "none" OS target of gcc. The best way > to deal with this would be to specify "arm-none-eabi" ABI for llvm, that > would include tls behaviour amongst other things, but that sounds like a > very complex task. > > > On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton wrote: > >> The prologue is run on every single function executed in a program, so >> I believe that in the hopes of keeping it as light as possible it >> never makes any function calls. >> >> I do agree though, that it's at tricky situation in that case. How >> does TLS otherwise work for that platform? >> >> On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov >> wrote: >> > I have a side question related to the same code. >> > >> > Currently __STACK_LIMIT is constant, but I would like the preamble to >> verify >> > stack overflow for multithreaded context, i.e. __STACK_LIMIT will >> depend on >> > the current running thread. Is there any reason, why it's not a >> function? >> > Any objections if I do some refactoring and make it a function? For a >> simple >> > case that could be a weak symbol that returns a constant. >> > >> > >> > On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton >> wrote: >> >> >> >> I agree with Corey, it's much better to send it upstream first. I'd be >> >> more than willing to help you out with writing tests or taking a peek >> >> at the patch if you want! I'm acrichto on IRC >> >> >> >> On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov < >> farcaller at gmail.com> >> >> wrote: >> >> > The problem is that mrc is generated unless target is thumb1, but >> >> > cortex-m3 >> >> > is thumb2 that still doesn't support mrc: >> >> > >> >> > >> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html >> , >> >> > so an additional check to ST->TargetTriple.Data is required to verify >> >> > it's >> >> > not thumbv7m. >> >> > >> >> > Do I need to submit patch against https://github.com/rust-lang/llvmor >> >> > send >> >> > it to upstream? >> >> > >> >> > >> >> > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov < >> farcaller at gmail.com> >> >> > wrote: >> >> >> >> >> >> Hm, it seems to have precautions to stop mrc from materializing on >> >> >> Thumb1. >> >> >> I guess I need to take a better look into what's going wrong on my >> >> >> side. >> >> >> I'll see what I can do with that. >> >> >> >> >> >> >> >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton >> >> >> wrote: >> >> >>> >> >> >>> The split stack patches for ARM were recently upstreamed, and they >> >> >>> were modified when being upstreamed as well. Primarily the >> location of >> >> >>> the split stack is no longer at a magic address for thumb, but >> rather >> >> >>> it uses the same instruction as ARM (some thumb processors do >> indeed >> >> >>> have the coprocessor). More information is in the long thread >> starting >> >> >>> at the initial attempt to upstream [1]. >> >> >>> >> >> >>> For now you'll have to use no_split_stack because the thumb split >> >> >>> stack will always use a coprocessor, but I'm sure that the upstream >> >> >>> LLVM devs would be quite welcoming to tweaks to the slit-stack >> support >> >> >>> (I'd also be willing to help). You can find the initial commit for >> >> >>> support at rust-lang/llvm [2]. >> >> >>> >> >> >>> [1] - >> >> >>> >> >> >>> >> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html >> >> >>> [2] - https://github.com/rust-lang/llvm/pull/4 >> >> >>> >> >> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov >> >> >>> >> >> >>> wrote: >> >> >>> > Starting recently (no more than two weeks), rustc is generating a >> >> >>> > broken >> >> >>> > prologue for arm. Here's the sample assembly: >> >> >>> > 0x00000f44 <+0>: push {r4, r5} >> >> >>> > => 0x00000f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3} >> >> >>> > 0x00000f4a <+6>: mov r5, sp >> >> >>> > 0x00000f4c <+8>: b.n 0xa78 >> >> >>> > 0x00000f4e <+10>: ands r4, r0 >> >> >>> > 0x00000f50 <+12>: cmp r4, r5 >> >> >>> > 0x00000f52 <+14>: bcc.n 0xf66 >> >> >>> > >> >> >>> > >> >> >>> > >> <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34> >> >> >>> > 0x00000f54 <+16>: movs r4, #16 >> >> >>> > 0x00000f56 <+18>: movs r5, #0 >> >> >>> > 0x00000f58 <+20>: push {lr} >> >> >>> > 0x00000f5a <+22>: bl 0x19d8 <__morestack> >> >> >>> > 0x00000f5e <+26>: ldr.w lr, [sp], #4 >> >> >>> > 0x00000f62 <+30>: pop {r4, r5} >> >> >>> > 0x00000f64 <+32>: bx lr >> >> >>> > >> >> >>> > The problem is at 0x00000f46, where code tries to read from >> >> >>> > coprocessor >> >> >>> > 15 >> >> >>> > register 13, which is "process id register". Well, coprocessor 15 >> >> >>> > (actually, >> >> >>> > all of the coprocessors) are missing from my target >> >> >>> > thumbv7m-linux-eabi >> >> >>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be >> >> >>> > redundant >> >> >>> > anyway), so I'm getting hardfaults in every function that rust >> >> >>> > doesn't >> >> >>> > inline. >> >> >>> > >> >> >>> > Any ideas on what might be going wrong? I assume that this is >> >> >>> > actually >> >> >>> > llvm's fault, as llvm should not materialize machine code which >> is >> >> >>> > not >> >> >>> > available for target anyway. >> >> >>> > >> >> >>> > Wrapping everything in #[no_split_stack] is a temporary >> workaround >> >> >>> > and >> >> >>> > surely not a long-term strategy. >> >> >>> > >> >> >>> > -- >> >> >>> > Sincerely, >> >> >>> > Vladimir "Farcaller" Pouzanov >> >> >>> > http://farcaller.net/ >> >> >>> > >> >> >>> > _______________________________________________ >> >> >>> > Rust-dev mailing list >> >> >>> > Rust-dev at mozilla.org >> >> >>> > https://mail.mozilla.org/listinfo/rust-dev >> >> >>> > >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> -- >> >> >> Sincerely, >> >> >> Vladimir "Farcaller" Pouzanov >> >> >> http://farcaller.net/ >> >> > >> >> > >> >> > >> >> > >> >> > -- >> >> > Sincerely, >> >> > Vladimir "Farcaller" Pouzanov >> >> > http://farcaller.net/ >> > >> > >> > >> > >> > -- >> > Sincerely, >> > Vladimir "Farcaller" Pouzanov >> > http://farcaller.net/ >> > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Wed Apr 30 06:49:52 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Wed, 30 Apr 2014 14:49:52 +0100 Subject: [rust-dev] Symbol visibility problem Message-ID: I have the following setup: libzinc, compiles as rlib, provides all the stuff support, compiles as obj, provides __morestack, memset/memcpy and other required things libapp, compiles as staticlib emitting obj, depends on libzinc, builds with lto. I link libapp.o and support.o to get the final binary. Now, to make multitasking work, I need to move __morestack into libzinc, so that I can access task API from the function. The problem is that publicly visible __morestack in libzinc is not visible from libapp, which requires it implicitly via function prologues. Other static symbols (like __STACK_LIMIT) are not available as well. Is there any way to promote the visibility of symbols from libzinc to libapp in this case? -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Wed Apr 30 09:13:35 2014 From: alex at crichton.co (Alex Crichton) Date: Wed, 30 Apr 2014 09:13:35 -0700 Subject: [rust-dev] PipeStream.by_ref() - Multiple applicable methods problem In-Reply-To: <5360D653.9050205@ntecs.de> References: <535FEF1B.908@ntecs.de> <5360D653.9050205@ntecs.de> Message-ID: Oddly enough, that was the first thing I jumped to as well! I think that type inference like that doesn't drive method selection, which is why it ended up not working out. On Wed, Apr 30, 2014 at 3:54 AM, Michael Neumann wrote: > > > Am 29.04.2014 22:51, schrieb Alex Crichton: > >> The by_ref() method exists on both the Reader and the Writer trait, >> and you're working with a stream which implements both Reader and >> Writer (hence the confusion by the compiler). >> >> You could work around it with something like: >> >> fn rdr<'a, T: Reader>(t: &'a mut T) -> RefReader<'a, T> { >> t.by_ref() >> } >> >> Eventually, with UFCS, you'll be able to do something like: >> >> let rdr = Reader::by_ref(&mut inp); >> >> (hopefully soon!) > > Thanks so much! This works! > > Actually I was trying to explicitly specify the type as in: > > let rdr: RefReader = t.by_ref(); > > and was wondering why it failed. > > Regards, > > Michael From alex at crichton.co Wed Apr 30 09:17:27 2014 From: alex at crichton.co (Alex Crichton) Date: Wed, 30 Apr 2014 09:17:27 -0700 Subject: [rust-dev] Symbol visibility problem In-Reply-To: References: Message-ID: In an rlib, all publicly reachable symbols will be exported from the object, for example: mod foo { pub static BAR: int = 3; } That symbol is not exported because BAR is not reachable from the outside world. pub use foo::BAR; mod foo { pub static BAR: int = 3; } This time, BAR will be an exported symbol because it is publicly reachable (you could also make 'foo' public). Would that help your use case, or are you thinking of something more complex? On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov wrote: > I have the following setup: > > libzinc, compiles as rlib, provides all the stuff > support, compiles as obj, provides __morestack, memset/memcpy and other > required things > libapp, compiles as staticlib emitting obj, depends on libzinc, builds > with lto. > > I link libapp.o and support.o to get the final binary. > > Now, to make multitasking work, I need to move __morestack into libzinc, so > that I can access task API from the function. The problem is that publicly > visible __morestack in libzinc is not visible from libapp, which requires it > implicitly via function prologues. Other static symbols (like __STACK_LIMIT) > are not available as well. > > Is there any way to promote the visibility of symbols from libzinc to libapp > in this case? > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From farcaller at gmail.com Wed Apr 30 09:29:39 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Wed, 30 Apr 2014 17:29:39 +0100 Subject: [rust-dev] Symbol visibility problem In-Reply-To: References: Message-ID: Right, so I have a publicly reachable symbol __STACK_LIMIT inside my libzinc rlib: #[no_mangle] pub static mut __STACK_LIMIT: u32 = 0; which is present in rlib's object file: % arm-none-eabi-nm zinc.o|grep __STACK_LIMIT 00000000 B __STACK_LIMIT Now, I compile my application, which is a staticlib, emiting an obj (I could change staticlib to binary, that doesn't really change anything at this emit level): rustc -Z no-landing-pads -C relocation_model=static --target thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj -L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs Which implicitly links to libzinc-de5e5c68-0.0.rlib. Given the lto nature, ./build/intermediate/app.o will contain all the required code from libzinc (and libcore), so I proceed to linker: arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T ./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o -L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m --gc-sections -lgcc Which fails due to "undefined reference to `__STACK_LIMIT'", as the lto step didn't keep the __STACK_LIMIT (which is, along with __morestack, used implicitly). I have the same problem with ISRs that re defined in libzinc. For now, I make trampolines in the app code: #[no_mangle] #[inline(never)] #[no_split_stack] pub unsafe fn task_scheduler() { task::task_scheduler(); } that look bad, but I don't yet know a better way to do it. I cannot move __STACK_LIMIT or __morestack in a dedicated object file and pass it to linker, as those depend on libzinc which isn't reaching the linker explicitly. On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton wrote: > In an rlib, all publicly reachable symbols will be exported from the > object, for example: > > > mod foo { pub static BAR: int = 3; } > > That symbol is not exported because BAR is not reachable from the outside > world. > > pub use foo::BAR; > mod foo { pub static BAR: int = 3; } > > This time, BAR will be an exported symbol because it is publicly > reachable (you could also make 'foo' public). > > Would that help your use case, or are you thinking of something more > complex? > > On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov > wrote: > > I have the following setup: > > > > libzinc, compiles as rlib, provides all the stuff > > support, compiles as obj, provides __morestack, memset/memcpy and other > > required things > > libapp, compiles as staticlib emitting obj, depends on libzinc, builds > > with lto. > > > > I link libapp.o and support.o to get the final binary. > > > > Now, to make multitasking work, I need to move __morestack into libzinc, > so > > that I can access task API from the function. The problem is that > publicly > > visible __morestack in libzinc is not visible from libapp, which > requires it > > implicitly via function prologues. Other static symbols (like > __STACK_LIMIT) > > are not available as well. > > > > Is there any way to promote the visibility of symbols from libzinc to > libapp > > in this case? > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From farcaller at gmail.com Wed Apr 30 10:41:21 2014 From: farcaller at gmail.com (Vladimir Pouzanov) Date: Wed, 30 Apr 2014 18:41:21 +0100 Subject: [rust-dev] Symbol visibility problem In-Reply-To: References: Message-ID: Ok, seems that I found a reasonably good solution. The "app" is now an rlib, and the actual staticlib app that gets linked is a wrapper, that sources all external crates and re-exports required symbols like this: #[no_split_stack] #[no_mangle] #[start] pub extern fn main() { app::main(); } I also had to move __STACK_LIMIT into external C file, as I couldn't define it as external in one crate and provide it in another crate down the chain. On Wed, Apr 30, 2014 at 5:29 PM, Vladimir Pouzanov wrote: > Right, so I have a publicly reachable symbol __STACK_LIMIT inside my > libzinc rlib: > > #[no_mangle] > pub static mut __STACK_LIMIT: u32 = 0; > > which is present in rlib's object file: > > % arm-none-eabi-nm zinc.o|grep __STACK_LIMIT > 00000000 B __STACK_LIMIT > > Now, I compile my application, which is a staticlib, emiting an obj (I > could change staticlib to binary, that doesn't really change anything at > this emit level): > > rustc -Z no-landing-pads -C relocation_model=static --target > thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj > -L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs > > Which implicitly links to libzinc-de5e5c68-0.0.rlib. > > Given the lto nature, ./build/intermediate/app.o will contain all the > required code from libzinc (and libcore), so I proceed to linker: > > arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T > ./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o > -L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m > --gc-sections -lgcc > > Which fails due to "undefined reference to `__STACK_LIMIT'", as the lto > step didn't keep the __STACK_LIMIT (which is, along with __morestack, used > implicitly). > > I have the same problem with ISRs that re defined in libzinc. For now, I > make trampolines in the app code: > > #[no_mangle] > #[inline(never)] > #[no_split_stack] > pub unsafe fn task_scheduler() { > task::task_scheduler(); > } > > that look bad, but I don't yet know a better way to do it. > > I cannot move __STACK_LIMIT or __morestack in a dedicated object file and > pass it to linker, as those depend on libzinc which isn't reaching the > linker explicitly. > > > On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton wrote: > >> In an rlib, all publicly reachable symbols will be exported from the >> object, for example: >> >> >> mod foo { pub static BAR: int = 3; } >> >> That symbol is not exported because BAR is not reachable from the outside >> world. >> >> pub use foo::BAR; >> mod foo { pub static BAR: int = 3; } >> >> This time, BAR will be an exported symbol because it is publicly >> reachable (you could also make 'foo' public). >> >> Would that help your use case, or are you thinking of something more >> complex? >> >> On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov >> wrote: >> > I have the following setup: >> > >> > libzinc, compiles as rlib, provides all the stuff >> > support, compiles as obj, provides __morestack, memset/memcpy and >> other >> > required things >> > libapp, compiles as staticlib emitting obj, depends on libzinc, builds >> > with lto. >> > >> > I link libapp.o and support.o to get the final binary. >> > >> > Now, to make multitasking work, I need to move __morestack into >> libzinc, so >> > that I can access task API from the function. The problem is that >> publicly >> > visible __morestack in libzinc is not visible from libapp, which >> requires it >> > implicitly via function prologues. Other static symbols (like >> __STACK_LIMIT) >> > are not available as well. >> > >> > Is there any way to promote the visibility of symbols from libzinc to >> libapp >> > in this case? >> > >> > -- >> > Sincerely, >> > Vladimir "Farcaller" Pouzanov >> > http://farcaller.net/ >> > >> > _______________________________________________ >> > Rust-dev mailing list >> > Rust-dev at mozilla.org >> > https://mail.mozilla.org/listinfo/rust-dev >> > >> > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex at crichton.co Wed Apr 30 11:15:57 2014 From: alex at crichton.co (Alex Crichton) Date: Wed, 30 Apr 2014 11:15:57 -0700 Subject: [rust-dev] Symbol visibility problem In-Reply-To: References: Message-ID: Ah, I forgot to mention, but the visibility rules are different for libraries than they are for executables (for better or for worse). An executable only has reachable C functions exported. I don't think statics are exported, but that's arguably a bug. Libraries, however, have all functions/symbols exported. If you're building an application which is invoked primarily through some other binding, I'd recommend using a staticlib output rather than an executable output (and just using the object file). This is primarily what staticlibs exist for. On Wed, Apr 30, 2014 at 10:41 AM, Vladimir Pouzanov wrote: > Ok, seems that I found a reasonably good solution. > > The "app" is now an rlib, and the actual staticlib app that gets linked is a > wrapper, that sources all external crates and re-exports required symbols > like this: > > #[no_split_stack] > #[no_mangle] > #[start] > pub extern fn main() { > app::main(); > } > > I also had to move __STACK_LIMIT into external C file, as I couldn't define > it as external in one crate and provide it in another crate down the chain. > > > On Wed, Apr 30, 2014 at 5:29 PM, Vladimir Pouzanov > wrote: >> >> Right, so I have a publicly reachable symbol __STACK_LIMIT inside my >> libzinc rlib: >> >> #[no_mangle] >> pub static mut __STACK_LIMIT: u32 = 0; >> >> which is present in rlib's object file: >> >> % arm-none-eabi-nm zinc.o|grep __STACK_LIMIT >> 00000000 B __STACK_LIMIT >> >> Now, I compile my application, which is a staticlib, emiting an obj (I >> could change staticlib to binary, that doesn't really change anything at >> this emit level): >> >> rustc -Z no-landing-pads -C relocation_model=static --target >> thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj >> -L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs >> >> Which implicitly links to libzinc-de5e5c68-0.0.rlib. >> >> Given the lto nature, ./build/intermediate/app.o will contain all the >> required code from libzinc (and libcore), so I proceed to linker: >> >> arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T >> ./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o >> -L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m >> --gc-sections -lgcc >> >> Which fails due to "undefined reference to `__STACK_LIMIT'", as the lto >> step didn't keep the __STACK_LIMIT (which is, along with __morestack, used >> implicitly). >> >> I have the same problem with ISRs that re defined in libzinc. For now, I >> make trampolines in the app code: >> >> #[no_mangle] >> #[inline(never)] >> #[no_split_stack] >> pub unsafe fn task_scheduler() { >> task::task_scheduler(); >> } >> >> that look bad, but I don't yet know a better way to do it. >> >> I cannot move __STACK_LIMIT or __morestack in a dedicated object file and >> pass it to linker, as those depend on libzinc which isn't reaching the >> linker explicitly. >> >> >> On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton wrote: >>> >>> In an rlib, all publicly reachable symbols will be exported from the >>> object, for example: >>> >>> >>> mod foo { pub static BAR: int = 3; } >>> >>> That symbol is not exported because BAR is not reachable from the outside >>> world. >>> >>> pub use foo::BAR; >>> mod foo { pub static BAR: int = 3; } >>> >>> This time, BAR will be an exported symbol because it is publicly >>> reachable (you could also make 'foo' public). >>> >>> Would that help your use case, or are you thinking of something more >>> complex? >>> >>> On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov >>> wrote: >>> > I have the following setup: >>> > >>> > libzinc, compiles as rlib, provides all the stuff >>> > support, compiles as obj, provides __morestack, memset/memcpy and >>> > other >>> > required things >>> > libapp, compiles as staticlib emitting obj, depends on libzinc, >>> > builds >>> > with lto. >>> > >>> > I link libapp.o and support.o to get the final binary. >>> > >>> > Now, to make multitasking work, I need to move __morestack into >>> > libzinc, so >>> > that I can access task API from the function. The problem is that >>> > publicly >>> > visible __morestack in libzinc is not visible from libapp, which >>> > requires it >>> > implicitly via function prologues. Other static symbols (like >>> > __STACK_LIMIT) >>> > are not available as well. >>> > >>> > Is there any way to promote the visibility of symbols from libzinc to >>> > libapp >>> > in this case? >>> > >>> > -- >>> > Sincerely, >>> > Vladimir "Farcaller" Pouzanov >>> > http://farcaller.net/ >>> > >>> > _______________________________________________ >>> > Rust-dev mailing list >>> > Rust-dev at mozilla.org >>> > https://mail.mozilla.org/listinfo/rust-dev >>> > >> >> >> >> >> -- >> Sincerely, >> Vladimir "Farcaller" Pouzanov >> http://farcaller.net/ > > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ From noamraph at gmail.com Wed Apr 30 23:48:09 2014 From: noamraph at gmail.com (Noam Yorav-Raphael) Date: Thu, 1 May 2014 09:48:09 +0300 Subject: [rust-dev] Another idea on requiring "mut" prefix at call site In-Reply-To: References: Message-ID: Just because I still think it might be a good idea -- if it turns out to be a good idea, it will be possible to add such a "mut" annotation to rust 1.1 and issue a warning if it is not being used, right? Noam On Apr 30, 2014 3:31 PM, "Noam Yorav-Raphael" wrote: > Actually I realize that my suggestion doesn't solve any real problem. > The example at reddit was quite strange, and as Patrick wrote, > avoiding autoborrow of ~ to & would solve it. > > The real place where such an annotation would help is where, like in > Artella's example, a function gets a &mut reference and passes it to > another function. Then it's not clear whether the other function > expects a non-mutable reference or is it going to mutate the variable. > > Then a solution might be to require writing "mut" before the name of a > &mut reference that can't be replaced with a non-mut reference. That > is, in this example: > > fn mut_it(x: &mut int) { > *x += 1; > } > > fn print_it(x: &int) { > println!("{}", x); > } > > fn f(x: &mut int) { > mut_it(x); > print_it(x); > } > > fn main() { > let mut x = 1i; > f(&mut x); > } > > You'll have to replace "mut_it(x)" with "mut_it(mut x)" > > On Wed, Apr 30, 2014 at 10:33 AM, Noam Yorav-Raphael > wrote: > > Hi, > > > > I had a bug caused by a function mutating its arguments, and it had > occurred > > to me that it may be a good idea if rust would require a "mut" prefix in > > that case. I asked on reddit, and was referred to this thread: > > https://mail.mozilla.org/pipermail/rust-dev/2014-January/007670.html > > > > In the above message, Patrick shows a few examples which show that it's > hard > > to come up with rules on which arguments should be prefixed by "mut" that > > will be sound and complete. I have an idea which may be. The idea is to > not > > look at function arguments but at uses of a variable. Here's a rule: > > > > Whenever a variable which was declared with "let mut" is being used in a > way > > that would have been illegal have it not been declared with "let mut", it > > should be prefixed by "mut", unless it's obvious from the context that it > > has to be mutable. > > > > I think it's quite simple and says exactly what should be the rules in > > Patrick's examples. What's not well-defined is the "obvious from the > > context" part. Certainly when a variable is on the left hand side of an > > assignment there would be no need for "mut" annotation, as well as when > it's > > being prefixed by "&mut". I don't know if there are other cases. > > > > (If you're interested in the bug: I had to use a function solve(A, b) > which > > gets a matrix A and a vector b and returns a vector x such that Ax=b. It > > does Gauss elimination, and for efficiency it modified A and b instead of > > allocating new arrays. I used it like x = solve(A, b) and then used A > again. > > It was in Fortran, so the arguments A and b were annotated as being "in > > out", but of course it didn't stop my perfectly looking function from > having > > a hidden bug.) > > > > What do you think? > > Noam > -------------- next part -------------- An HTML attachment was scrubbed... URL: