Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/chalk_db.rs27
-rw-r--r--crates/hir-ty/src/tests/traits.rs55
2 files changed, 78 insertions, 4 deletions
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<Interner> 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<Interner> 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
@@ -83,6 +83,61 @@ async fn test() {
}
#[test]
+fn auto_sized_async_block() {
+ check_no_mismatches(
+ r#"
+//- minicore: future, sized
+
+use core::future::Future;
+struct MyFut<Fut>(Fut);
+
+impl<Fut> Future for MyFut<Fut>
+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<T: ?Sized> {}
+
+#[lang = "coerce_unsized"]
+pub trait CoerceUnsized<T> {}
+
+pub unsafe trait Allocator {}
+
+pub struct Global;
+unsafe impl Allocator for Global {}
+
+#[lang = "owned_box"]
+#[fundamental]
+pub struct Box<T: ?Sized, A: Allocator = Global>;
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
+
+fn send() -> Box<dyn Future<Output = ()> + Send + 'static>{
+ box async move {}
+}
+
+fn not_send() -> Box<dyn Future<Output = ()> + 'static> {
+ box async move {}
+}
+ "#,
+ );
+}
+
+#[test]
fn infer_try() {
check_types(
r#"