Implement support for GeneratorWitnessMIR in new solver
This commit is contained in:
parent
2fb0e8d162
commit
4a4fc3bb5b
3 changed files with 90 additions and 3 deletions
|
@ -1,7 +1,9 @@
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::{def_id::DefId, Movability, Mutability};
|
use rustc_hir::{def_id::DefId, Movability, Mutability};
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::{
|
||||||
|
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::solve::EvalCtxt;
|
use crate::solve::EvalCtxt;
|
||||||
|
|
||||||
|
@ -60,7 +62,16 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
||||||
|
|
||||||
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
|
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
|
||||||
|
|
||||||
ty::GeneratorWitnessMIR(..) => todo!(),
|
ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx
|
||||||
|
.tcx()
|
||||||
|
.generator_hidden_types(def_id)
|
||||||
|
.map(|bty| {
|
||||||
|
ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
|
||||||
|
tcx,
|
||||||
|
bty.subst(tcx, substs),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect()),
|
||||||
|
|
||||||
// For `PhantomData<T>`, we pass `T`.
|
// For `PhantomData<T>`, we pass `T`.
|
||||||
ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]),
|
ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]),
|
||||||
|
@ -76,6 +87,29 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn replace_erased_lifetimes_with_bound_vars<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||||
|
debug_assert!(!ty.has_late_bound_regions());
|
||||||
|
let mut counter = 0;
|
||||||
|
let ty = tcx.fold_regions(ty, |mut r, current_depth| {
|
||||||
|
if let ty::ReErased = r.kind() {
|
||||||
|
let br = ty::BoundRegion {
|
||||||
|
var: ty::BoundVar::from_u32(counter),
|
||||||
|
kind: ty::BrAnon(counter, None),
|
||||||
|
};
|
||||||
|
counter += 1;
|
||||||
|
r = tcx.mk_re_late_bound(current_depth, br);
|
||||||
|
}
|
||||||
|
r
|
||||||
|
});
|
||||||
|
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
||||||
|
(0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))),
|
||||||
|
);
|
||||||
|
ty::Binder::bind_with_vars(ty, bound_vars)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
||||||
ecx: &EvalCtxt<'_, 'tcx>,
|
ecx: &EvalCtxt<'_, 'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
|
@ -178,7 +212,16 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
|
||||||
|
|
||||||
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
|
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
|
||||||
|
|
||||||
ty::GeneratorWitnessMIR(..) => todo!(),
|
ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx
|
||||||
|
.tcx()
|
||||||
|
.generator_hidden_types(def_id)
|
||||||
|
.map(|bty| {
|
||||||
|
ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
|
||||||
|
ecx.tcx(),
|
||||||
|
bty.subst(ecx.tcx(), substs),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
|
||||||
|
--> $DIR/auto-with-drop_tracking_mir.rs:24:13
|
||||||
|
|
|
||||||
|
LL | is_send(foo());
|
||||||
|
| ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Send` is not implemented for `impl Future<Output = ()>`
|
||||||
|
note: required by a bound in `is_send`
|
||||||
|
--> $DIR/auto-with-drop_tracking_mir.rs:23:24
|
||||||
|
|
|
||||||
|
LL | fn is_send(_: impl Send) {}
|
||||||
|
| ^^^^ required by this bound in `is_send`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
26
tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
Normal file
26
tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir
|
||||||
|
// edition: 2021
|
||||||
|
// revisions: pass fail
|
||||||
|
//[pass] check-pass
|
||||||
|
|
||||||
|
#![feature(negative_impls)]
|
||||||
|
|
||||||
|
struct NotSync;
|
||||||
|
impl !Sync for NotSync {}
|
||||||
|
|
||||||
|
async fn foo() {
|
||||||
|
#[cfg(pass)]
|
||||||
|
let x = &();
|
||||||
|
#[cfg(fail)]
|
||||||
|
let x = &NotSync;
|
||||||
|
bar().await;
|
||||||
|
drop(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn bar() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
fn is_send(_: impl Send) {}
|
||||||
|
is_send(foo());
|
||||||
|
//[fail]~^ ERROR `impl Future<Output = ()>` cannot be sent between threads safely
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue