These are chat archives for rust-lang/rust

15th
Jun 2017
Sathya Narrayanan
@sourcepirate
Jun 15 2017 01:19
what does proc() in rust do ?
Denis Lisov
@tanriol
Jun 15 2017 09:30
@sourcepirate You question is not clear...
Daan Rijks
@ijks
Jun 15 2017 09:53
@sourcepirate IIRC it's old syntax for closures, so it's not actually in the language anymore. Where did you see it used?
Roman Proskuryakov
@kpp
Jun 15 2017 19:02
Could you please explain why p1 + p2.into() does not work while p1 + &p2.into() does? How can I fix it? https://play.rust-lang.org/?gist=5aeab229c25c42c76ac51032aa6bb63c&version=stable&backtrace=1
stevensonmt
@stevensonmt
Jun 15 2017 19:40
// T + T
impl Add for Position {
    type Output = Position;
    fn add(self, other: Position) -> Position {
        Position { x: self.x + other.x, y: self.y + other.y }
    }
}
// T + &T
impl<'a> Add<&'a Position> for Position {
    type Output = Position;
    fn add(self, other: &'a Position) -> Position {
        Position { x: self.x + other.x, y: self.y + other.y }
    }
}
You defined Add twice. If you comment out or delete the second definition there is no error for p1 + p2.into().
Roman Proskuryakov
@kpp
Jun 15 2017 19:42
Well, If I comment out it works. But I want 2 implementations, 1 for T+T and the second for T+&T
Similar to macro_rules! add_impland forward_ref_binop!
Roman Proskuryakov
@kpp
Jun 15 2017 19:56
and the problem is not in defining Add twice. Here is the working example with no need to delete the second definition:
    let p1 = Position { x: 1, y: 2 };
    let p2 = WalkPosition { x: 1, y: 2 };
    let p3: Position = p2.into();
    let p4 = p1 + p3;
stevensonmt
@stevensonmt
Jun 15 2017 19:57
You are right, sorry.
Scott Corbeil
@scorbeil
Jun 15 2017 20:13
Can someone explain how to fix this?
fn main() {
    println!("compiled")
}

fn make_fn_once<F>(f: F) -> Box<FnOnce(&mut i32)->i32>
    where
        F: 'static + FnMut(&mut i32) -> i32
{
    Box::new(move |ref mut arg: &mut i32| f(arg))
}
rustc 1.18.0 (03fc9d622 2017-06-06)
error: cannot borrow immutable captured outer variable in an `FnOnce` closure `f` as mutable
 --> <anon>:9:43
  |
9 |     Box::new(move |ref mut arg: &mut i32| f(arg))
  |                                           ^

error: aborting due to previous error
Roman Proskuryakov
@kpp
Jun 15 2017 20:19
FnOnce - A version of the call operator that takes a by-value receiver.
while FnMut - A version of the call operator that takes a mutable receiver.
So you want to cast &mut i32 -> i32, which does not make sense
Scott Corbeil
@scorbeil
Jun 15 2017 20:20
I don't want to cast it. I want to wrap it. So I want the FnOnce to own the FnMut. Is that not what I'm expressing here? Is it even possible?
Denis Lisov
@tanriol
Jun 15 2017 20:23
@scorbeil Maybe fn make_fn_once<F>(mut f: F) -> ... { ... } ?
Scott Corbeil
@scorbeil
Jun 15 2017 20:24
That did it. Thanks @tanriol !
Roman Proskuryakov
@kpp
Jun 15 2017 20:42
Well, let p3: Position = p1 + Into::<Position>::into(p2); works. But how can I teach it to interfere the type?
And why p2.into() fails while &(p2.into()) is okay?
Denis Lisov
@tanriol
Jun 15 2017 20:47
@kpp Just guessing, but it looks like type inference needs to infer the type without knowing the exact set of Into conversions available. Thus this would be ambiguous if you had both Into<Position> and Into<&'a Position>...
Roman Proskuryakov
@kpp
Jun 15 2017 20:49
Lets have a look at:
    let p1 = Position { x: 1, y: 2 };
    let p2 = WalkPosition { x: 1, y: 2 };
    let p3 = p2.into();
    let p4: Position = p1 + p3;

   |
37 |     let p3 = p2.into();
   |         ^^
   |         |
   |         consider giving `p3` a type
   |         cannot infer type for `_`
But let p3: Position = p1 + &p3; fixes it
It completly blows out my mind
type inference needs to infer the type without knowing the exact set of Into conversions available
It seems fair both for p3 and &p3 but the second one works
Why?
Denis Lisov
@tanriol
Jun 15 2017 20:59
Because with &p3 it's definitely not the impl Add<Position> for Position (&p3 is a reference, not a Position) and thus there's only one impl left.
Roman Proskuryakov
@kpp
Jun 15 2017 21:00
Nice. Thanks!
So my Add is okay, right? Is the problem only in interpreting how Intoand type interference works?
stevensonmt
@stevensonmt
Jun 15 2017 21:07
@kpp did you look at rust-lang/rust#35738
Roman Proskuryakov
@kpp
Jun 15 2017 21:11
woah
It would be nice to add a compiler warning reporting such problems. Is it possible to implement?
stevensonmt
@stevensonmt
Jun 15 2017 21:19
fn main() {
    let p1 = Position { x: 1, y: 2 };
    let p2 = WalkPosition { x: 1, y: 2 };
    let p3: Position = p1 + (p2.into(): Position);
}
error: type ascription is experimental (see issue #23416)
If using the nightly that allows type ascription it should otherwise work, I think.
Roman Proskuryakov
@kpp
Jun 15 2017 21:21
event nightly requires to #![feature(type_ascription)]
but it works, thanks
stevensonmt
@stevensonmt
Jun 15 2017 21:21
yes, that's true.
stevensonmt
@stevensonmt
Jun 15 2017 21:39
Without using type_ascription:
fn main() {
    let p1 = Position { x: 1, y: 2 };
    let p2 = WalkPosition { x: 1, y: 2 };
    let p3: Position = p1 + Into::<Position>::into(p2);
}
stevensonmt
@stevensonmt
Jun 15 2017 21:46
Or even better:
fn main() {
    let p1 = Position { x: 1, y: 2 };
    let p2: Position = WalkPosition { x: 1, y: 2 }.into();
    let p3: Position = p1 + p2;
}
Roman Proskuryakov
@kpp
Jun 15 2017 21:48
I prefer let p3 = p1 + Position::from(p2);
Thanks
stevensonmt
@stevensonmt
Jun 15 2017 21:48
Nice.