diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs index af2aa96574..faec99c7d3 100644 --- a/crates/hir-ty/src/chalk_db.rs +++ b/crates/hir-ty/src/chalk_db.rs @@ -241,6 +241,27 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { .intern(Interner), ), }); + let mut binder = vec![]; + binder.push(crate::wrap_empty_binders(impl_bound)); + let sized_trait = self + .db + .lang_item(self.krate, SmolStr::new_inline("sized")) + .and_then(|item| item.as_trait()); + if let Some(sized_trait_) = sized_trait { + let sized_bound = WhereClause::Implemented(TraitRef { + trait_id: to_chalk_trait_id(sized_trait_), + // Self type as the first parameter. + substitution: Substitution::from1( + Interner, + TyKind::BoundVar(BoundVar { + debruijn: DebruijnIndex::INNERMOST, + index: 0, + }) + .intern(Interner), + ), + }); + binder.push(crate::wrap_empty_binders(sized_bound)); + } let proj_bound = WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(ProjectionTy { associated_ty_id: to_assoc_type_id(future_output), @@ -255,11 +276,9 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }) .intern(Interner), }); + binder.push(crate::wrap_empty_binders(proj_bound)); let bound = OpaqueTyDatumBound { - bounds: make_single_type_binders(vec![ - crate::wrap_empty_binders(impl_bound), - crate::wrap_empty_binders(proj_bound), - ]), + bounds: make_single_type_binders(binder), where_clauses: chalk_ir::Binders::empty(Interner, vec![]), }; // The opaque type has 1 parameter. diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index a11b026df5..30c67d41b7 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -82,6 +82,61 @@ async fn test() { ); } +#[test] +fn auto_sized_async_block() { + check_no_mismatches( + r#" +//- minicore: future, sized + +use core::future::Future; +struct MyFut(Fut); + +impl Future for MyFut +where Fut: Future +{ + type Output = Fut::Output; +} +async fn reproduction() -> usize { + let f = async {999usize}; + MyFut(f).await +} + "#, + ); + check_no_mismatches( + r#" +//- minicore: future +//#11815 +#[lang = "sized"] +pub trait Sized {} + +#[lang = "unsize"] +pub trait Unsize {} + +#[lang = "coerce_unsized"] +pub trait CoerceUnsized {} + +pub unsafe trait Allocator {} + +pub struct Global; +unsafe impl Allocator for Global {} + +#[lang = "owned_box"] +#[fundamental] +pub struct Box; + +impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} + +fn send() -> Box + Send + 'static>{ + box async move {} +} + +fn not_send() -> Box + 'static> { + box async move {} +} + "#, + ); +} + #[test] fn infer_try() { check_types(