Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --I ran into this error when compiling the crate with nightly. I reduced the example down to this, no external deps needed: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: Compiles without errors on current stable/beta. <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Bisected: searched nightlies: from nightly-2022-03-29 to nightly-2022-03-31 regressed nightly: nightly-2022-03-31 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.1</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
cc and
Huh how did we miss this on crater? Either way, I know how to fix this. Maybe i'll even get it in before the beta cutoff. But even if not, the fix will be small and easily backported
I ran into the compilation error testing against the branch of fatfs, the latest version released on doesn't trigger the issue.
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-medium
Still in beta, leaving open until we backport the PR
Backported in

Discussion:
infcx: &InferCtxt<'_, 'tcx>, opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, ) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> { <del> opaque_ty_decls .into_iter() .map(|(opaque_type_key, (concrete_type, origin))| { let substs = opaque_type_key.substs; debug!(?concrete_type, ?substs); </del> <ins> let mut result: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> = VecMap::new(); for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls { let substs = opaque_type_key.substs; debug!(?concrete_type, ?substs); </ins> <del> let mut subst_regions = vec![self.universal_regions.fr_static]; let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| { if let ty::RePlaceholder(..) = region.kind() { // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. return region; </del> <ins> let mut subst_regions = vec![self.universal_regions.fr_static]; let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| { if let ty::RePlaceholder(..) = region.kind() { // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. return region; } let vid = self.to_region_vid(region); trace!(?vid); let scc = self.constraint_sccs.scc(vid); trace!(?scc); match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| { self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?) }) { Some(region) => { let vid = self.universal_regions.to_region_vid(region); subst_regions.push(vid); region </ins> } <del> let vid = self.to_region_vid(region); trace!(?vid); let scc = self.constraint_sccs.scc(vid); trace!(?scc); match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| { self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?) }) { Some(region) => { let vid = self.universal_regions.to_region_vid(region); subst_regions.push(vid); region } None => { subst_regions.push(vid); infcx.tcx.sess.delay_span_bug( concrete_type.span, "opaque type with non-universal region substs", ); infcx.tcx.lifetimes.re_static } </del> <ins> None => { subst_regions.push(vid); infcx.tcx.sess.delay_span_bug( concrete_type.span, "opaque type with non-universal region substs", ); infcx.tcx.lifetimes.re_static </ins> } <del> }); </del> <ins> } }); </ins> <del> subst_regions.sort(); subst_regions.dedup(); </del> <ins> subst_regions.sort(); subst_regions.dedup(); </ins> <del> let universal_concrete_type = infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region { ty::ReVar(vid) => subst_regions .iter() .find(|ur_vid| self.eval_equal(vid, **ur_vid)) .and_then(|ur_vid| self.definitions[*ur_vid].external_name) .unwrap_or(infcx.tcx.lifetimes.re_root_empty), _ => region, }); </del> <ins> let universal_concrete_type = infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region { ty::ReVar(vid) => subst_regions .iter() .find(|ur_vid| self.eval_equal(vid, **ur_vid)) .and_then(|ur_vid| self.definitions[*ur_vid].external_name) .unwrap_or(infcx.tcx.lifetimes.re_root_empty), _ => region, }); </ins> <del> debug!(?universal_concrete_type, ?universal_substs); </del> <ins> debug!(?universal_concrete_type, ?universal_substs); </ins> <del> let opaque_type_key = OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs }; let remapped_type = infcx.infer_opaque_definition_from_instantiation( opaque_type_key, universal_concrete_type, ); let ty = if check_opaque_type_parameter_valid( infcx.tcx, opaque_type_key, origin, concrete_type.span, ) { remapped_type } else { infcx.tcx.ty_error() }; (opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span }) }) .collect() </del> <ins> let opaque_type_key = OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs }; let remapped_type = infcx.infer_opaque_definition_from_instantiation( opaque_type_key, universal_concrete_type, ); let ty = if check_opaque_type_parameter_valid( infcx.tcx, opaque_type_key, origin, concrete_type.span, ) { remapped_type } else { infcx.tcx.ty_error() }; // Sometimes two opaque types are the same only after we remap the generic parameters // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)` // and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that // once we convert the generic parameters to those of the opaque type. if let Some(prev) = result.get_mut(&opaque_type_key) { if prev.ty != ty { let mut err = infcx.tcx.sess.struct_span_err( concrete_type.span, &format!("hidden type `{}` differed from previous `{}`", ty, prev.ty), ); err.span_note(prev.span, "previous hidden type bound here"); err.emit(); prev.ty = infcx.tcx.ty_error(); } // Pick a better span if there is one. // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. prev.span = prev.span.substitute_dummy(concrete_type.span); } else { result.insert(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span }); } } result </ins> } /// Map the regions in the type to named regions. This is similar to what

<ins> // check-pass use std::marker::PhantomData; pub struct ConcreteError {} pub trait IoBase {} struct X {} impl IoBase for X {} pub struct ClusterIterator<B, E, S = B> { pub fat: B, phantom_s: PhantomData<S>, phantom_e: PhantomData<E>, } pub struct FileSystem<IO: IoBase> { pub disk: IO, } impl<IO: IoBase> FileSystem<IO> { pub fn cluster_iter(&self) -> ClusterIterator<impl IoBase + '_, ConcreteError> { ClusterIterator { fat: X {}, phantom_s: PhantomData::default(), phantom_e: PhantomData::default(), } } } fn main() {} </ins>