Skip to content

Commit 38adedc

Browse files
authored
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
2 parents bef5187 + 3bf3dad commit 38adedc

23 files changed

+61
-14
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -1250,21 +1250,18 @@ pub trait PrettyPrinter<'tcx>:
12501250
.generics_of(principal.def_id)
12511251
.own_args_no_defaults(cx.tcx(), principal.args);
12521252

1253-
let mut projections = predicates.projection_bounds();
1254-
1255-
let mut args = args.iter().cloned();
1256-
let arg0 = args.next();
1257-
let projection0 = projections.next();
1258-
if arg0.is_some() || projection0.is_some() {
1259-
let args = arg0.into_iter().chain(args);
1260-
let projections = projection0.into_iter().chain(projections);
1253+
let mut projections: Vec<_> = predicates.projection_bounds().collect();
1254+
projections.sort_by_cached_key(|proj| {
1255+
cx.tcx().item_name(proj.item_def_id()).to_string()
1256+
});
12611257

1258+
if !args.is_empty() || !projections.is_empty() {
12621259
p!(generic_delimiters(|mut cx| {
1263-
cx = cx.comma_sep(args)?;
1264-
if arg0.is_some() && projection0.is_some() {
1260+
cx = cx.comma_sep(args.iter().copied())?;
1261+
if !args.is_empty() && !projections.is_empty() {
12651262
write!(cx, ", ")?;
12661263
}
1267-
cx.comma_sep(projections)
1264+
cx.comma_sep(projections.iter().copied())
12681265
}));
12691266
}
12701267
}

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
838838
obligation.param_env,
839839
real_trait_pred_and_base_ty,
840840
);
841-
if self.predicate_may_hold(&obligation) {
841+
let sized_obligation = Obligation::new(
842+
self.tcx,
843+
obligation.cause.clone(),
844+
obligation.param_env,
845+
ty::TraitRef::from_lang_item(
846+
self.tcx,
847+
hir::LangItem::Sized,
848+
obligation.cause.span,
849+
[base_ty],
850+
),
851+
);
852+
if self.predicate_may_hold(&obligation)
853+
&& self.predicate_must_hold_modulo_regions(&sized_obligation)
854+
{
842855
let call_node = self.tcx.hir().get(*call_hir_id);
843856
let msg = "consider dereferencing here";
844857
let is_receiver = matches!(

tests/ui/traits/object/enforce-supertrait-projection.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
77

88
fn transmute<A, B>(x: A) -> B {
99
foo::<A, B, dyn Trait<A = A, B = B>>(x)
10-
//~^ ERROR type mismatch resolving `<dyn Trait<B = B, A = A> as SuperTrait>::A == B`
10+
//~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
1111
}
1212

1313
fn foo<A, B, T: ?Sized>(x: T::A) -> B

tests/ui/traits/object/enforce-supertrait-projection.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0271]: type mismatch resolving `<dyn Trait<B = B, A = A> as SuperTrait>::A == B`
1+
error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
22
--> $DIR/enforce-supertrait-projection.rs:9:17
33
|
44
LL | fn transmute<A, B>(x: A) -> B {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
fn use_iterator<I>(itr: I)
2+
where
3+
I: IntoIterator<Item = i32>,
4+
{
5+
}
6+
7+
fn pass_iterator<I>(i: &dyn IntoIterator<Item = i32, IntoIter = I>)
8+
where
9+
I: Iterator<Item = i32>,
10+
{
11+
use_iterator(i);
12+
//~^ ERROR `&dyn IntoIterator<IntoIter = I, Item = i32>` is not an iterator
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0277]: `&dyn IntoIterator<IntoIter = I, Item = i32>` is not an iterator
2+
--> $DIR/dont-suggest-unsize-deref.rs:11:18
3+
|
4+
LL | use_iterator(i);
5+
| ------------ ^ `&dyn IntoIterator<IntoIter = I, Item = i32>` is not an iterator
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `Iterator` is not implemented for `&dyn IntoIterator<IntoIter = I, Item = i32>`
10+
= note: required for `&dyn IntoIterator<IntoIter = I, Item = i32>` to implement `IntoIterator`
11+
note: required by a bound in `use_iterator`
12+
--> $DIR/dont-suggest-unsize-deref.rs:3:8
13+
|
14+
LL | fn use_iterator<I>(itr: I)
15+
| ------------ required by a bound in this function
16+
LL | where
17+
LL | I: IntoIterator<Item = i32>,
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `use_iterator`
19+
20+
error: aborting due to previous error
21+
22+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)