Rollup merge of #115629 - compiler-errors:sugg-deref-unsize, r=oli-obk
Don't suggest dereferencing to unsized type Rudimentary check that the self type is Sized. I don't really like any of this diagnostics code -- it's really messy and also really prone to false positives and negatives, but oh well. Fixes #115569
This commit is contained in:
commit
38adedc598
23 changed files with 61 additions and 14 deletions
|
@ -1250,21 +1250,18 @@ pub trait PrettyPrinter<'tcx>:
|
||||||
.generics_of(principal.def_id)
|
.generics_of(principal.def_id)
|
||||||
.own_args_no_defaults(cx.tcx(), principal.args);
|
.own_args_no_defaults(cx.tcx(), principal.args);
|
||||||
|
|
||||||
let mut projections = predicates.projection_bounds();
|
let mut projections: Vec<_> = predicates.projection_bounds().collect();
|
||||||
|
projections.sort_by_cached_key(|proj| {
|
||||||
let mut args = args.iter().cloned();
|
cx.tcx().item_name(proj.item_def_id()).to_string()
|
||||||
let arg0 = args.next();
|
});
|
||||||
let projection0 = projections.next();
|
|
||||||
if arg0.is_some() || projection0.is_some() {
|
|
||||||
let args = arg0.into_iter().chain(args);
|
|
||||||
let projections = projection0.into_iter().chain(projections);
|
|
||||||
|
|
||||||
|
if !args.is_empty() || !projections.is_empty() {
|
||||||
p!(generic_delimiters(|mut cx| {
|
p!(generic_delimiters(|mut cx| {
|
||||||
cx = cx.comma_sep(args)?;
|
cx = cx.comma_sep(args.iter().copied())?;
|
||||||
if arg0.is_some() && projection0.is_some() {
|
if !args.is_empty() && !projections.is_empty() {
|
||||||
write!(cx, ", ")?;
|
write!(cx, ", ")?;
|
||||||
}
|
}
|
||||||
cx.comma_sep(projections)
|
cx.comma_sep(projections.iter().copied())
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -838,7 +838,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
real_trait_pred_and_base_ty,
|
real_trait_pred_and_base_ty,
|
||||||
);
|
);
|
||||||
if self.predicate_may_hold(&obligation) {
|
let sized_obligation = Obligation::new(
|
||||||
|
self.tcx,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.param_env,
|
||||||
|
ty::TraitRef::from_lang_item(
|
||||||
|
self.tcx,
|
||||||
|
hir::LangItem::Sized,
|
||||||
|
obligation.cause.span,
|
||||||
|
[base_ty],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if self.predicate_may_hold(&obligation)
|
||||||
|
&& self.predicate_must_hold_modulo_regions(&sized_obligation)
|
||||||
|
{
|
||||||
let call_node = self.tcx.hir().get(*call_hir_id);
|
let call_node = self.tcx.hir().get(*call_hir_id);
|
||||||
let msg = "consider dereferencing here";
|
let msg = "consider dereferencing here";
|
||||||
let is_receiver = matches!(
|
let is_receiver = matches!(
|
||||||
|
|
|
@ -7,7 +7,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
|
||||||
|
|
||||||
fn transmute<A, B>(x: A) -> B {
|
fn transmute<A, B>(x: A) -> B {
|
||||||
foo::<A, B, dyn Trait<A = A, B = B>>(x)
|
foo::<A, B, dyn Trait<A = A, B = B>>(x)
|
||||||
//~^ ERROR type mismatch resolving `<dyn Trait<B = B, A = A> as SuperTrait>::A == B`
|
//~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<A, B, T: ?Sized>(x: T::A) -> B
|
fn foo<A, B, T: ?Sized>(x: T::A) -> B
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0271]: type mismatch resolving `<dyn Trait<B = B, A = A> as SuperTrait>::A == B`
|
error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
|
||||||
--> $DIR/enforce-supertrait-projection.rs:9:17
|
--> $DIR/enforce-supertrait-projection.rs:9:17
|
||||||
|
|
|
|
||||||
LL | fn transmute<A, B>(x: A) -> B {
|
LL | fn transmute<A, B>(x: A) -> B {
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
fn use_iterator<I>(itr: I)
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = i32>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pass_iterator<I>(i: &dyn IntoIterator<Item = i32, IntoIter = I>)
|
||||||
|
where
|
||||||
|
I: Iterator<Item = i32>,
|
||||||
|
{
|
||||||
|
use_iterator(i);
|
||||||
|
//~^ ERROR `&dyn IntoIterator<IntoIter = I, Item = i32>` is not an iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
error[E0277]: `&dyn IntoIterator<IntoIter = I, Item = i32>` is not an iterator
|
||||||
|
--> $DIR/dont-suggest-unsize-deref.rs:11:18
|
||||||
|
|
|
||||||
|
LL | use_iterator(i);
|
||||||
|
| ------------ ^ `&dyn IntoIterator<IntoIter = I, Item = i32>` is not an iterator
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Iterator` is not implemented for `&dyn IntoIterator<IntoIter = I, Item = i32>`
|
||||||
|
= note: required for `&dyn IntoIterator<IntoIter = I, Item = i32>` to implement `IntoIterator`
|
||||||
|
note: required by a bound in `use_iterator`
|
||||||
|
--> $DIR/dont-suggest-unsize-deref.rs:3:8
|
||||||
|
|
|
||||||
|
LL | fn use_iterator<I>(itr: I)
|
||||||
|
| ------------ required by a bound in this function
|
||||||
|
LL | where
|
||||||
|
LL | I: IntoIterator<Item = i32>,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `use_iterator`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue