Skip to content

Commit f57e6fa

Browse files
committed
compare_predicate_entailment move comment
1 parent 4fe666e commit f57e6fa

File tree

1 file changed

+66
-63
lines changed

1 file changed

+66
-63
lines changed

compiler/rustc_typeck/src/check/compare_method.rs

+66-63
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,72 @@ pub(crate) fn compare_impl_method<'tcx>(
7070
}
7171
}
7272

73+
/// This function is best explained by example. Consider a trait:
74+
///
75+
/// trait Trait<'t, T> {
76+
/// // `trait_m`
77+
/// fn method<'a, M>(t: &'t T, m: &'a M) -> Self;
78+
/// }
79+
///
80+
/// And an impl:
81+
///
82+
/// impl<'i, 'j, U> Trait<'j, &'i U> for Foo {
83+
/// // `impl_m`
84+
/// fn method<'b, N>(t: &'j &'i U, m: &'b N) -> Foo;
85+
/// }
86+
///
87+
/// We wish to decide if those two method types are compatible.
88+
/// For this we have to show that, assuming the bounds of the impl hold, the
89+
/// bounds of `trait_m` imply the bounds of `impl_m`.
90+
///
91+
/// We start out with `trait_to_impl_substs`, that maps the trait
92+
/// type parameters to impl type parameters. This is taken from the
93+
/// impl trait reference:
94+
///
95+
/// trait_to_impl_substs = {'t => 'j, T => &'i U, Self => Foo}
96+
///
97+
/// We create a mapping `dummy_substs` that maps from the impl type
98+
/// parameters to fresh types and regions. For type parameters,
99+
/// this is the identity transform, but we could as well use any
100+
/// placeholder types. For regions, we convert from bound to free
101+
/// regions (Note: but only early-bound regions, i.e., those
102+
/// declared on the impl or used in type parameter bounds).
103+
///
104+
/// impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 }
105+
///
106+
/// Now we can apply `placeholder_substs` to the type of the impl method
107+
/// to yield a new function type in terms of our fresh, placeholder
108+
/// types:
109+
///
110+
/// <'b> fn(t: &'i0 U0, m: &'b) -> Foo
111+
///
112+
/// We now want to extract and substitute the type of the *trait*
113+
/// method and compare it. To do so, we must create a compound
114+
/// substitution by combining `trait_to_impl_substs` and
115+
/// `impl_to_placeholder_substs`, and also adding a mapping for the method
116+
/// type parameters. We extend the mapping to also include
117+
/// the method parameters.
118+
///
119+
/// trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 }
120+
///
121+
/// Applying this to the trait method type yields:
122+
///
123+
/// <'a> fn(t: &'i0 U0, m: &'a) -> Foo
124+
///
125+
/// This type is also the same but the name of the bound region (`'a`
126+
/// vs `'b`). However, the normal subtyping rules on fn types handle
127+
/// this kind of equivalency just fine.
128+
///
129+
/// We now use these substitutions to ensure that all declared bounds are
130+
/// satisfied by the implementation's method.
131+
///
132+
/// We do this by creating a parameter environment which contains a
133+
/// substitution corresponding to `impl_to_placeholder_substs`. We then build
134+
/// `trait_to_placeholder_substs` and use it to convert the predicates contained
135+
/// in the `trait_m` generics to the placeholder form.
136+
///
137+
/// Finally we register each of these predicates as an obligation and check that
138+
/// they hold.
73139
fn compare_predicate_entailment<'tcx>(
74140
tcx: TyCtxt<'tcx>,
75141
impl_m: &ty::AssocItem,
@@ -96,69 +162,6 @@ fn compare_predicate_entailment<'tcx>(
96162
},
97163
);
98164

99-
// This code is best explained by example. Consider a trait:
100-
//
101-
// trait Trait<'t, T> {
102-
// fn method<'a, M>(t: &'t T, m: &'a M) -> Self;
103-
// }
104-
//
105-
// And an impl:
106-
//
107-
// impl<'i, 'j, U> Trait<'j, &'i U> for Foo {
108-
// fn method<'b, N>(t: &'j &'i U, m: &'b N) -> Foo;
109-
// }
110-
//
111-
// We wish to decide if those two method types are compatible.
112-
//
113-
// We start out with trait_to_impl_substs, that maps the trait
114-
// type parameters to impl type parameters. This is taken from the
115-
// impl trait reference:
116-
//
117-
// trait_to_impl_substs = {'t => 'j, T => &'i U, Self => Foo}
118-
//
119-
// We create a mapping `dummy_substs` that maps from the impl type
120-
// parameters to fresh types and regions. For type parameters,
121-
// this is the identity transform, but we could as well use any
122-
// placeholder types. For regions, we convert from bound to free
123-
// regions (Note: but only early-bound regions, i.e., those
124-
// declared on the impl or used in type parameter bounds).
125-
//
126-
// impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 }
127-
//
128-
// Now we can apply placeholder_substs to the type of the impl method
129-
// to yield a new function type in terms of our fresh, placeholder
130-
// types:
131-
//
132-
// <'b> fn(t: &'i0 U0, m: &'b) -> Foo
133-
//
134-
// We now want to extract and substitute the type of the *trait*
135-
// method and compare it. To do so, we must create a compound
136-
// substitution by combining trait_to_impl_substs and
137-
// impl_to_placeholder_substs, and also adding a mapping for the method
138-
// type parameters. We extend the mapping to also include
139-
// the method parameters.
140-
//
141-
// trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 }
142-
//
143-
// Applying this to the trait method type yields:
144-
//
145-
// <'a> fn(t: &'i0 U0, m: &'a) -> Foo
146-
//
147-
// This type is also the same but the name of the bound region ('a
148-
// vs 'b). However, the normal subtyping rules on fn types handle
149-
// this kind of equivalency just fine.
150-
//
151-
// We now use these substitutions to ensure that all declared bounds are
152-
// satisfied by the implementation's method.
153-
//
154-
// We do this by creating a parameter environment which contains a
155-
// substitution corresponding to impl_to_placeholder_substs. We then build
156-
// trait_to_placeholder_substs and use it to convert the predicates contained
157-
// in the trait_m.generics to the placeholder form.
158-
//
159-
// Finally we register each of these predicates as an obligation in
160-
// a fresh FulfillmentCtxt, and invoke select_all_or_error.
161-
162165
// Create mapping from impl to placeholder.
163166
let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id);
164167

0 commit comments

Comments
 (0)