error[E0599]: no method named `method` found for struct `MyType` in the current scope

error[E0599]: the method `method` exists for struct `MyType<Xxx>`, but its trait bounds were not satisfied

無効なメソッドの呼出を行った。

パターン

パターン A

基本形

対象のメソッドが型にそもそもないパターン。

サンプル

以下では、型 MyValue にメソッド method が存在しない。


fn main() {
    let value = MyValue();
    value.method();
}

struct MyValue();

error[E0599]: no method named `method` found for struct `MyValue` in the current scope
 --> src\main.rs:3:11
  |
3 |     value.method();
  |           ^^^^^^ method not found in `MyValue`
...
6 | struct MyValue();
  | -------------- method `method` not found for this struct

パターン B

変数の隠蔽

対象のメソッドを持つ変数が同名の変数で隠蔽されているパターン。

サンプル


fn main() {
    let x = MyTypeX();
    let x = x.conv();
    x.method_of_x();
}

struct MyTypeX();
struct MyTypeY();

impl MyTypeX {
    pub fn conv(self) -> MyTypeY {
        MyTypeY()
    }

    pub fn method_of_x(&self) {
        // nop.
    }
}

error[E0599]: no method named `method_of_x` found for struct `MyTypeY` in the current scope
 --> src\main.rs:4:7
  |
4 |     x.method_of_x();
  |       ^^^^^^^^^^^ method not found in `MyTypeY`
...
8 | struct MyTypeY();
  | -------------- method `method_of_x` not found for this struct
  |
note: there's an earlier shadowed binding `x` of type `MyTypeX` that has method `method_of_x` available
 --> src\main.rs:2:9
  |
2 |     let x = MyTypeX();
  |         ^ `x` of type `MyTypeX` that has method `method_of_x` defined earlier here
3 |     let x = x.conv();
  |         - earlier `x` shadowed here with type `MyTypeY`

パターン C

関連関数との取り違え

対象のメソッドが型になく、代わりに同名の関連関数があるパターン。

サンプル


fn main() {
    let ret = MyType(42).add(1);
    assert_eq!(ret, MyType(43))
}

#[derive(PartialEq)]
struct MyType(i32);

impl MyType {
    pub fn add(x: Self, value: i32) -> Self {
        Self(x.0 + value)
    }
}

error[E0599]: no method named `add` found for struct `MyType` in the current scope
  --> src\main.rs:2:26
   |
 2 |     let ret = MyType(42).add(1);
   |               -----------^^^---
   |               |          |
   |               |          this is an associated function, not a method
   |               help: use associated function syntax instead: `MyType::add(MyType(42), 1)`
...
 7 | struct MyType(i32);
   | ------------- method `add` not found for this struct
   |
   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in an impl for the type `MyType`
  --> src\main.rs:10:5
   |
10 |     pub fn add(x: Self, value: i32) -> Self {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `add`, perhaps you need to implement it:
           candidate #1: `Add`

パターン D1

境界への不適合 (通常版)

対象のメソッドは型にあるが、境界に適合しないパターン。

サンプル

以下では、型 MyValue<T> にメソッド print_binary があるが、境界に適合せず呼べない。なぜなら、型パラメタ T に割り当てられた型は bool であり、これは TUpperHex を実装すべきとした実装時の境界に違反する。


use std::fmt::UpperHex;

fn main() {
    let value = MyValue(true);
    value.print_binary();
}

struct MyValue<T>(T);
impl<T: UpperHex> MyValue<T> {
    fn print_binary(&self) {
        println!("{:X}", self.0)
    }
}

error[E0599]: the method `print_binary` exists for struct `MyValue<bool>`, but its trait bounds were not satisfied
 --> src\main.rs:5:11
  |
5 |     value.print_binary();
  |           ^^^^^^^^^^^^ method cannot be called on `MyValue<bool>` due to unsatisfied trait bounds
...
8 | struct MyValue<T>(T);
  | ----------------- method `print_binary` not found for this struct
  |
note: trait bound `bool: UpperHex` was not satisfied
 --> src\main.rs:9:9
  |
9 | impl<T: UpperHex> MyValue<T> {
  |         ^^^^^^^^  ----------
  |         |
  |         unsatisfied trait bound introduced here

パターン D2

境界への不適合 (derive 属性版)

対象のメソッドは型にあるが、そのメソッドが derive 属性で実装されたトレイトのメソッドであり、その境界に適合しないパターン。

derive 属性 - 型パラメタの影響』で紹介する通り、derive 属性は型パラメタについての境界を導入する場合が多い。この境界に違反するとエラーになる。なお、下記のサンプルではエラーメッセージがその境界 T: Default について指摘しているが、ソース中に該当箇所が存在しない。そのため、混乱しやすい。

サンプル

以下では、MyVec<T>Deault の実装は derive 属性に由来するため、T: Default の境界を持つ。しかし、MyVec::<T>::default() における TClone しか実装していない。


fn main() {
    let values = values(1, 3);
    assert_eq!(values.0, vec![1, 1, 1]);
}

fn values<T: Clone>(value: T, len: usize) -> MyVec<T> {
    let mut ret = MyVec::<T>::default();
    for _ in 0..len {
        ret.0.push(value.clone());
    }

    ret
}

#[derive(Default, Clone, PartialEq)]
struct MyVec<T>(Vec<T>);

error[E0599]: the function or associated item `default` exists for struct `MyVec<T>`, but its trait bounds were not satisfied
  --> src\main.rs:7:31
   |
 7 |     let mut ret = MyVec::<T>::default();
   |                               ^^^^^^^ function or associated item cannot be called on `MyVec<T>` due to unsatisfied trait bounds
...
16 | struct MyVec<T>(Vec<T>);
   | --------------- function or associated item `default` not found for this struct because it doesn't satisfy `MyVec<T>: Default`
   |
note: trait bound `T: Default` was not satisfied
  --> src\main.rs:15:10
   | 
15 | #[derive(Default, Clone, PartialEq)]
   |          ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
help: consider restricting the type parameter to satisfy the trait bound
   |
 6 | fn values<T: Clone>(value: T, len: usize) -> MyVec<T> where T: Default {
   |                                                       ++++++++++++++++

パターン E

HRTB を期待する型推論

HRTB - 型推論』で紹介する通り、HRTB を含んだ型は型推論できない。

そのため、型推論により型が決定された変数は、HRTB を境界とする実装に適合しない。

サンプル

以下では、MyType<T>::method を呼ぶには、型パラメタ T が HRTB を含んだ境界を満たす必要がある。しかし、_ による型推論は、通常のライフタイム注釈しか推論できない。


fn main() {
    let var = MyType(|_| {});
	var.method();
}

struct MyType<T>(T);
impl<T> MyType<T> where T: Fn(&i32) {
    fn method(&self) {}
}

error[E0599]: no method named `method` found for struct `MyType<{closure@src\main.rs:2:22: 2:25}>` in the current scope
 --> src\main.rs:3:9
  |
3 |     var.method();
  |         ^^^^^^ method not found in `MyType<{closure@main.rs:2:22}>`
...
6 | struct MyType<T>(T);
  | ---------------- method `method` not found for this struct
  |
  = note: the method was found for
          - `MyType<T>`

解決策

HRTB を期待する箇所の参照を推論せずに明示するとよい。


fn main() {
    let var = MyType(|_arg: &_| {});
    var.method();
}

struct MyType<T>(T);
impl<T> MyType<T> where T: Fn(&i32) {
    fn method(&self) {}
}