Simon
Simon

Reputation: 553

Traits with parameterized associated types

I come from a C++ background and was wondering if I could code up a trait for use in the foo and bar functions:

#![feature(alloc)]

use std::rc::{Rc, Weak};

pub trait MyTrait {
    /// Value type
    type VAL;
    /// Strongly boxed type
    /// Will be constrained to something like Box, Rc, Arc
    type SB;
    /// Weakly boxed type
    type WB;
}

struct MyFoo;

impl MyTrait for MyFoo {
    type VAL = i64;
    type SB = Rc<i64>;
    type WB = Weak<i64>;
}

fn foo<T: MyTrait>(value: T::VAL) {}
// Uncomment
// fn bar<T: MyTrait>(rc_val: T::SB<T::VAL>) {}

fn main() {
    let x = 100 as i64;
    let y = Rc::new(200 as i64);
    foo::<MyFoo>(x);
    // Uncomment
    // bar::<MyFoo>(y);

    println!("Hello, world!");
}

foo works, but the nested type argument rc_val in bar causes problems:

error[E0109]: type parameters are not allowed on this type
  --> src/main.rs:25:34
   |
25 | fn bar<T: MyTrait>(rc_val: T::SB<T::VAL>) {}
   |                                  ^^^^^^ type parameter not allowed

I saw something about this on the IRC channel related to Higher Kinded Types, but I'm not that familiar with functional programming. Can someone suggest a workaround for what I'm trying to do here? This code was tested in the playground with the nightly build.

Upvotes: 2

Views: 606

Answers (1)

huon
huon

Reputation: 102236

The design means that you should be able to just write

fn bar<T: MyTrait>(rc_val: T::SB) {}

The trait implementation of MyTrait for MyFoo already specifies the type parameter for SB.

If you want to connect SB and VAL, one can place trait bounds on SB, e.g.:

trait MyTrait {
    type VAL;
    type SB: Deref<Target = Self::VAL>;
}

Upvotes: 5

Related Questions