diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 8d4b97571a6a3..47b1ee04e777f 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -8,7 +8,7 @@ use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Ty, TyCtxt, TypeFoldable}; use rustc_ast::ast; use rustc_attr as attr; @@ -482,21 +482,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .iter() .map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars)) .map(|bound| { - bound.fold_with(&mut ty::fold::BottomUpFolder { + bound.fold_with(&mut ReplaceOpaqueTyFolder { tcx: self.interner.tcx, - ty_op: |ty| { - if let ty::Opaque(def_id, substs) = *ty.kind() { - if def_id == opaque_ty_id.0 && substs == identity_substs { - return self.interner.tcx.mk_ty(ty::Bound( - ty::INNERMOST, - ty::BoundTy::from(ty::BoundVar::from_u32(0)), - )); - } - } - ty - }, - lt_op: |lt| lt, - ct_op: |ct| ct, + opaque_ty_id, + identity_substs, + binder_index: ty::INNERMOST, }) }) .filter_map(|bound| { @@ -739,3 +729,38 @@ fn binders_for<'tcx>( }), ) } + +struct ReplaceOpaqueTyFolder<'tcx> { + tcx: TyCtxt<'tcx>, + opaque_ty_id: chalk_ir::OpaqueTyId>, + identity_substs: SubstsRef<'tcx>, + binder_index: ty::DebruijnIndex, +} + +impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_binder>( + &mut self, + t: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { + self.binder_index.shift_in(1); + let t = t.super_fold_with(self); + self.binder_index.shift_out(1); + t + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Opaque(def_id, substs) = *ty.kind() { + if def_id == self.opaque_ty_id.0 && substs == self.identity_substs { + return self.tcx.mk_ty(ty::Bound( + self.binder_index, + ty::BoundTy::from(ty::BoundVar::from_u32(0)), + )); + } + } + ty + } +} diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 2cd179526bf13..e3c865ce9e632 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -323,7 +323,10 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ty::Closure(def_id, substs) => { chalk_ir::TyKind::Closure(chalk_ir::ClosureId(def_id), substs.lower_into(interner)) } - ty::Generator(_def_id, _substs, _) => unimplemented!(), + ty::Generator(def_id, substs, _) => chalk_ir::TyKind::Generator( + chalk_ir::GeneratorId(def_id), + substs.lower_into(interner), + ), ty::GeneratorWitness(_) => unimplemented!(), ty::Never => chalk_ir::TyKind::Never, ty::Tuple(types) => { diff --git a/src/test/ui/chalkify/bugs/async.rs b/src/test/ui/chalkify/bugs/async.rs new file mode 100644 index 0000000000000..58fc93064edf5 --- /dev/null +++ b/src/test/ui/chalkify/bugs/async.rs @@ -0,0 +1,9 @@ +// check-fail +// known-bug +// compile-flags: -Z chalk --edition=2021 + +fn main() -> () {} + +async fn foo(x: u32) -> u32 { + x +} diff --git a/src/test/ui/chalkify/bugs/async.stderr b/src/test/ui/chalkify/bugs/async.stderr new file mode 100644 index 0000000000000..7a86561bcb9ce --- /dev/null +++ b/src/test/ui/chalkify/bugs/async.stderr @@ -0,0 +1,39 @@ +error[E0277]: the trait bound `[static generator@$DIR/async.rs:7:29: 9:2]: Generator` is not satisfied + --> $DIR/async.rs:7:29 + | +LL | async fn foo(x: u32) -> u32 { + | _____________________________^ +LL | | x +LL | | } + | |_^ the trait `Generator` is not implemented for `[static generator@$DIR/async.rs:7:29: 9:2]` + | +note: required by a bound in `from_generator` + --> $SRC_DIR/core/src/future/mod.rs:LL:COL + | +LL | T: Generator, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `from_generator` + +error[E0280]: the requirement `<[static generator@$DIR/async.rs:7:29: 9:2] as Generator>::Yield == ()` is not satisfied + --> $DIR/async.rs:7:29 + | +LL | async fn foo(x: u32) -> u32 { + | _____________________________^ +LL | | x +LL | | } + | |_^ + | +note: required by a bound in `from_generator` + --> $SRC_DIR/core/src/future/mod.rs:LL:COL + | +LL | T: Generator, + | ^^^^^^^^^^ required by this bound in `from_generator` + +error[E0280]: the requirement ` as Future>::Output == u32` is not satisfied + --> $DIR/async.rs:7:25 + | +LL | async fn foo(x: u32) -> u32 { + | ^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index 2a23d72edc064..f6be550283a21 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -10,8 +10,8 @@ use regex::Regex; // A few of those error codes can't be tested but all the others can and *should* be tested! const EXEMPTED_FROM_TEST: &[&str] = &[ - "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0465", "E0476", "E0514", "E0519", - "E0523", "E0554", "E0640", "E0717", "E0729", + "E0279", "E0313", "E0377", "E0461", "E0462", "E0465", "E0476", "E0514", "E0519", "E0523", + "E0554", "E0640", "E0717", "E0729", ]; // Some error codes don't have any tests apparently...