mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
Rollup merge of #109755 - compiler-errors:new-solver-generator-witness-mir, r=cjgillot
Implement support for `GeneratorWitnessMIR` in new solver r? ```@cjgillot``` I mostly want this to cut down the number of failing UI tests when running the UI test suite with `--compare-mode=next-solver`, but there doesn't seem like much reason to block implementing this since it adds minimal complexity to the existing structural traits impl in the new solver. If others are against adding this for some reason, then maybe we should just make `GeneratorWitnessMIR` return `NoSolution` for these traits. Anything but an ICE please 😸 🧊
This commit is contained in:
commit
c86c9339e6
@ -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…
Reference in New Issue
Block a user