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 <co...@octayn.net> 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 <farcal...@gmail.com>
> 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 <co...@octayn.net>
> wrote:
> >>
> >> You don't use bounds in the struct, you put them in the impl. So you
> >> would instead say
> >>
> >>
> >> struct LCD<S> {
> >>   spi: S,
> >>   ...
> >> }
> >>
> >>
> >> and then:
> >>
> >> impl<S: SPI> LCD<S> {
> >>     ...
> >> }
> >>
> >> On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov <farcal...@gmail.com>
> >> 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 <marci...@gmail.com>
> 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<T : LCD>(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 <danielmi...@gmail.com>
> >> >> 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<T: TotalOrd>(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@mozilla.org
> >> >> > https://mail.mozilla.org/listinfo/rust-dev
> >> >> >
> >> >
> >> >
> >> >
> >> >
> >> > --
> >> > Sincerely,
> >> > Vladimir "Farcaller" Pouzanov
> >> > http://farcaller.net/
> >> >
> >> > _______________________________________________
> >> > Rust-dev mailing list
> >> > Rust-dev@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/
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to