35191


RustでDeref時の優先度について質問です。

[code]

    pub trait T {
        fn func(self);
    }
    
    pub struct A {}
    
    impl<'a> T for &'a A {
        fn func(self) {
            println!("impl &A");
        }
    }
    
    impl<'a> T for &'a mut A {
        fn func(self) {
            println!("impl &mut A");
        }
    }
    
    fn main() {
        let mut a = A {};
        a.func();
    }
    
[/code]

以上のコードは実行すると

[code]

    impl &A
    
[/code]

と表示され`impl T for &A {}`の`func()`が実行されていることが確認できます。ここで`impl T for &A
{}`の部分を削除すると出力が

[code]

    impl &mut A
    
[/code]

となります。つまり`a.func()`は`<&A as T>::func(&a)`と`<&mut A as T>::func(&mut
a)`の両方の解釈が可能ですが、実際には前者として扱います。

これはRustが暗黙の型変換において`&mut A`よりも`&A`を優先しているように解釈したのですが、これは言語仕様で決まっているのでしょうか？


CC BY-SA 3.0
2017-06-01T10:06:10.357
35189
2017-06-01T10:44:18.253
9572
question
rust
メソッド呼び出し時のDerefの優先度


[RFC 0048](https://github.com/rust-
lang/rfcs/blob/master/text/0048-traits.md)によっておおよそ説明できそうです。これによると、メソッド呼び出しの解決は
トレイトの解決 (`METHOD_SEARCH`) とそのトレイトのレシーバ型に対する調整 (`RECONCILE`) の2段階からなるようですが、
`RECONCILE` では `&mut` よりも `&` が優先的に検索されています。

このRFCではOP主の例のように同じレシーバー型、同じトレイトに対して複数の実装があるケースを考慮していないようですが、この状況については[このSOの質問](https://stackoverflow.com/questions/28519997/what-
are-rusts-exact-auto-dereferencing-
rules)が参考になりそうです。この質問のOP主は「`&T`の`self`は、`T`の`&self`と同様に扱われる」(抄訳。おそらくミスタイプと思われたため原文の`&T`と`T`を入れ替えた)と予想しています。Accepted
Answer主はOP主の予想をほぼ肯定しており、Niko
Matsakis氏にもチェックしてもらったと書いてあるので、これはある程度権威的な情報源と言えるかと思います。

なお、Rust Referenceには関連する情報は今のところ執筆されていないようです。


CC BY-SA 3.0
2017-06-01T10:44:18.253
35191
2017-06-01T10:44:18.253
8568
35189
answer