Auto merge of #106503 - cjgillot:remap-nofilter, r=oli-obk
Do not filter substs in `remap_generic_params_to_declaration_params`. The relevant filtering should have been performed by borrowck. Fixes https://github.com/rust-lang/rust/issues/105826 r? types
This commit is contained in:
commit
6d46b1ec87
4 changed files with 41 additions and 28 deletions
|
@ -252,7 +252,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let definition_ty = instantiated_ty
|
let definition_ty = instantiated_ty
|
||||||
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false, origin)
|
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
|
||||||
.ty;
|
.ty;
|
||||||
|
|
||||||
if !check_opaque_type_parameter_valid(
|
if !check_opaque_type_parameter_valid(
|
||||||
|
|
|
@ -564,7 +564,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
opaque_type_key,
|
opaque_type_key,
|
||||||
self.fcx.infcx.tcx,
|
self.fcx.infcx.tcx,
|
||||||
true,
|
true,
|
||||||
decl.origin,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);
|
self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);
|
||||||
|
|
|
@ -28,7 +28,6 @@ use crate::ty::util::Discr;
|
||||||
pub use adt::*;
|
pub use adt::*;
|
||||||
pub use assoc::*;
|
pub use assoc::*;
|
||||||
pub use generics::*;
|
pub use generics::*;
|
||||||
use hir::OpaqueTyOrigin;
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::node_id::NodeMap;
|
use rustc_ast::node_id::NodeMap;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
|
@ -1345,7 +1344,6 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
// typeck errors have subpar spans for opaque types, so delay error reporting until borrowck.
|
// typeck errors have subpar spans for opaque types, so delay error reporting until borrowck.
|
||||||
ignore_errors: bool,
|
ignore_errors: bool,
|
||||||
origin: OpaqueTyOrigin,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
|
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
|
||||||
|
|
||||||
|
@ -1361,30 +1359,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
|
||||||
// This zip may have several times the same lifetime in `substs` paired with a different
|
// This zip may have several times the same lifetime in `substs` paired with a different
|
||||||
// lifetime from `id_substs`. Simply `collect`ing the iterator is the correct behaviour:
|
// lifetime from `id_substs`. Simply `collect`ing the iterator is the correct behaviour:
|
||||||
// it will pick the last one, which is the one we introduced in the impl-trait desugaring.
|
// it will pick the last one, which is the one we introduced in the impl-trait desugaring.
|
||||||
let map = substs.iter().zip(id_substs);
|
let map = substs.iter().zip(id_substs).collect();
|
||||||
|
|
||||||
let map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>> = match origin {
|
|
||||||
// HACK: The HIR lowering for async fn does not generate
|
|
||||||
// any `+ Captures<'x>` bounds for the `impl Future<...>`, so all async fns with lifetimes
|
|
||||||
// would now fail to compile. We should probably just make hir lowering fill this in properly.
|
|
||||||
OpaqueTyOrigin::AsyncFn(_) => map.collect(),
|
|
||||||
OpaqueTyOrigin::FnReturn(_) | OpaqueTyOrigin::TyAlias => {
|
|
||||||
// Opaque types may only use regions that are bound. So for
|
|
||||||
// ```rust
|
|
||||||
// type Foo<'a, 'b, 'c> = impl Trait<'a> + 'b;
|
|
||||||
// ```
|
|
||||||
// we may not use `'c` in the hidden type.
|
|
||||||
let variances = tcx.variances_of(def_id);
|
|
||||||
debug!(?variances);
|
|
||||||
|
|
||||||
map.filter(|(_, v)| {
|
|
||||||
let ty::GenericArgKind::Lifetime(lt) = v.unpack() else { return true };
|
|
||||||
let ty::ReEarlyBound(ebr) = lt.kind() else { bug!() };
|
|
||||||
variances[ebr.index as usize] == ty::Variance::Invariant
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
debug!("map = {:#?}", map);
|
debug!("map = {:#?}", map);
|
||||||
|
|
||||||
// Convert the type from the function into a type valid outside
|
// Convert the type from the function into a type valid outside
|
||||||
|
|
39
tests/ui/impl-trait/issues/issue-105826.rs
Normal file
39
tests/ui/impl-trait/issues/issue-105826.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
struct A(Vec<u8>);
|
||||||
|
|
||||||
|
struct B<'a> {
|
||||||
|
one: &'a mut A,
|
||||||
|
two: &'a mut Vec<u8>,
|
||||||
|
three: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> B<'a> {
|
||||||
|
fn one(&mut self) -> &mut impl Write {
|
||||||
|
&mut self.one.0
|
||||||
|
}
|
||||||
|
fn two(&mut self) -> &mut impl Write {
|
||||||
|
&mut *self.two
|
||||||
|
}
|
||||||
|
fn three(&mut self) -> &mut impl Write {
|
||||||
|
&mut self.three
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C<'a>(B<'a>);
|
||||||
|
|
||||||
|
impl<'a> C<'a> {
|
||||||
|
fn one(&mut self) -> &mut impl Write {
|
||||||
|
self.0.one()
|
||||||
|
}
|
||||||
|
fn two(&mut self) -> &mut impl Write {
|
||||||
|
self.0.two()
|
||||||
|
}
|
||||||
|
fn three(&mut self) -> &mut impl Write {
|
||||||
|
self.0.three()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue