These are chat archives for rust-lang/rust

3rd
Dec 2017
Restioson
@Restioson
Dec 03 2017 06:56
So, no way to get private trait functions?
saolof
@saolof
Dec 03 2017 06:57
define the function outside of the trait body?
Restioson
@Restioson
Dec 03 2017 06:58
Nope, it gotta be implemented differently for every trait impl, but it overlaps with the supertrait :/
idk if this is the best design choice ever... but it's certainly better than the other idea's i've thought of...
at this point i'm contemplating putting a double underscore before the name and noting that it should not be used outside of impl's
Restioson
@Restioson
Dec 03 2017 07:03
but that's sorta... eh
Restioson
@Restioson
Dec 03 2017 07:11
Okaaay, just checking... Is there no way to 'half implement' a trait for a type, if that type then implements the rest of the methods?
trait HalfImplemented {
    fn needs_explicit_impl();
    fn can_be_generically_impld();
}

impl <T> HalfImplemented for T {
    // fn need_explicit_impl(); needs to be explicitly impl'd to make HalfImplemented available for T
    fn can_be_generically_impld() {
        println!("Generically impld");
    }
}

struct Something;

impl HalfImplemented for Something {
    fn needs_explicit_impl() {
        println!("Explicitly impld");
    }
}

// HalfImplemented is now available for Something
something like this?
I'm getting pretty desperate, lol
saolof
@saolof
Dec 03 2017 07:35
split it into two traits?
with one inheriting from the other
Restioson
@Restioson
Dec 03 2017 07:37
Hmm, maybe I can do that
ideally i want them to be unified though :(
saolof
@saolof
Dec 03 2017 07:39
or do you just want a default implementation for the second method
traits methods can have default implementations in the trait body
trait HalfImplemented {
    fn needs_explicit_impl();
    fn can_be_generically_impld() {
        println!("Generically impld");
    }
}
struct Something;

impl HalfImplemented for Something {
    fn needs_explicit_impl() {
        println!("Explicitly impld");
    }
}
Restioson
@Restioson
Dec 03 2017 07:43
Hmmm, seems I have not made myself clear enough, my bad
so essentially, I have a Terminal trait for terminals -- got various methods like writing a string. However, I want to be able to support serial and stream terminals, which don't necesarily let you set a character at a position. So, I created a SizedTerminal trait, with methods like set_char(char, Color, Point), etc. I want all Terminal traits to be available to SizedTerminals, so I am trying to make SizedTerminal subtrait Terminal, but since a lot of the Terminal impl logic would be common for all SizedTerminal i want to generically impl it for all sizedterminals
saolof
@saolof
Dec 03 2017 07:59
default impl is a planned addition to the language afaik
Restioson
@Restioson
Dec 03 2017 08:02
No
Maybe, can I override a supertrait's method's in a subtrait but leave some non-overriden?
saolof
@saolof
Dec 03 2017 08:05
what you could do is implement both, but use https://doc.rust-lang.org/std/macro.unimplemented.html in the explicit impl method
and override it in a struct impl block, instead of a trait impl block
saolof
@saolof
Dec 03 2017 08:10
but as I understood you, default impl in https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md#reuse is probably whay you'd really want
Restioson
@Restioson
Dec 03 2017 08:14
@saolof hrmrmrmrm....
I coudl use reuse and then unimplemented!() the other methods which need to be specialized... but the issue there is it might look to the user like it's all fine and dandy and they don't need to do anything since it compiles
If I could just leave them out of the generic impl...
saolof
@saolof
Dec 03 2017 08:17
right
So I guess the only type-safe solution is to split the parent trait into the methods that can be made generic
and those that can't
so two subtraits, and define your old parent trait as the intersection of those
Restioson
@Restioson
Dec 03 2017 08:19
I wish I could do defaults for certain trait bounds :(
because that's kinda ugly
saolof
@saolof
Dec 03 2017 08:21
trait GenericHalfImplemented {
    fn can_be_generically_impld();
}

trait HalfImplemented : GenericHalfImplemented {
    fn needs_explicit_impl();
}

impl <T : SomeSpecializedStuff> GenericHalfImplemented for T {
    // fn need_explicit_impl(); needs to be explicitly impl'd to make HalfImplemented available for T
    fn can_be_generically_impld() {
        println!("Generically impld");
    }
}

struct Something;

impl HalfImplemented for Something {
    fn needs_explicit_impl() {
        println!("Explicitly impld");
    }
}
Restioson
@Restioson
Dec 03 2017 08:21
like
default fn name(...) -> ... where Self: SomeTrait
I want to have the Terminal trait as a base common ground you can treat everything which is a terminal as -- splitting it would require Terminal + SomethingElse, which is a bit verbose and also you can't do &mut (Terminal + SomethingElse)
saolof
@saolof
Dec 03 2017 08:23
you can have Terminal : GenericTerminal
Restioson
@Restioson
Dec 03 2017 08:24
Hmm
saolof
@saolof
Dec 03 2017 08:24
i.e. terminal has a parent trait with the methods that lend themselves to good generic implementations
Restioson
@Restioson
Dec 03 2017 08:24
I could also have an extra trait -- SizedTerminalImpl which then you have to impl which provides the methods I would be making explicit
Restioson
@Restioson
Dec 03 2017 10:14
I guess what I'm kinda looking for is a sorry
... Sort* of abstract base impl
Restioson
@Restioson
Dec 03 2017 10:19
Hmmm
Reading one of aturon's post, which talks about half impl
That looks like so exactly what I want!!!
Restioson
@Restioson
Dec 03 2017 10:31
Hmmm... Doesn't seem to work? Using this as reference. Playground
David
@dvdplm
Dec 03 2017 12:41
Hi! What is the best way to convert a u64 to a base36 string in Rust? i.e. this JS (123456789).toString(36);
Sherab Giovannini
@Shaddy
Dec 03 2017 12:54

Hi guys, I'm facing a weird behaviour. I'm just creating a flags structure by using bitflags extern crate. Such like this:

https://play.rust-lang.org/?gist=22497f17e9b5b38ac32e5bb388f0803f&version=stable

The problem is that when I want to integrate such code in my project, for some reason it fails.

I'm doing, for example this:

bitflags! {
    pub struct Access: u32 {
        const READ       = 0x00000001;
        const WRITE      = 0x00000002;
        const EXECUTE    = 0x00000004;
    }
}

pub fn consumer(access: Access) {
    println!("{:?}", Access::READ);
}

And getting this error:

error[E0599]: no associated item named `READ` found for type `example::Access` in the current scope
  --> src\example\mod.rs:34:22
   |
34 |     println!("{:?}", Access::READ);
   |                      ^^^^^^^^^^^^
   |
   = help: items from traits can only be used if the trait is in scope
   = note: the following traits are implemented but not in scope, perhaps add a `use` for one of them:
           candidate #1: `use <example::Access as bitflags::<unnamed>::fmt::Debug>::fmt::__BitFlags;`
           candidate #2: `use example::Access::all::__BitFlags;`
David Harvey-Macaulay
@alteous
Dec 03 2017 13:12

@Shaddy Your playground example works on nightly but not on stable.

Hang on... now it is working for me?!

David
@dvdplm
Dec 03 2017 13:12
@Shaddy that is exactly what I need (I think), but I'm getting "no radix in fmt" errors, both on playground and locally (running yesterdays nightly)
Sherab Giovannini
@Shaddy
Dec 03 2017 13:12
@dvdplm that feature was removed / moved to another place
@alteous
active toolchain
----------------

nightly-x86_64-pc-windows-msvc (default)
rustc 1.23.0-nightly (d6b06c63a 2017-11-09)
my current project as a scope of a lib.rs which declares the use of bitflags macro, and it imports also by using mod mylib;
David Harvey-Macaulay
@alteous
Dec 03 2017 13:14
Initially the playground example failed with the error message you gave. Then I switched to nightly and it worked... but then I switched back to stable and it also worked. :S
Maybe cargo update?
Sherab Giovannini
@Shaddy
Dec 03 2017 13:16
the "to_str_radix" function is implemented by https://rust-num.github.io/num/num/struct.BigInt.html
:/
I'll try a cargo update
that is really weird
David
@dvdplm
Dec 03 2017 13:17
@Shaddy yep, saw that! :) I also found this: http://ticki.github.io/redocs/std/fmt/struct.RadixFmt.html – with notice "Deprecated since 1.7.0: not used enough to stabilize"
Sherab Giovannini
@Shaddy
Dec 03 2017 13:20
@alteous updating
    Updating registry `https://github.com/rust-lang/crates.io-index`
    Updating ansi_term v0.9.0 -> v0.10.2
      Adding bitflags v1.0.1
and still the same :(
David
@dvdplm
Dec 03 2017 13:23

@Shaddy Ok so this seem to work:

let v:u64 = 1234567;
let bv = BigInt::from(v);
println!("{}", bv.to_str_radix(36));

…but good lord, that was frustrating!

@Shaddy thanks a lot for the pointer(s). :)
Sherab Giovannini
@Shaddy
Dec 03 2017 13:23
i was about to polst it
extern crate num_bigint;

use num_bigint::ToBigInt;

fn main() {
    println!("{}", 123456789.to_bigint().unwrap().to_str_radix(36));
}
just creating the link lol
by using trait ToBigInt, you add to native integers the possiblity to just convert to bigint, which feels cleaner to me
David
@dvdplm
Dec 03 2017 13:24
Feels kind of dumb to have to pull in the whole crate, but <sigh>
Yeah, it's ugly either way if you ask me. :/
Sherab Giovannini
@Shaddy
Dec 03 2017 13:25
I don't think so
anyway, you can just add another trait to do it simple
let me write some code
Sherab Giovannini
@Shaddy
Dec 03 2017 13:28
I mean to have it simpler
that code, even if its ugly, its really efficient
David
@dvdplm
Dec 03 2017 13:28
Yes, looks like someone smart gave it some thought.
Sherab Giovannini
@Shaddy
Dec 03 2017 13:30
you could do something like this
extern crate num_bigint;

use num_bigint::ToBigInt;

trait ToBase36 {
    fn to_base36(&self) -> String;
}

impl ToBase36 for usize {
    fn to_base36(&self) -> String {
        self.to_bigint()
            .expect(format!("Unable to parse {:?}", self).as_ref())
            .to_str_radix(36)
    }
}

fn main() {
    println!("{}", 123456789.to_base36());
}
you also could improve by doing generic Integer
but I think is enough to get the point
Aleksey Kladov
@matklad
Dec 03 2017 13:30
I think using https://crates.io/crates/radix would be preferable here :)
David
@dvdplm
Dec 03 2017 13:30
That looks great
Aleksey Kladov
@matklad
Dec 03 2017 13:30
Reaching for BigInts just to print a string seems like an overkill, and is not really efficient.
Sherab Giovannini
@Shaddy
Dec 03 2017 13:31
and yes, using https://docs.rs/radix/0.3.3/radix/enum.RadixNum.html should be better LOL
Restioson
@Restioson
Dec 03 2017 13:31
OK, seems I didn't actually link the playground earlier. FML
David
@dvdplm
Dec 03 2017 13:32
@matklad :+1:
Restioson
@Restioson
Dec 03 2017 13:32
Apparently having a default impl that doesn't contain all methods is an error :/
The RFC says it should work, though
The RFC is tagged with implemented...
Whoops accidentally linked to a comment
Mobile feels :(
Sherab Giovannini
@Shaddy
Dec 03 2017 13:35
still fighting with bitflags, if anyone can just put some light I would appreciate
(the issue is just few pharagraphs above)
Restioson
@Restioson
Dec 03 2017 13:37
Maybe that bit isn't impl'd yet. Try doing what rustc recommended? Maybe it in a trait of that
The first sentence Is in reference to my problem, and the rest is in reference to yours @Shaddy
Restioson
@Restioson
Dec 03 2017 13:45
D'you guys think I should post on the users forum about the default impl thing? It's not a syntax error so I'd think k it implemented
Sherab Giovannini
@Shaddy
Dec 03 2017 14:11
my bitflags problem is solved, just versioning problem
Restioson
@Restioson
Dec 03 2017 14:13
Looks like #37653 is gonna impl what I want
Yayy
Grégoire Geis
@71
Dec 03 2017 14:55
Anyone knows how to implement a macro that generates a macro? There's no way to escape $, which leads to some errors when defining delimited macros

For example:

macro_rules! mkprintnames {
    ( $name: ident ) => (macro_rules! $name {
        ( $( $names: expr),* ) => (println!("{}, say hello to {}!", $( $names ),* ));
    });
}

fn main(){
    mkprintnames!(printnames);
    printnames!("Greg", "Gerg");
}

throws:

error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
 --> src/main.rs:4:12
  |
4 |         ( $( $names: expr),* ) => (println!("{}, say hello to {}!", $( $names ),* ));
  |            ^^^^^^^^^^^^^^^

error: Could not compile `playground`.
Aleksey Kladov
@matklad
Dec 03 2017 15:00
@6A not sure that is the proper way to do it, but you can pass $ as an argument to a macro: https://play.rust-lang.org/?gist=3451bea4fbb795fa7ad8e7fe8ae623bb&version=stable
Restioson
@Restioson
Dec 03 2017 15:01
Now I just wait and give a +1 comment.
Grégoire Geis
@71
Dec 03 2017 15:01
@matklad Ah, thanks a lot! I actually tried with the dollar sign being the first argument, but Rust didn't like that.
Restioson
@Restioson
Dec 03 2017 15:01
Maybe a procedural macro for that lol
Ariel Ben-Yehuda
@arielb1
Dec 03 2017 23:15
what's the standard way of having a function work for both I: Iterator<Item=T> and I: Iterator<Item=&T>
assuming the function wants an iterator over &T
*to consume a stream of &T
Mac O'Brien
@cormac-obrien
Dec 03 2017 23:17
I: Iterator<Item=AsRef<T>>?
Ariel Ben-Yehuda
@arielb1
Dec 03 2017 23:21
@cormac-obrien: I don't think AsRef has a diagonal impl
Ryan
@rnleach
Dec 03 2017 23:43
Is the rls in vscode broken for anyone else right now? The last few nightly releases haven't worked for me.