diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 33f07c1d8fc41..13e346b86bce3 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -279,8 +279,18 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // HACK This bubble is required for this tests to pass: // nested-return-type2-tait2.rs // nested-return-type2-tait3.rs - let infcx = - self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); + // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error` + // and prepopulate this `InferCtxt` with known opaque values, rather than + // using the `Bind` anchor here. For now it's fine. + let infcx = self + .tcx + .infer_ctxt() + .with_opaque_type_inference(if self.tcx.trait_solver_next() { + DefiningAnchor::Bind(def_id) + } else { + DefiningAnchor::Bubble + }) + .build(); let ocx = ObligationCtxt::new(&infcx); // 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 diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3b896f6540c07..908ff3da5ca0b 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -188,9 +188,6 @@ pub(crate) fn type_check<'mir, 'tcx>( // FIXME(-Ztrait-solver=next): A bit dubious that we're only registering // predefined opaques in the typeck root. - // FIXME(-Ztrait-solver=next): This is also totally wrong for TAITs, since - // the HIR typeck map defining usages back to their definition params, - // they won't actually match up with the usages in this body... if infcx.tcx.trait_solver_next() && !infcx.tcx.is_typeck_child(body.source.def_id()) { checker.register_predefined_opaques_in_new_solver(); } @@ -1042,10 +1039,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .typeck(self.body.source.def_id().expect_local()) .concrete_opaque_types .iter() - .map(|(&def_id, &hidden_ty)| { - let substs = ty::InternalSubsts::identity_for_item(self.infcx.tcx, def_id); - (ty::OpaqueTypeKey { def_id, substs }, hidden_ty) - }) + .map(|(k, v)| (*k, *v)) .collect(); let renumbered_opaques = self.infcx.tcx.fold_regions(opaques, |_, _| { 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..4d96a7ff4c3d7 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -1,3 +1,4 @@ +use rustc_errors::StashKey; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem}; @@ -59,7 +60,20 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local } } - let Some(hidden) = locator.found else { + if let Some(hidden) = locator.found { + // Only check against typeck if we didn't already error + if !hidden.ty.references_error() { + for concrete_type in locator.typeck_types { + if concrete_type.ty != tcx.erase_regions(hidden.ty) + && !(concrete_type, hidden).references_error() + { + hidden.report_mismatch(&concrete_type, def_id, tcx).emit(); + } + } + } + + hidden.ty + } else { let reported = tcx.sess.emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), name: tcx.item_name(tcx.local_parent(def_id).to_def_id()), @@ -70,21 +84,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local _ => "item", }, }); - return tcx.ty_error(reported); - }; - - // Only check against typeck if we didn't already error - if !hidden.ty.references_error() { - for concrete_type in locator.typeck_types { - if concrete_type.ty != tcx.erase_regions(hidden.ty) - && !(concrete_type, hidden).references_error() - { - hidden.report_mismatch(&concrete_type, def_id, tcx).emit(); - } - } + tcx.ty_error(reported) } - - hidden.ty } struct TaitConstraintLocator<'tcx> { @@ -130,13 +131,28 @@ impl TaitConstraintLocator<'_> { self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) }); return; } - let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else { + + let mut constrained = false; + for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types { + if opaque_type_key.def_id != self.def_id { + continue; + } + constrained = true; + let concrete_type = + self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params( + opaque_type_key, + self.tcx, + true, + )); + if self.typeck_types.iter().all(|prev| prev.ty != concrete_type.ty) { + self.typeck_types.push(concrete_type); + } + } + + if !constrained { debug!("no constraints in typeck results"); return; }; - if self.typeck_types.iter().all(|prev| prev.ty != typeck_hidden_ty.ty) { - self.typeck_types.push(typeck_hidden_ty); - } // Use borrowck to get the type with unerased regions. let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types; @@ -190,17 +206,45 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> { } } -pub(super) fn find_opaque_ty_constraints_for_rpit( - tcx: TyCtxt<'_>, +pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( + tcx: TyCtxt<'tcx>, def_id: LocalDefId, owner_def_id: LocalDefId, ) -> Ty<'_> { - let concrete = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied(); + let tables = tcx.typeck(owner_def_id); + + // Check that all of the opaques we inferred during HIR are compatible. + // FIXME: We explicitly don't check that the types inferred during HIR + // typeck are compatible with the one that we infer during borrowck, + // because that one actually sometimes has consts evaluated eagerly so + // using strict type equality will fail. + let mut hir_opaque_ty: Option> = None; + if tables.tainted_by_errors.is_none() { + for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types { + if opaque_type_key.def_id != def_id { + continue; + } + let concrete_type = tcx.erase_regions( + hidden_type.remap_generic_params_to_declaration_params(opaque_type_key, tcx, true), + ); + if let Some(prev) = &mut hir_opaque_ty { + if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() { + prev.report_mismatch(&concrete_type, def_id, tcx).stash( + tcx.def_span(opaque_type_key.def_id), + StashKey::OpaqueHiddenTypeMismatch, + ); + } + } else { + hir_opaque_ty = Some(concrete_type); + } + } + } - if let Some(concrete) = concrete { + let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied(); + if let Some(mir_opaque_ty) = mir_opaque_ty { 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: mir_opaque_ty }; match tcx.hir().get(scope) { Node::Item(it) => intravisit::walk_item(&mut locator, it), @@ -208,17 +252,18 @@ 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(|| { - 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 + mir_opaque_ty.ty + } else { + if let Some(guar) = tables.tainted_by_errors { + // Some error in the owner fn prevented us from populating // the `concrete_opaque_types` table. tcx.ty_error(guar) } else { - table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| { + // Fall back to the RPIT we inferred during HIR typeck + if let Some(hir_opaque_ty) = hir_opaque_ty { + hir_opaque_ty.ty + } 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, @@ -226,9 +271,9 @@ pub(super) fn find_opaque_ty_constraints_for_rpit( // For backwards compatibility reasons, we fall back to // `()` until we the diverging default is changed. tcx.mk_diverging_default() - }) + } } - }) + } } struct RpitConstraintChecker<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0f21fc1e66238..964acc4eb77ef 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -583,19 +583,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { continue; } - let hidden_type = - self.tcx().erase_regions(hidden_type.remap_generic_params_to_declaration_params( - opaque_type_key, - self.tcx(), - true, - )); - + // Here we only detect impl trait definition conflicts when they + // are equal modulo regions. if let Some(last_opaque_ty) = self .typeck_results .concrete_opaque_types - .insert(opaque_type_key.def_id, hidden_type) + .insert(opaque_type_key, hidden_type) && last_opaque_ty.ty != hidden_type.ty { + assert!(!self.tcx().trait_solver_next()); hidden_type .report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx()) .stash( diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index e04dbbff9a777..8cbffa14850fa 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -155,11 +155,7 @@ pub struct TypeckResults<'tcx> { /// We also store the type here, so that the compiler can use it as a hint /// for figuring out hidden types, even if they are only set in dead code /// (which doesn't show up in MIR). - /// - /// 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, ty::OpaqueHiddenType<'tcx>>, /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr index 7e64e67f24cdf..e6d46b02706b1 100644 --- a/tests/ui/chalkify/bugs/async.stderr +++ b/tests/ui/chalkify/bugs/async.stderr @@ -13,16 +13,9 @@ error: internal compiler error: projection clauses should be implied from elsewh LL | async fn foo(x: u32) -> u32 { | ^^^query stack during panic: #0 [typeck] type-checking `foo` -#1 [thir_body] building THIR for `foo` -#2 [check_match] match-checking `foo` -#3 [mir_built] building MIR for `foo` -#4 [unsafety_check_result] unsafety-checking `foo` -#5 [mir_const] preparing `foo` for borrow checking -#6 [mir_promoted] promoting constants in MIR for `foo` -#7 [mir_borrowck] borrow-checking `foo` -#8 [type_of] computing type of `foo::{opaque#0}` -#9 [check_mod_item_types] checking item types in top-level module -#10 [analysis] running analysis passes on this crate +#1 [type_of] computing type of `foo::{opaque#0}` +#2 [check_mod_item_types] checking item types in top-level module +#3 [analysis] running analysis passes on this crate end of query stack error: aborting due to 2 previous errors diff --git a/tests/ui/dyn-star/param-env-infer.next.stderr b/tests/ui/dyn-star/param-env-infer.next.stderr index 64d76bb04b1cb..408abecc30d44 100644 --- a/tests/ui/dyn-star/param-env-infer.next.stderr +++ b/tests/ui/dyn-star/param-env-infer.next.stderr @@ -13,41 +13,6 @@ error[E0391]: cycle detected when computing type of `make_dyn_star::{opaque#0}` LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: ...which requires borrow-checking `make_dyn_star`... - --> $DIR/param-env-infer.rs:11:1 - | -LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `make_dyn_star`... - --> $DIR/param-env-infer.rs:11:1 - | -LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires preparing `make_dyn_star` for borrow checking... - --> $DIR/param-env-infer.rs:11:1 - | -LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `make_dyn_star`... - --> $DIR/param-env-infer.rs:11:1 - | -LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `make_dyn_star`... - --> $DIR/param-env-infer.rs:11:1 - | -LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires match-checking `make_dyn_star`... - --> $DIR/param-env-infer.rs:11:1 - | -LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building THIR for `make_dyn_star`... - --> $DIR/param-env-infer.rs:11:1 - | -LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `make_dyn_star`... --> $DIR/param-env-infer.rs:11:1 | diff --git a/tests/ui/impl-trait/auto-trait-leak.stderr b/tests/ui/impl-trait/auto-trait-leak.stderr index aa4ee75bb7594..c0c4cd5013e5f 100644 --- a/tests/ui/impl-trait/auto-trait-leak.stderr +++ b/tests/ui/impl-trait/auto-trait-leak.stderr @@ -4,41 +4,6 @@ error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}` LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^ | -note: ...which requires borrow-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires preparing `cycle1` for borrow checking... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires match-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building THIR for `cycle1`... - --> $DIR/auto-trait-leak.rs:12:1 - | -LL | fn cycle1() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle1`... --> $DIR/auto-trait-leak.rs:14:5 | @@ -50,41 +15,6 @@ note: ...which requires computing type of `cycle2::{opaque#0}`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ -note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires preparing `cycle2` for borrow checking... - --> $DIR/auto-trait-leak.rs:19:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires match-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires building THIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 - | -LL | fn cycle2() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... --> $DIR/auto-trait-leak.rs:20:5 | diff --git a/tests/ui/impl-trait/multiple-defining-usages-in-body.rs b/tests/ui/impl-trait/multiple-defining-usages-in-body.rs index c3a6f09f86d93..86661153a0d09 100644 --- a/tests/ui/impl-trait/multiple-defining-usages-in-body.rs +++ b/tests/ui/impl-trait/multiple-defining-usages-in-body.rs @@ -4,9 +4,9 @@ impl Trait for () {} fn foo() -> impl Trait { //~^ WARN function cannot return without recursing [unconditional_recursion] let a: T = foo::(); - //~^ ERROR concrete type differs from previous defining opaque type use loop {} let _: T = foo::(); + //~^ ERROR concrete type differs from previous defining opaque type use } fn main() {} diff --git a/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr b/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr index 06991749bfad1..f3c090408b42e 100644 --- a/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr +++ b/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr @@ -11,15 +11,15 @@ LL | let a: T = foo::(); = note: `#[warn(unconditional_recursion)]` on by default error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-defining-usages-in-body.rs:6:16 + --> $DIR/multiple-defining-usages-in-body.rs:8:16 | -LL | let a: T = foo::(); - | ^^^^^^^^^^^^^ expected `U`, got `T` +LL | let _: T = foo::(); + | ^^^^^^^^^^^^^ expected `T`, got `U` | note: previous use here - --> $DIR/multiple-defining-usages-in-body.rs:9:16 + --> $DIR/multiple-defining-usages-in-body.rs:6:16 | -LL | let _: T = foo::(); +LL | let a: T = foo::(); | ^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs new file mode 100644 index 0000000000000..028222f4e6dba --- /dev/null +++ b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs @@ -0,0 +1,19 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +// Makes sure we don't prepopulate the MIR typeck of `define` +// with `Foo = T`, but instead, `Foo = B`, so that +// the param-env predicates actually apply. + +#![feature(type_alias_impl_trait)] + +type Foo = impl NeedsSend; + +trait NeedsSend {} +impl NeedsSend for T {} + +fn define(a: A, b: B) { + let y: Option> = Some(b); +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/cross_inference.rs b/tests/ui/type-alias-impl-trait/cross_inference.rs index dafaf40a69df4..07f3dd1997bed 100644 --- a/tests/ui/type-alias-impl-trait/cross_inference.rs +++ b/tests/ui/type-alias-impl-trait/cross_inference.rs @@ -1,3 +1,5 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next // check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs index 9ae2c34b935f2..da845e86147b7 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -8,7 +8,6 @@ type X = impl Into<&'static A>; fn f(a: &'static A, b: B) -> (X, X) { //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied - //~| ERROR concrete type differs from previous defining opaque type use (a, a) } diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr index 0d24d42ba62e8..66a6b0bbf7431 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -10,15 +10,6 @@ help: consider introducing a `where` clause, but there might be an alternative b LL | fn f(a: &'static A, b: B) -> (X, X) where &'static B: From<&A> { | ++++++++++++++++++++++++++ -error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn.rs:9:45 - | -LL | fn f(a: &'static A, b: B) -> (X, X) { - | ^^^^^^^^^^^^^^^^^^ - | | - | expected `&B`, got `&A` - | this expression supplies two conflicting concrete types for the same opaque type - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`.