# Error code E0207

A type, const or lifetime parameter that is specified for `impl` is not constrained.

Erroneous code example:

    #![allow(unused)]
    fn main() {
    struct Foo;

    impl<T: Default> Foo {
        // error: the type parameter `T` is not constrained by the impl trait, self
        // type, or predicates [E0207]
        fn get(&self) -> T {
            <T as Default>::default()
        }
    }
    }

Any type or const parameter of an `impl` must meet at least one of the following criteria:

- it appears in the implementing type of the impl, e.g. `impl<T> Foo<T>`
- for a trait impl, it appears in the implemented trait, e.g. `impl<T> SomeTrait<T> for Foo`
- it is bound as an associated type, e.g. `impl<T, U> SomeTrait for T where T: AnotherTrait<AssocType=U>`

Any unconstrained lifetime parameter of an `impl` is not supported if the lifetime parameter is used by an associated type.

### Error example 1

Suppose we have a struct `Foo` and we would like to define some methods for it. The previous code example has a definition which leads to a compiler error:

The problem is that the parameter `T` does not appear in the implementing type (`Foo`) of the impl. In this case, we can fix the error by moving the type parameter from the `impl` to the method `get`:

    #![allow(unused)]
    fn main() {
    struct Foo;

    // Move the type parameter from the impl to the method
    impl Foo {
        fn get<T: Default>(&self) -> T {
            <T as Default>::default()
        }
    }
    }

### Error example 2

As another example, suppose we have a `Maker` trait and want to establish a type `FooMaker` that makes `Foo`s:

    #![allow(unused)]
    fn main() {
    trait Maker {
        type Item;
        fn make(&mut self) -> Self::Item;
    }

    struct Foo<T> {
        foo: T
    }

    struct FooMaker;

    impl<T: Default> Maker for FooMaker {
    // error: the type parameter `T` is not constrained by the impl trait, self
    // type, or predicates [E0207]
        type Item = Foo<T>;

        fn make(&mut self) -> Foo<T> {
            Foo { foo: <T as Default>::default() }
        }
    }
    }

This fails to compile because `T` does not appear in the trait or in the implementing type.

One way to work around this is to introduce a phantom type parameter into `FooMaker`, like so:

    #![allow(unused)]
    fn main() {
    use std::marker::PhantomData;

    trait Maker {
        type Item;
        fn make(&mut self) -> Self::Item;
    }

    struct Foo<T> {
        foo: T
    }

    // Add a type parameter to `FooMaker`
    struct FooMaker<T> {
        phantom: PhantomData<T>,
    }

    impl<T: Default> Maker for FooMaker<T> {
        type Item = Foo<T>;

        fn make(&mut self) -> Foo<T> {
            Foo {
                foo: <T as Default>::default(),
            }
        }
    }
    }

Another way is to do away with the associated type in `Maker` and use an input type parameter instead:

    #![allow(unused)]
    fn main() {
    // Use a type parameter instead of an associated type here
    trait Maker<Item> {
        fn make(&mut self) -> Item;
    }

    struct Foo<T> {
        foo: T
    }

    struct FooMaker;

    impl<T: Default> Maker<Foo<T>> for FooMaker {
        fn make(&mut self) -> Foo<T> {
            Foo { foo: <T as Default>::default() }
        }
    }
    }

### Error example 3

Suppose we have a struct `Foo` and we would like to define some methods for it. The following code example has a definition which leads to a compiler error:

    #![allow(unused)]
    fn main() {
    struct Foo;

    impl<const T: i32> Foo {
        // error: the const parameter `T` is not constrained by the impl trait, self
        // type, or predicates [E0207]
        fn get(&self) -> i32 {
            i32::default()
        }
    }
    }

The problem is that the const parameter `T` does not appear in the implementing type (`Foo`) of the impl. In this case, we can fix the error by moving the type parameter from the `impl` to the method `get`:

    #![allow(unused)]
    fn main() {
    struct Foo;

    // Move the const parameter from the impl to the method
    impl Foo {
        fn get<const T: i32>(&self) -> i32 {
            i32::default()
        }
    }
    }

### Error example 4

Suppose we have a struct `Foo` and a struct `Bar` that uses lifetime `'a`. We would like to implement trait `Contains` for `Foo`. The trait `Contains` have the associated type `B`. The following code example has a definition which leads to a compiler error:

    #![allow(unused)]
    fn main() {
    struct Foo;
    struct Bar<'a>;

    trait Contains {
        type B;

        fn get(&self) -> i32;
    }

    impl<'a> Contains for Foo {
        type B = Bar<'a>;

        // error: the lifetime parameter `'a` is not constrained by the impl trait,
        // self type, or predicates [E0207]
        fn get(&self) -> i32 {
            i32::default()
        }
    }
    }

Please note that unconstrained lifetime parameters are not supported if they are being used by an associated type.

### Additional information

For more information, please see RFC 447.