Auto merge of #145608 - Darksonn:derefmut-pin-fix, r=lcnr
Prevent downstream `impl DerefMut for Pin<LocalType>` The safety requirements for [`PinCoerceUnsized`](https://doc.rust-lang.org/stable/std/pin/trait.PinCoerceUnsized.html) are essentially that the type does not have a malicious `Deref` or `DerefMut` impl. However, the `Pin` type is fundamental, so the end-user can provide their own implementation of `DerefMut` for `Pin<&SomeLocalType>`, so it's possible for `Pin` to have a malicious `DerefMut` impl. This unsoundness is known as rust-lang/rust#85099. Unfortunately, this means that the implementation of `PinCoerceUnsized` for `Pin` is currently unsound. To fix that, modify the impl so that it becomes impossible for downstream crates to provide their own implementation of `DerefMut` for `Pin` by abusing a hidden struct that is not fundamental. This PR is a breaking change, but it fixes rust-lang/rust#85099. The PR supersedes rust-lang/rust#144896. r? lcnr
This commit is contained in:
@@ -3476,6 +3476,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
// can do about it. As far as they are concerned, `?` is compiler magic.
|
||||
return;
|
||||
}
|
||||
if tcx.is_diagnostic_item(sym::PinDerefMutHelper, parent_def_id) {
|
||||
let parent_predicate =
|
||||
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
|
||||
|
||||
// Skip PinDerefMutHelper in suggestions, but still show downstream suggestions.
|
||||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
body_id,
|
||||
err,
|
||||
parent_predicate,
|
||||
param_env,
|
||||
&data.derived.parent_code,
|
||||
obligated_types,
|
||||
seen_requirements,
|
||||
)
|
||||
});
|
||||
return;
|
||||
}
|
||||
let self_ty_str =
|
||||
tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
|
||||
let trait_name = tcx.short_string(
|
||||
|
||||
Reference in New Issue
Block a user