These are chat archives for rust-lang/rust

15th
Dec 2018
Zakarum
@omni-viral
Dec 15 2018 07:30
@tcp9 what?
2018 edition is now default edition.
tcp9
@tcp9
Dec 15 2018 09:46
@omni-viral but when i'm vising https://doc.rust-lang.org/book/2018-edition/ch13-03-improving-our-io-project.html , it shows "The 2018 edition of the book is no longer distributed with Rust's documentation...."
zsugabubus
@zsugabubus
Dec 15 2018 14:16

Hi all! I just don't understand why I (would) have to "repeat" Add bound for &T if trait AddAndAddRefs already requires Add for &Self. Could you explain me this a bit better? Isn't it absolutely redundant?

use std::ops::Add;

trait AddAndAddRefs
where
    Self: Sized + Add<Self, Output = Self>, 
    for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>
{}
impl AddAndAddRefs for i32 {}

struct S<T: AddAndAddRefs>(T);

The error:

error[E0277]: cannot add `&'b T` to `&'a T`
  --> src/main.rs:10:1
   |
10 | struct S<T: AddAndAddRefs>(T);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `&'a T + &'b T`
   |
   = help: the trait `for<'a, 'b> std::ops::Add<&'b T>` is not implemented for `&'a T`
   = help: consider adding a `where for<'a, 'b> &'a T: std::ops::Add<&'b T>` bound
note: required by `AddAndAddRefs`
Zakarum
@omni-viral
Dec 15 2018 14:27
Because where clause on trait works only as predicate on trait and impls. It doesn't add info to the AddAndAddRef
They are not transitive
However you can use trait inheritance syntax instead
zsugabubus
@zsugabubus
Dec 15 2018 14:35
But how I do it with trait inheritance? I want to require something for &Self, not another trait for Self.
Zakarum
@omni-viral
Dec 15 2018 14:58
At most you can implement a method on trait and use it instead of +
zsugabubus
@zsugabubus
Dec 15 2018 15:04
Ehh... I don't want such workarounds
Take the following example:
struct U;
impl Add for U {
    type Output = U;
    fn add(self, _: U) -> U { U }
}

trait AddAndAddRefs
where
    Self: Sized + Add<Self, Output = Self>, 
    for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>
{}
impl AddAndAddRefs for U {}
error[E0277]: cannot add `&'b U` to `&'a U`
  --> src/lib.rs:14:6
   |
14 | impl AddAndAddRefs for U {}
   |      ^^^^^^^^^^^^^ no implementation for `&'a U + &'b U`
   |
   = help: the trait `for<'a, 'b> std::ops::Add<&'b U>` is not implemented for `&'a U`
zsugabubus
@zsugabubus
Dec 15 2018 15:10
So that's why I don't understand why compiler wants me to add a redundant Add bound for T (in my code above). If that doesn't satisfy, I get an error like this, so it's unnecessary to require this bound twice. Doesn't it?
red75prime
@red75prime
Dec 15 2018 16:05
There's no blanket implementation of impl<'a, T> Add<&'a T> for &'a T where T: Add<T> in standard library. You need to implement Add for &U yourself.
Dirk Van Haerenborgh
@vhdirk
Dec 15 2018 18:25
Hi guys. I have a struct Message<'o, Owner> where Owner is generic over the data type that created the message, with lifetime 'o
now, I'd like to implement Drop for Message<>, but only if Owner is a specific type
can that be done?
Akos Vandra
@axos88
Dec 15 2018 18:34
Hi guys. Can someone explain why self.cache() is borrowed at the point where I try to assign Some((4,4)) to it? And how to get around this?
struct Foo {
    cache: Option<(u32, u32)>
}

impl Foo {
    fn bar(&mut self) -> &mut u32 {
        {
            if let Some(ref mut c) = self.cache {
                if (c.1 > 2) {
                    return &mut c.0
                }
            }
        }

        self.cache = Some((4, 4));

        return &mut self.cache.as_mut().unwrap().0
    }
}
Dirk Van Haerenborgh
@vhdirk
Dec 15 2018 18:41
@zsugabubus Thanks. So no explicit specialization of Drop? not even if I require all types to implement a specific trait (say, MessageOwner)?
Akos Vandra
@axos88
Dec 15 2018 18:43
Apparently the following works. What's the difference?
match self.cache {
  Some(ref mut c) if c.1 > 2 => return &mut c.0,
  _ => ()
}
matrixbot
@matrixbot
Dec 15 2018 18:57
bspeice Akos Vandra (Gitter): The compiler message I think should make this clear. Because of the potential for the if let block to return, it captures a borrow there.
zsugabubus
@zsugabubus
Dec 15 2018 18:57
@vhdirk Only if you use MessageOwner as struct Message<O: MessageOwner>. You cannot impl Drop for only a subset of implementations.
Dirk Van Haerenborgh
@vhdirk
Dec 15 2018 18:58
@zsugabubus that's what I do
but let's say I have structs Foo and Bar. Both implement MessageOwner
But I want to have a different drop implementation depending on Foo or Bar. (it's all about c-pointer ownership, really)
zsugabubus
@zsugabubus
Dec 15 2018 19:08
You cannot specialize Drop for Foo or Bar. You have to implement Dropas generic over MessageOwner. (You have to use the same drop for dropping every Message.)
But you can do something like FooMessage and BarMessage and use different Drop implementations.
Dirk Van Haerenborgh
@vhdirk
Dec 15 2018 19:22
@zsugabubus thanks.I suspect rust doesn't (yet) have RTTI?
zsugabubus
@zsugabubus
Dec 15 2018 19:31
Dirk Van Haerenborgh
@vhdirk
Dec 15 2018 19:55
@zsugabubus That's a cool approach. Thanks!
zsugabubus
@zsugabubus
Dec 15 2018 19:57
@vhdirk :thumbsup:
Michal 'vorner' Vaner
@vorner
Dec 15 2018 22:13
Did some significant speedup of rustc and rls land recently in nightly, or is it just me getting more tired and slower today?
David O'Connor
@David-OConnor
Dec 15 2018 22:33
Is there an issue with docs.rs? I've been getting "The requested resource does not exist" when trying to view docs for a package I published. Old versions work, but not the last two versions I've uploaded. Is there a way to view a log, in case there was an error building it? cargo rustdoc runs with no error, and I can view the dosc locally in target/doc
Michal 'vorner' Vaner
@vorner
Dec 15 2018 22:41
https://docs.rs/releases ‒ I guess it just doesn't get to building them lately
maybe it'll catch up later on
David O'Connor
@David-OConnor
Dec 15 2018 23:04
Hmm.. Might be that you have to build with the --release flag before publishing
David O'Connor
@David-OConnor
Dec 15 2018 23:14
I assumed cargo package and cargo publish would automatically build a release version. Perhaps this isn't the case?
David O'Connor
@David-OConnor
Dec 15 2018 23:55

Unrelated: Is there a way to use the regex crate to replace all with arbitrary processing of the thing to be replaced? Eg: using re.replace_all:

let text = "beforeWordsafter more words beforeWords2after etc";

let re = Regex::new(r"before(?P<replace_this>.*)after").unwrap();
let replaced = re.replace_all(text, get_excited("$replace_this"));

// replaced is "beforeWords!after more words beforeWords2!after"

Where we'd get the original text, but with the match groups processed.