Rollup merge of #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.
This commit is contained in:
Michael Goulet 2023-01-18 18:00:28 -05:00 committed by GitHub
commit 685c77305c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 5 deletions

View file

@ -4,12 +4,13 @@ use std::ops::ControlFlow;
use crate::ty::{
visit::TypeVisitable, AliasTy, Const, ConstKind, DefIdTree, InferConst, InferTy, Opaque,
PolyTraitPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor,
PolyTraitPredicate, Projection, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor,
};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::WherePredicate;
use rustc_span::Span;
@ -443,7 +444,7 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
type BreakTy = ();
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
match *t.kind() {
Infer(InferTy::TyVar(_)) if self.infer_suggestable => {}
FnDef(..)
@ -458,9 +459,9 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
}
Alias(Opaque, AliasTy { def_id, .. }) => {
let parent = self.tcx.parent(*def_id);
if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = self.tcx.type_of(parent).kind()
let parent = self.tcx.parent(def_id);
if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent)
&& let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *self.tcx.type_of(parent).kind()
&& parent_opaque_def_id == def_id
{
// Okay
@ -469,6 +470,12 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
}
}
Alias(Projection, AliasTy { def_id, .. }) => {
if self.tcx.def_kind(def_id) != DefKind::AssocTy {
return ControlFlow::Break(());
}
}
Param(param) => {
// FIXME: It would be nice to make this not use string manipulation,
// but it's pretty hard to do this, since `ty::ParamTy` is missing

View file

@ -0,0 +1,21 @@
// edition:2021
#![feature(async_fn_in_trait)]
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
trait Foo {
async fn bar();
}
async fn test<T: Foo>() {
T::bar().await;
}
fn test2<T: Foo>() {
assert_is_send(test::<T>());
//~^ ERROR future cannot be sent between threads safely
}
fn assert_is_send(_: impl Send) {}
fn main() {}

View file

@ -0,0 +1,29 @@
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/missing-send-bound.rs:3:12
|
LL | #![feature(async_fn_in_trait)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= note: `#[warn(incomplete_features)]` on by default
error: future cannot be sent between threads safely
--> $DIR/missing-send-bound.rs:15:20
|
LL | assert_is_send(test::<T>());
| ^^^^^^^^^^^ future returned by `test` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>`
note: future is not `Send` as it awaits another future which is not `Send`
--> $DIR/missing-send-bound.rs:11:5
|
LL | T::bar().await;
| ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send`
note: required by a bound in `assert_is_send`
--> $DIR/missing-send-bound.rs:19:27
|
LL | fn assert_is_send(_: impl Send) {}
| ^^^^ required by this bound in `assert_is_send`
error: aborting due to previous error; 1 warning emitted