diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 9277a262f9789..0b9b954636040 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -244,7 +244,7 @@ fn do_mir_borrowck<'tcx>( // Compute non-lexical lifetimes. let nll::NllOutput { regioncx, - opaque_type_values, + concrete_opaque_types, polonius_input, polonius_output, opt_closure_req, @@ -274,7 +274,7 @@ fn do_mir_borrowck<'tcx>( &body, ®ioncx, &opt_closure_req, - &opaque_type_values, + &concrete_opaque_types, &mut errors, ); @@ -434,7 +434,7 @@ fn do_mir_borrowck<'tcx>( let tainted_by_errors = mbcx.emit_errors(); let result = BorrowCheckResult { - concrete_opaque_types: opaque_type_values, + concrete_opaque_types, closure_requirements: opt_closure_req, used_mut_upvars: mbcx.used_mut_upvars, tainted_by_errors, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 889acb3acbed7..77514a571f1e8 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -45,7 +45,7 @@ pub type PoloniusOutput = Output; /// closure requirements to propagate, and any generated errors. pub(crate) struct NllOutput<'tcx> { pub regioncx: RegionInferenceContext<'tcx>, - pub opaque_type_values: FxIndexMap>, + pub concrete_opaque_types: FxIndexMap>>, pub polonius_input: Option>, pub polonius_output: Option>, pub opt_closure_req: Option>, @@ -302,7 +302,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( }); // Solve the region constraints. - let (closure_region_requirements, nll_errors) = + let (opt_closure_req, nll_errors) = regioncx.solve(infcx, param_env, &body, polonius_output.clone()); if !nll_errors.is_empty() { @@ -313,14 +313,14 @@ pub(crate) fn compute_regions<'cx, 'tcx>( )); } - let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values); + let concrete_opaque_types = regioncx.infer_opaque_types(&infcx, opaque_type_values); NllOutput { regioncx, - opaque_type_values: remapped_opaque_tys, + concrete_opaque_types, polonius_input: all_facts.map(Box::new), polonius_output, - opt_closure_req: closure_region_requirements, + opt_closure_req, nll_errors, } } @@ -382,7 +382,7 @@ pub(super) fn dump_annotation<'tcx>( body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, - opaque_type_values: &FxIndexMap>, + concrete_opaque_types: &FxIndexMap>>, errors: &mut crate::error::BorrowckErrors<'tcx>, ) { let tcx = infcx.tcx; @@ -425,8 +425,8 @@ pub(super) fn dump_annotation<'tcx>( err }; - if !opaque_type_values.is_empty() { - err.note(format!("Inferred opaque type values:\n{:#?}", opaque_type_values)); + if !concrete_opaque_types.is_empty() { + err.note(format!("Inferred opaque type values:\n{:#?}", concrete_opaque_types)); } errors.buffer_non_error_diag(err); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 7fc89e89a3599..14b3da2f4e3f0 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -8,6 +8,7 @@ use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::visit::TypeVisitableExt; +use rustc_middle::ty::EarlyBinder; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; @@ -62,8 +63,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, infcx: &InferCtxt<'tcx>, opaque_ty_decls: FxIndexMap, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, - ) -> FxIndexMap> { - let mut result: FxIndexMap> = FxIndexMap::default(); + ) -> FxIndexMap>> { + let mut result: FxIndexMap>> = + FxIndexMap::default(); let member_constraints: FxIndexMap<_, _> = self .member_constraints @@ -144,11 +146,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { universal_concrete_type, origin, ); + // 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` mapped to `(X, Y)` // and `OpaqueType` 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.def_id) { + if let Some(stored_hidden_ty) = result.get_mut(&opaque_type_key.def_id) { + let mut prev = stored_hidden_ty.subst_identity(); + let ty = ty.subst_identity(); if prev.ty != ty { let guar = ty.error_reported().err().unwrap_or_else(|| { prev.report_mismatch( @@ -163,10 +168,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { // 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); + *stored_hidden_ty = EarlyBinder(prev); } else { result.insert( opaque_type_key.def_id, - OpaqueHiddenType { ty, span: concrete_type.span }, + ty.map_bound(|ty| OpaqueHiddenType { ty, span: concrete_type.span }), ); } } @@ -215,7 +221,7 @@ pub trait InferCtxtExt<'tcx> { opaque_type_key: OpaqueTypeKey<'tcx>, instantiated_ty: OpaqueHiddenType<'tcx>, origin: OpaqueTyOrigin, - ) -> Ty<'tcx>; + ) -> EarlyBinder>; } impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { @@ -248,14 +254,14 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { opaque_type_key: OpaqueTypeKey<'tcx>, instantiated_ty: OpaqueHiddenType<'tcx>, origin: OpaqueTyOrigin, - ) -> Ty<'tcx> { + ) -> EarlyBinder> { if let Some(e) = self.tainted_by_errors() { - return self.tcx.ty_error(e); + return EarlyBinder::dummy(self.tcx.ty_error(e)); } let definition_ty = instantiated_ty .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) - .ty; + .map_bound(|ty| ty.ty); if let Err(guar) = check_opaque_type_parameter_valid( self.tcx, @@ -263,7 +269,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { origin, instantiated_ty.span, ) { - return self.tcx.ty_error(guar); + return EarlyBinder::dummy(self.tcx.ty_error(guar)); } // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` @@ -274,6 +280,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { let def_id = opaque_type_key.def_id; // This logic duplicates most of `check_opaque_meets_bounds`. // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely. + // + // FIXME(lcnr): Move this check into a separate function which cannot access `self` here. + // This check runs in the context of the opaque type, not the defining scope. let param_env = self.tcx.param_env(def_id); // HACK This bubble is required for this tests to pass: // nested-return-type2-tait2.rs @@ -281,10 +290,11 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { let infcx = self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); let ocx = ObligationCtxt::new(&infcx); + let hidden_type = definition_ty.subst_identity(); // Require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())); + let predicate = ty::PredicateKind::WellFormed(hidden_type.into()); let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id); @@ -295,14 +305,14 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { &ObligationCause::misc(instantiated_ty.span, def_id), param_env, opaque_ty, - definition_ty, + hidden_type, ) { infcx .err_ctxt() .report_mismatched_types( &ObligationCause::misc(instantiated_ty.span, def_id), opaque_ty, - definition_ty, + hidden_type, err, ) .emit(); @@ -328,7 +338,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { definition_ty } else { let reported = infcx.err_ctxt().report_fulfillment_errors(&errors); - self.tcx.ty_error(reported) + EarlyBinder::dummy(self.tcx.ty_error(reported)) } } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cf204cff6b3a7..39f119f4009b0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1043,8 +1043,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .concrete_opaque_types .iter() .map(|(&def_id, &hidden_ty)| { + // FIXME(-Ztrait-solver=next): Using the identity substs for the opaques + // is incorrect and should be fixed. let substs = ty::InternalSubsts::identity_for_item(self.infcx.tcx, def_id); - (ty::OpaqueTypeKey { def_id, substs }, hidden_ty) + (ty::OpaqueTypeKey { def_id, substs }, hidden_ty.subst_identity()) }) .collect(); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index f7c5b44678f72..9d801b9420968 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -3,7 +3,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::DUMMY_SP; +use rustc_span::{ErrorGuaranteed, DUMMY_SP}; use crate::errors::UnconstrainedOpaqueType; @@ -134,6 +134,8 @@ impl TaitConstraintLocator<'_> { debug!("no constraints in typeck results"); return; }; + + let typeck_hidden_ty = typeck_hidden_ty.subst_identity(); if self.typeck_types.iter().all(|prev| prev.ty != typeck_hidden_ty.ty) { self.typeck_types.push(typeck_hidden_ty); } @@ -142,6 +144,7 @@ impl TaitConstraintLocator<'_> { let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types; debug!(?concrete_opaque_types); if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) { + let concrete_type = concrete_type.subst_identity(); debug!(?concrete_type, "found constraint"); if let Some(prev) = &mut self.found { if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() { @@ -197,10 +200,18 @@ pub(super) fn find_opaque_ty_constraints_for_rpit( ) -> Ty<'_> { let concrete = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied(); + // In most cases the opaque type is defined by MIR typeck, + // in this case we check whether all nested bodies, e.g. closures, + // also have the same hidden type. + // + // If this is not the case we instead lookup the opaque type in the + // hir typeck results. if let Some(concrete) = concrete { + let concrete = concrete.subst_identity(); let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id); debug!(?scope); - let mut locator = RpitConstraintChecker { def_id, tcx, found: concrete }; + let mut locator = + RpitConstraintChecker { def_id, tcx, found: concrete, tainted_by_errors: None }; match tcx.hir().get(scope) { Node::Item(it) => intravisit::walk_item(&mut locator, it), @@ -208,27 +219,51 @@ pub(super) fn find_opaque_ty_constraints_for_rpit( Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it), other => bug!("{:?} is not a valid scope for an opaque type item", other), } - } - concrete.map(|concrete| concrete.ty).unwrap_or_else(|| { + if let Some(guar) = locator.tainted_by_errors { + tcx.ty_error(guar) + } else { + // As a sanity check we also compare the type defined by mir typeck to + // the one defined by hir typeck. This should never fail unless there + // is some different error somewhere. + // + // We still return the type inferred by mir borrowck as we otherwise get + // ICE in tests with recursive opaque types. For those we only error + // when checking the opaque returned by `type_of`. + if let Some(typeck_ty) = tcx.typeck(owner_def_id).concrete_opaque_types.get(&def_id) { + let typeck_ty = typeck_ty.subst_identity(); + if tcx.erase_regions(concrete.ty) != typeck_ty.ty { + concrete.report_mismatch(&typeck_ty, def_id, tcx).delay_as_bug(); + } + } else { + tcx.sess.delay_span_bug( + concrete.span, + format!("opaque type defined in MIR not in HIR: {concrete:?}"), + ); + } + + concrete.ty + } + } else { + // If that isn't the case we use the type from HIR typeck. let table = tcx.typeck(owner_def_id); if let Some(guar) = table.tainted_by_errors { // Some error in the // owner fn prevented us from populating // the `concrete_opaque_types` table. tcx.ty_error(guar) + } else if let Some(ty) = table.concrete_opaque_types.get(&def_id) { + ty.subst_identity().ty } else { - table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| { - // We failed to resolve the opaque type or it - // resolves to itself. We interpret this as the - // no values of the hidden type ever being constructed, - // so we can just make the hidden type be `!`. - // For backwards compatibility reasons, we fall back to - // `()` until we the diverging default is changed. - tcx.mk_diverging_default() - }) + // We failed to resolve the opaque type or it + // resolves to itself. We interpret this as the + // no values of the hidden type ever being constructed, + // so we can just make the hidden type be `!`. + // For backwards compatibility reasons, we fall back to + // `()` until we the diverging default is changed. + tcx.mk_diverging_default() } - }) + } } struct RpitConstraintChecker<'tcx> { @@ -238,11 +273,13 @@ struct RpitConstraintChecker<'tcx> { def_id: LocalDefId, found: ty::OpaqueHiddenType<'tcx>, + + tainted_by_errors: Option, } impl RpitConstraintChecker<'_> { #[instrument(skip(self), level = "debug")] - fn check(&self, def_id: LocalDefId) { + fn check(&mut self, def_id: LocalDefId) { // Use borrowck to get the type with unerased regions. let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types; debug!(?concrete_opaque_types); @@ -253,10 +290,11 @@ impl RpitConstraintChecker<'_> { } debug!(?concrete_type, "found constraint"); - + let concrete_type = concrete_type.subst_identity(); if concrete_type.ty != self.found.ty && !(concrete_type, self.found).references_error() { - self.found.report_mismatch(&concrete_type, self.def_id, self.tcx).emit(); + let guar = self.found.report_mismatch(&concrete_type, self.def_id, self.tcx).emit(); + self.tainted_by_errors = Some(guar); } } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0f21fc1e66238..4f12965ad1db4 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -13,14 +13,13 @@ use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::visit::{TypeVisitableExt}; use rustc_middle::ty::TypeckResults; use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; use std::mem; -use std::ops::ControlFlow; /////////////////////////////////////////////////////////////////////////// // Entry point @@ -561,47 +560,34 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { for (opaque_type_key, decl) in opaque_types { let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span); let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span); - - struct RecursionChecker { - def_id: LocalDefId, - } - impl<'tcx> ty::TypeVisitor> for RecursionChecker { - type BreakTy = (); - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() { - if def_id == self.def_id.to_def_id() { - return ControlFlow::Break(()); - } - } - t.super_visit_with(self) + + // When defining an opaque to be literally itself we don't record that + // as it may be a non-defining use. MIR typecheck will handle this instead. + if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind() { + if alias_ty.def_id == opaque_type_key.def_id.to_def_id() { + continue; } } - if hidden_type - .visit_with(&mut RecursionChecker { def_id: opaque_type_key.def_id }) - .is_break() - { - continue; - } - let hidden_type = - self.tcx().erase_regions(hidden_type.remap_generic_params_to_declaration_params( - opaque_type_key, - self.tcx(), - true, - )); + let hidden_type = hidden_type + .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx(), true) + .map_bound(|hidden_type| self.tcx().erase_regions(hidden_type)); if let Some(last_opaque_ty) = self .typeck_results .concrete_opaque_types .insert(opaque_type_key.def_id, hidden_type) - && last_opaque_ty.ty != hidden_type.ty { - hidden_type - .report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx()) - .stash( - self.tcx().def_span(opaque_type_key.def_id), - StashKey::OpaqueHiddenTypeMismatch, - ); + let hidden_type = hidden_type.subst_identity(); + let last_opaque_ty = last_opaque_ty.subst_identity(); + if hidden_type.ty != last_opaque_ty.ty { + hidden_type + .report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx()) + .stash( + self.tcx().def_span(opaque_type_key.def_id), + StashKey::OpaqueHiddenTypeMismatch, + ); + } } } } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 53fd2dd23a705..2f90d5af341d1 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -227,7 +227,10 @@ pub struct BorrowCheckResult<'tcx> { /// All the opaque types that are restricted to concrete types /// by this function. Unlike the value in `TypeckResults`, this has /// unerased regions. - pub concrete_opaque_types: FxIndexMap>, + /// + /// Unlike the rest of the borrow check results, the hidden types are + /// in the scope of the opaque type, not the scope of the body. + pub concrete_opaque_types: FxIndexMap>>, pub closure_requirements: Option>, pub used_mut_upvars: SmallVec<[FieldIdx; 8]>, pub tainted_by_errors: Option, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 73f435d4840ac..a6a83195b43c3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1467,7 +1467,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> { tcx: TyCtxt<'tcx>, // typeck errors have subpar spans for opaque types, so delay error reporting until borrowck. ignore_errors: bool, - ) -> Self { + ) -> EarlyBinder { let OpaqueTypeKey { def_id, substs } = opaque_type_key; // Use substs to build up a reverse map from regions to their @@ -1488,7 +1488,12 @@ impl<'tcx> OpaqueHiddenType<'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, // after producing an error for each of them. - self.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span, ignore_errors)) + EarlyBinder(self.fold_with(&mut opaque_types::ReverseMapper::new( + tcx, + map, + self.span, + ignore_errors, + ))) } } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 43f95635ab00a..072dca88c5719 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -742,6 +742,18 @@ impl Iterator for EarlyBinderIter { } impl<'tcx, T: TypeFoldable>> ty::EarlyBinder { + /// Wraps `value` in a binder, asserting that `value` does not + /// contain any generic parameters that would be bound by the + /// binder. + #[track_caller] + pub fn dummy(value: T) -> EarlyBinder { + assert!( + !value.has_param(), + "`{value:?}` has generic parameters, so it cannot be wrapped in a dummy binder", + ); + EarlyBinder(value) + } + pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T { let mut folder = SubstFolder { tcx, substs, binders_passed: 0 }; self.0.fold_with(&mut folder) diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index e04dbbff9a777..cedd24bebf023 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -159,7 +159,7 @@ pub struct TypeckResults<'tcx> { /// These types are mapped back to the opaque's identity substitutions /// (with erased regions), which is why we don't associated substs with any /// of these usages. - pub concrete_opaque_types: FxIndexMap>, + pub concrete_opaque_types: FxIndexMap>>, /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index c19420bbb0ceb..0e1be0469b15b 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -10,12 +10,5 @@ note: previous use here LL | |x| x | ^^^^^ -error[E0720]: cannot resolve opaque type - --> $DIR/impl-fn-predefined-lifetimes.rs:4:35 - | -LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - | ^^^^^^^^^^^^^^^ cannot resolve opaque type - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr index 3c24eff9ae301..d4c5e7cc2c2a7 100644 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr @@ -13,12 +13,5 @@ LL | | "" LL | | } | |_____^ -error[E0720]: cannot resolve opaque type - --> $DIR/default-body-with-rpit.rs:12:28 - | -LL | async fn baz(&self) -> impl Debug { - | ^^^^^^^^^^ cannot resolve opaque type - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr index 3c24eff9ae301..d4c5e7cc2c2a7 100644 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr @@ -13,12 +13,5 @@ LL | | "" LL | | } | |_____^ -error[E0720]: cannot resolve opaque type - --> $DIR/default-body-with-rpit.rs:12:28 - | -LL | async fn baz(&self) -> impl Debug { - | ^^^^^^^^^^ cannot resolve opaque type - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`.