Skip to content

Commit

Permalink
Rollup merge of #109755 - compiler-errors:new-solver-generator-witnes…
Browse files Browse the repository at this point in the history
…s-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 😸 🧊
  • Loading branch information
matthiaskrgr authored Apr 6, 2023
2 parents 3e21d68 + 4a4fc3b commit c86c933
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{def_id::DefId, Movability, Mutability};
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;

Expand Down Expand Up @@ -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::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`.
ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]),
Expand All @@ -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>(
ecx: &EvalCtxt<'_, 'tcx>,
ty: Ty<'tcx>,
Expand Down Expand Up @@ -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::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()),
}
}

Expand Down
18 changes: 18 additions & 0 deletions tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 26 additions & 0 deletions tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit c86c933

Please sign in to comment.