Rollup merge of #72194 - doctorn:dispatch-from-dyn-ice, r=estebank
Don't ICE on missing `Unsize` impl Previously code of the form ```rust #![feature(unsize, dispatch_from_dyn)] use std::marker::Unsize; use std::ops::DispatchFromDyn; pub struct Foo<'a, T: ?Sized> { _inner: &'a &'a T, } impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T> {} ``` would generate an ICE due to the missing `Unsize` impl being run through the `suggest_change_mut` suggestion. This PR adds an early exit and a pointer to the appropriate docs regarding `Unsize` instead: ``` error[E0277]: the trait bound `&'a T: std::marker::Unsize<&'a U>` is not satisfied --> src/test/ui/issues/issue-71036.rs:11:1 | 11 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unsize<&'a U>` is not implemented for `&'a T` | = note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information = note: required because of the requirements on the impl of `std::ops::DispatchFromDyn<&'a &'a U>` for `&'a &'a T` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. ``` r? @estebank Resolves #71036
This commit is contained in:
commit
7b5bc61e99
@ -283,6 +283,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
.unwrap_or(false);
|
||||
let is_from = format!("{}", trait_ref.print_only_trait_path())
|
||||
.starts_with("std::convert::From<");
|
||||
let is_unsize =
|
||||
{ Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait() };
|
||||
let (message, note) = if is_try && is_from {
|
||||
(
|
||||
Some(format!(
|
||||
@ -405,6 +407,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
if is_unsize {
|
||||
// If the obligation failed due to a missing implementation of the
|
||||
// `Unsize` trait, give a pointer to why that might be the case
|
||||
err.note(
|
||||
"all implementations of `Unsize` are provided \
|
||||
automatically by the compiler, see \
|
||||
<https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> \
|
||||
for more information",
|
||||
);
|
||||
}
|
||||
|
||||
// Try to report a help message
|
||||
if !trait_ref.has_infer_types_or_consts()
|
||||
&& self.predicate_can_apply(obligation.param_env, trait_ref)
|
||||
@ -427,6 +440,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
|
||||
self.report_similar_impl_candidates(impl_candidates, &mut err);
|
||||
}
|
||||
// Changing mutability doesn't make a difference to whether we have
|
||||
// an `Unsize` impl (Fixes ICE in #71036)
|
||||
if !is_unsize {
|
||||
self.suggest_change_mut(
|
||||
&obligation,
|
||||
&mut err,
|
||||
@ -434,6 +450,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
points_at_arg,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If this error is due to `!: Trait` not implemented but `(): Trait` is
|
||||
// implemented, and fallback has occurred, then it could be due to a
|
||||
|
17
src/test/ui/issues/issue-71036.rs
Normal file
17
src/test/ui/issues/issue-71036.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#![feature(unsize, dispatch_from_dyn)]
|
||||
|
||||
use std::marker::Unsize;
|
||||
use std::ops::DispatchFromDyn;
|
||||
|
||||
#[allow(unused)]
|
||||
struct Foo<'a, T: ?Sized> {
|
||||
_inner: &'a &'a T,
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T> {}
|
||||
//~^ ERROR the trait bound `&'a T: std::marker::Unsize<&'a U>` is not satisfied
|
||||
//~| NOTE the trait `std::marker::Unsize<&'a U>` is not implemented for `&'a T`
|
||||
//~| NOTE all implementations of `Unsize` are provided automatically by the compiler
|
||||
//~| NOTE required because of the requirements on the impl
|
||||
|
||||
fn main() {}
|
12
src/test/ui/issues/issue-71036.stderr
Normal file
12
src/test/ui/issues/issue-71036.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0277]: the trait bound `&'a T: std::marker::Unsize<&'a U>` is not satisfied
|
||||
--> $DIR/issue-71036.rs:11:1
|
||||
|
|
||||
LL | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unsize<&'a U>` is not implemented for `&'a T`
|
||||
|
|
||||
= note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
|
||||
= note: required because of the requirements on the impl of `std::ops::DispatchFromDyn<&'a &'a U>` for `&'a &'a T`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user