mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
fix: #12441 False-positive type-mismatch error with generic future
This commit is contained in:
parent
e10799536a
commit
1a97ab34db
2 changed files with 78 additions and 4 deletions
|
@ -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.
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue