Change:
Here is an example which uses a RPIT on a borrowed type in three different ways: IMO this is perfectly reasonable code and (EDIT: see below). On stable () we have the following: And on beta () and nightly () we get some additional errors: EDIT: On second thought, I guess the first error (on stable) is reasonable, since we are actually returning a in that case. If you either use in the body or in the return type then the error goes away. But the second error is still a regression. It most recently worked on: rustc 1.66.0 ( 2022-12-12) : modify labels: +regression-from-stable-to-beta -regression-untriaged
This is . Cc It is related to the invariance: Another case that doesn't rely on member constraints in the second function and yields a different error message: I also found a distantly related regression that doesn't require invariance. It looks like a missed subtyping opportunity:
Another version using TAIT: At this point there are two classes of regression: The first is related to the fact that and the the second requires more subtyping relations. label I-types-nominated T-types T-compiler
WG-prioritization assigning priority (). label -I-prioritize +P-critical
From beta crater: https://crater- https://crater- https://crater- https://crater- https://crater-
unnominating as it will get fixed by which is approved again. Have to try to get this into beta though, only have 1 more day for that

Discussion:
} let definition_ty = instantiated_ty <del> .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false, origin) </del> <ins> .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) </ins> .ty; if !check_opaque_type_parameter_valid(

opaque_type_key, self.fcx.infcx.tcx, true, <del> decl.origin, </del> ); self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);

pub use adt::*; pub use assoc::*; pub use generics::*; <del> use hir::OpaqueTyOrigin; </del> use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_attr as attr;

tcx: TyCtxt<'tcx>, // typeck errors have subpar spans for opaque types, so delay error reporting until borrowck. ignore_errors: bool, <del> origin: OpaqueTyOrigin, </del> ) -> Self { let OpaqueTypeKey { def_id, substs } = opaque_type_key;

// 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: // it will pick the last one, which is the one we introduced in the impl-trait desugaring. <del> let map = substs.iter().zip(id_substs); 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() } }; </del> <ins> let map = substs.iter().zip(id_substs).collect(); </ins> debug!("map = {:#?}", map); // Convert the type from the function into a type valid outside

<ins> // 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() {} </ins>