debug!("coerce: unsize successful");
return unsize;
}
- Err(TypeError::ObjectUnsafeCoercion(did)) => {
- debug!("coerce: unsize not object safe");
- return Err(TypeError::ObjectUnsafeCoercion(did));
- }
Err(error) => {
debug!(?error, "coerce: unsize failed");
}
target = self.shallow_resolve(target);
debug!(?source, ?target);
- // These 'if' statements require some explanation.
- // The `CoerceUnsized` trait is special - it is only
- // possible to write `impl CoerceUnsized<B> for A` where
- // A and B have 'matching' fields. This rules out the following
- // two types of blanket impls:
- //
- // `impl<T> CoerceUnsized<T> for SomeType`
- // `impl<T> CoerceUnsized<SomeType> for T`
- //
- // Both of these trigger a special `CoerceUnsized`-related error (E0376)
- //
- // We can take advantage of this fact to avoid performing unnecessary work.
- // If either `source` or `target` is a type variable, then any applicable impl
- // would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`)
- // or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for
- // SomeType`).
- //
- // However, these are exactly the kinds of impls which are forbidden by
- // the compiler! Therefore, we can be sure that coercion will always fail
- // when either the source or target type is a type variable. This allows us
- // to skip performing any trait selection, and immediately bail out.
+ // We don't apply any coercions incase either the source or target
+ // aren't sufficiently well known but tend to instead just equate
+ // them both.
if source.is_ty_var() {
debug!("coerce_unsized: source is a TyVar, bailing out");
return Err(TypeError::Mismatch);
// Special-case that coercion alone cannot handle:
// Function items or non-capturing closures of differing IDs or InternalSubsts.
let (a_sig, b_sig) = {
- #[allow(rustc::usage_of_ty_tykind)]
- let is_capturing_closure = |ty: &ty::TyKind<'tcx>| {
- if let &ty::Closure(closure_def_id, _substs) = ty {
+ let is_capturing_closure = |ty: Ty<'tcx>| {
+ if let &ty::Closure(closure_def_id, _substs) = ty.kind() {
self.tcx.upvars_mentioned(closure_def_id.expect_local()).is_some()
} else {
false
}
};
- if is_capturing_closure(prev_ty.kind()) || is_capturing_closure(new_ty.kind()) {
+ if is_capturing_closure(prev_ty) || is_capturing_closure(new_ty) {
(None, None)
} else {
match (prev_ty.kind(), new_ty.kind()) {