Skip to content

Commit

Permalink
fix: rust-lang#12441 False-positive type-mismatch error with generic …
Browse files Browse the repository at this point in the history
…future
  • Loading branch information
bitgaoshu committed Jun 3, 2022
1 parent e107995 commit 1a97ab3
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 4 deletions.
27 changes: 23 additions & 4 deletions crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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.
Expand Down
55 changes: 55 additions & 0 deletions crates/hir-ty/src/tests/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(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(
Expand Down

0 comments on commit 1a97ab3

Please sign in to comment.