Skip to content

Commit 685c773

Browse files
Rollup merge of rust-lang#106753 - compiler-errors:rpitit-not-suggestable, r=spastorino
Make sure that RPITITs are not considered suggestable Makes no sense to suggest `where impl Future<Output = ()>: Send`, for example.
2 parents f7066f7 + 0be510e commit 685c773

File tree

3 files changed

+62
-5
lines changed

3 files changed

+62
-5
lines changed

compiler/rustc_middle/src/ty/diagnostics.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ use std::ops::ControlFlow;
44

55
use crate::ty::{
66
visit::TypeVisitable, AliasTy, Const, ConstKind, DefIdTree, InferConst, InferTy, Opaque,
7-
PolyTraitPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor,
7+
PolyTraitPredicate, Projection, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor,
88
};
99

1010
use rustc_data_structures::fx::FxHashMap;
1111
use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg};
1212
use rustc_hir as hir;
13+
use rustc_hir::def::DefKind;
1314
use rustc_hir::def_id::DefId;
1415
use rustc_hir::WherePredicate;
1516
use rustc_span::Span;
@@ -443,7 +444,7 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
443444
type BreakTy = ();
444445

445446
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
446-
match t.kind() {
447+
match *t.kind() {
447448
Infer(InferTy::TyVar(_)) if self.infer_suggestable => {}
448449

449450
FnDef(..)
@@ -458,9 +459,9 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
458459
}
459460

460461
Alias(Opaque, AliasTy { def_id, .. }) => {
461-
let parent = self.tcx.parent(*def_id);
462-
if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
463-
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = self.tcx.type_of(parent).kind()
462+
let parent = self.tcx.parent(def_id);
463+
if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent)
464+
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *self.tcx.type_of(parent).kind()
464465
&& parent_opaque_def_id == def_id
465466
{
466467
// Okay
@@ -469,6 +470,12 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
469470
}
470471
}
471472

473+
Alias(Projection, AliasTy { def_id, .. }) => {
474+
if self.tcx.def_kind(def_id) != DefKind::AssocTy {
475+
return ControlFlow::Break(());
476+
}
477+
}
478+
472479
Param(param) => {
473480
// FIXME: It would be nice to make this not use string manipulation,
474481
// but it's pretty hard to do this, since `ty::ParamTy` is missing
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// edition:2021
2+
3+
#![feature(async_fn_in_trait)]
4+
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
5+
6+
trait Foo {
7+
async fn bar();
8+
}
9+
10+
async fn test<T: Foo>() {
11+
T::bar().await;
12+
}
13+
14+
fn test2<T: Foo>() {
15+
assert_is_send(test::<T>());
16+
//~^ ERROR future cannot be sent between threads safely
17+
}
18+
19+
fn assert_is_send(_: impl Send) {}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/missing-send-bound.rs:3:12
3+
|
4+
LL | #![feature(async_fn_in_trait)]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error: future cannot be sent between threads safely
11+
--> $DIR/missing-send-bound.rs:15:20
12+
|
13+
LL | assert_is_send(test::<T>());
14+
| ^^^^^^^^^^^ future returned by `test` is not `Send`
15+
|
16+
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>`
17+
note: future is not `Send` as it awaits another future which is not `Send`
18+
--> $DIR/missing-send-bound.rs:11:5
19+
|
20+
LL | T::bar().await;
21+
| ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send`
22+
note: required by a bound in `assert_is_send`
23+
--> $DIR/missing-send-bound.rs:19:27
24+
|
25+
LL | fn assert_is_send(_: impl Send) {}
26+
| ^^^^ required by this bound in `assert_is_send`
27+
28+
error: aborting due to previous error; 1 warning emitted
29+

0 commit comments

Comments
 (0)