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),
|
.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 {
|
let proj_bound = WhereClause::AliasEq(AliasEq {
|
||||||
alias: AliasTy::Projection(ProjectionTy {
|
alias: AliasTy::Projection(ProjectionTy {
|
||||||
associated_ty_id: to_assoc_type_id(future_output),
|
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 })
|
ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
|
||||||
.intern(Interner),
|
.intern(Interner),
|
||||||
});
|
});
|
||||||
|
binder.push(crate::wrap_empty_binders(proj_bound));
|
||||||
let bound = OpaqueTyDatumBound {
|
let bound = OpaqueTyDatumBound {
|
||||||
bounds: make_single_type_binders(vec![
|
bounds: make_single_type_binders(binder),
|
||||||
crate::wrap_empty_binders(impl_bound),
|
|
||||||
crate::wrap_empty_binders(proj_bound),
|
|
||||||
]),
|
|
||||||
where_clauses: chalk_ir::Binders::empty(Interner, vec![]),
|
where_clauses: chalk_ir::Binders::empty(Interner, vec![]),
|
||||||
};
|
};
|
||||||
// The opaque type has 1 parameter.
|
// 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]
|
#[test]
|
||||||
fn infer_try() {
|
fn infer_try() {
|
||||||
check_types(
|
check_types(
|
||||||
|
|
Loading…
Reference in a new issue