From 5f044f352884cc627a0d6216581f68d9e045a7b4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 6 May 2024 15:20:13 +0000 Subject: [PATCH 1/3] BorrowckInferCtxt: infcx by value --- compiler/rustc_borrowck/src/consumers.rs | 4 +-- compiler/rustc_borrowck/src/lib.rs | 34 ++++++++----------- compiler/rustc_borrowck/src/nll.rs | 8 ++--- .../rustc_borrowck/src/region_infer/mod.rs | 9 ++--- compiler/rustc_borrowck/src/renumber.rs | 4 +-- compiler/rustc_borrowck/src/type_check/mod.rs | 6 ++-- .../rustc_borrowck/src/universal_regions.rs | 6 ++-- 7 files changed, 31 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 64726eacca7..b9fa46ea883 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -2,7 +2,6 @@ use rustc_hir::def_id::LocalDefId; use rustc_index::{IndexSlice, IndexVec}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::{Body, Promoted}; use rustc_middle::ty::TyCtxt; use std::rc::Rc; @@ -105,8 +104,7 @@ pub fn get_body_with_borrowck_facts( options: ConsumerOptions, ) -> BodyWithBorrowckFacts<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - let infcx = tcx.infer_ctxt().with_opaque_type_inference(def).build(); let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexSlice<_, _> = &promoted.borrow(); - *super::do_mir_borrowck(&infcx, input_body, promoted, Some(options)).1.unwrap() + *super::do_mir_borrowck(tcx, input_body, promoted, Some(options)).1.unwrap() } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 47c83e0bb2b..8f4da4ef746 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -23,9 +23,8 @@ use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::{BitSet, ChunkedBitSet}; use rustc_index::{IndexSlice, IndexVec}; -use rustc_infer::infer::{ - InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, -}; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; use rustc_middle::query::Providers; @@ -123,9 +122,8 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> { return tcx.arena.alloc(result); } - let infcx = tcx.infer_ctxt().with_opaque_type_inference(def).build(); let promoted: &IndexSlice<_, _> = &promoted.borrow(); - let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0; + let opt_closure_req = do_mir_borrowck(tcx, input_body, promoted, None).0; debug!("mir_borrowck done"); tcx.arena.alloc(opt_closure_req) @@ -136,18 +134,15 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> { /// Use `consumer_options: None` for the default behavior of returning /// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according /// to the given [`ConsumerOptions`]. -#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")] +#[instrument(skip(tcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")] fn do_mir_borrowck<'tcx>( - infcx: &InferCtxt<'tcx>, + tcx: TyCtxt<'tcx>, input_body: &Body<'tcx>, input_promoted: &IndexSlice>, consumer_options: Option, ) -> (BorrowCheckResult<'tcx>, Option>>) { let def = input_body.source.def_id().expect_local(); - debug!(?def); - - let tcx = infcx.tcx; - let infcx = BorrowckInferCtxt::new(infcx); + let infcx = BorrowckInferCtxt::new(tcx, def); let param_env = tcx.param_env(def); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); @@ -440,13 +435,14 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { (result, body_with_facts) } -pub struct BorrowckInferCtxt<'cx, 'tcx> { - pub(crate) infcx: &'cx InferCtxt<'tcx>, +pub struct BorrowckInferCtxt<'tcx> { + pub(crate) infcx: InferCtxt<'tcx>, pub(crate) reg_var_to_origin: RefCell>, } -impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { - pub(crate) fn new(infcx: &'cx InferCtxt<'tcx>) -> Self { +impl<'tcx> BorrowckInferCtxt<'tcx> { + pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + let infcx = tcx.infer_ctxt().with_opaque_type_inference(def_id).build(); BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()) } } @@ -494,16 +490,16 @@ pub(crate) fn next_nll_region_var( } } -impl<'cx, 'tcx> Deref for BorrowckInferCtxt<'cx, 'tcx> { +impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { type Target = InferCtxt<'tcx>; - fn deref(&self) -> &'cx Self::Target { - self.infcx + fn deref(&self) -> &Self::Target { + &self.infcx } } struct MirBorrowckCtxt<'cx, 'tcx> { - infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, + infcx: &'cx BorrowckInferCtxt<'tcx>, param_env: ParamEnv<'tcx>, body: &'cx Body<'tcx>, move_data: &'cx MoveData<'tcx>, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 4aa32a61f7c..49f50babdcb 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -51,7 +51,7 @@ pub(crate) struct NllOutput<'tcx> { /// `compute_regions`. #[instrument(skip(infcx, param_env, body, promoted), level = "debug")] pub(crate) fn replace_regions_in_mir<'tcx>( - infcx: &BorrowckInferCtxt<'_, 'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexSlice>, @@ -75,7 +75,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>( /// /// This may result in errors being reported. pub(crate) fn compute_regions<'cx, 'tcx>( - infcx: &BorrowckInferCtxt<'_, 'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, universal_regions: UniversalRegions<'tcx>, body: &Body<'tcx>, promoted: &IndexSlice>, @@ -202,7 +202,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( } pub(super) fn dump_mir_results<'tcx>( - infcx: &BorrowckInferCtxt<'_, 'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, @@ -254,7 +254,7 @@ pub(super) fn dump_mir_results<'tcx>( #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] pub(super) fn dump_annotation<'tcx>( - infcx: &BorrowckInferCtxt<'_, 'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 78465ad7975..54574446b55 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -250,10 +250,7 @@ pub enum ExtraConstraintInfo { } #[instrument(skip(infcx, sccs), level = "debug")] -fn sccs_info<'cx, 'tcx>( - infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, - sccs: Rc>, -) { +fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: Rc>) { use crate::renumber::RegionCtxt; let var_to_origin = infcx.reg_var_to_origin.borrow(); @@ -322,8 +319,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// The `outlives_constraints` and `type_tests` are an initial set /// of constraints produced by the MIR type check. - pub(crate) fn new<'cx>( - _infcx: &BorrowckInferCtxt<'cx, 'tcx>, + pub(crate) fn new( + _infcx: &BorrowckInferCtxt<'tcx>, var_infos: VarInfos, universal_regions: Rc>, placeholder_indices: Rc, diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index dca8df32800..f5757bcaa1d 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -11,7 +11,7 @@ /// inference variables, returning the number of variables created. #[instrument(skip(infcx, body, promoted), level = "debug")] pub fn renumber_mir<'tcx>( - infcx: &BorrowckInferCtxt<'_, 'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexSlice>, ) { @@ -57,7 +57,7 @@ pub(crate) fn preference_value(self) -> usize { } struct RegionRenumberer<'a, 'tcx> { - infcx: &'a BorrowckInferCtxt<'a, 'tcx>, + infcx: &'a BorrowckInferCtxt<'tcx>, } impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index b67c5d85818..65f0cf5afe8 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -122,7 +122,7 @@ macro_rules! span_mirbug_and_err { /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis /// - `elements` -- MIR region map pub(crate) fn type_check<'mir, 'tcx>( - infcx: &BorrowckInferCtxt<'_, 'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, promoted: &IndexSlice>, @@ -865,7 +865,7 @@ fn field_ty( /// way, it accrues region constraints -- these can later be used by /// NLL region checking. struct TypeChecker<'a, 'tcx> { - infcx: &'a BorrowckInferCtxt<'a, 'tcx>, + infcx: &'a BorrowckInferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, last_span: Span, body: &'a Body<'tcx>, @@ -1020,7 +1020,7 @@ pub fn span(&self, body: &Body<'_>) -> Span { impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn new( - infcx: &'a BorrowckInferCtxt<'a, 'tcx>, + infcx: &'a BorrowckInferCtxt<'tcx>, body: &'a Body<'tcx>, param_env: ty::ParamEnv<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 070238fc378..f8123535e2d 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -240,7 +240,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// signature. This will also compute the relationships that are /// known between those regions. pub fn new( - infcx: &BorrowckInferCtxt<'_, 'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId, param_env: ty::ParamEnv<'tcx>, ) -> Self { @@ -411,7 +411,7 @@ pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diag<'_, ()>) { } struct UniversalRegionsBuilder<'cx, 'tcx> { - infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, + infcx: &'cx BorrowckInferCtxt<'tcx>, mir_def: LocalDefId, param_env: ty::ParamEnv<'tcx>, } @@ -796,7 +796,7 @@ fn compute_inputs_and_output( } #[extension(trait InferCtxtExt<'tcx>)] -impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { +impl<'tcx> BorrowckInferCtxt<'tcx> { #[instrument(skip(self), level = "debug")] fn replace_free_regions_with_nll_infer_vars( &self, From 24ee32cf70468b66da1a45e89422ca64e42c851c Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 6 May 2024 16:04:57 +0000 Subject: [PATCH 2/3] borrowck: more eagerly prepopulate opaques --- compiler/rustc_borrowck/src/lib.rs | 28 ++++++++ compiler/rustc_borrowck/src/type_check/mod.rs | 71 +------------------ .../rustc_infer/src/infer/opaque_types/mod.rs | 13 ++++ .../dyn-trait-elided-two-inputs-ref-assoc.rs | 3 + .../in-trait/placeholder-implied-bounds.rs | 3 + tests/ui/impl-trait/issues/issue-105826.rs | 3 + ...llegal-upcast-from-impl-opaque.next.stderr | 14 ---- .../illegal-upcast-from-impl-opaque.rs | 29 -------- ... => upcast-defining-opaque.current.stderr} | 6 +- .../trait-upcasting/upcast-defining-opaque.rs | 24 +++++++ 10 files changed, 78 insertions(+), 116 deletions(-) delete mode 100644 tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr delete mode 100644 tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs rename tests/ui/traits/trait-upcasting/{illegal-upcast-from-impl-opaque.current.stderr => upcast-defining-opaque.current.stderr} (62%) create mode 100644 tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8f4da4ef746..abe57e26af4 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -182,6 +182,12 @@ fn do_mir_borrowck<'tcx>( nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes + // FIXME(-Znext-solver): A bit dubious that we're only registering + // predefined opaques in the typeck root. + if infcx.next_trait_solver() && !infcx.tcx.is_typeck_child(body.source.def_id()) { + infcx.register_predefined_opaques_for_next_solver(def); + } + let location_table = LocationTable::new(body); let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true); @@ -488,6 +494,28 @@ pub(crate) fn next_nll_region_var( next_region } + + /// With the new solver we prepopulate the opaque type storage during + /// MIR borrowck with the hidden types from HIR typeck. This is necessary + /// to avoid ambiguities as earlier goals can rely on the hidden type + /// of an opaque which is only constrained by a later goal. + fn register_predefined_opaques_for_next_solver(&self, def_id: LocalDefId) { + let tcx = self.tcx; + // OK to use the identity arguments for each opaque type key, since + // we remap opaques from HIR typeck back to their definition params. + for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) { + // HIR typeck did not infer the regions of the opaque, so we instantiate + // them with fresh inference variables. + let (key, hidden_ty) = tcx.fold_regions(data, |_, _| { + self.next_nll_region_var_in_universe( + NllRegionVariableOrigin::Existential { from_forall: false }, + ty::UniverseIndex::ROOT, + ) + }); + + self.inject_new_hidden_type_unchecked(key, hidden_ty); + } + } } impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 65f0cf5afe8..13acc672def 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -24,7 +24,6 @@ use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; -use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::visit::TypeVisitableExt; @@ -1028,7 +1027,7 @@ fn new( implicit_region_bound: ty::Region<'tcx>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, ) -> Self { - let mut checker = Self { + Self { infcx, last_span: body.span, body, @@ -1039,74 +1038,6 @@ fn new( implicit_region_bound, borrowck_context, reported_errors: Default::default(), - }; - - // FIXME(-Znext-solver): A bit dubious that we're only registering - // predefined opaques in the typeck root. - if infcx.next_trait_solver() && !infcx.tcx.is_typeck_child(body.source.def_id()) { - checker.register_predefined_opaques_for_next_solver(); - } - - checker - } - - pub(super) fn register_predefined_opaques_for_next_solver(&mut self) { - // OK to use the identity arguments for each opaque type key, since - // we remap opaques from HIR typeck back to their definition params. - let opaques: Vec<_> = self - .infcx - .tcx - .typeck(self.body.source.def_id().expect_local()) - .concrete_opaque_types - .iter() - .map(|(k, v)| (*k, *v)) - .collect(); - - let renumbered_opaques = self.infcx.tcx.fold_regions(opaques, |_, _| { - self.infcx.next_nll_region_var_in_universe( - NllRegionVariableOrigin::Existential { from_forall: false }, - ty::UniverseIndex::ROOT, - ) - }); - - let param_env = self.param_env; - let result = self.fully_perform_op( - Locations::All(self.body.span), - ConstraintCategory::OpaqueType, - CustomTypeOp::new( - |ocx| { - let mut obligations = Vec::new(); - for (opaque_type_key, hidden_ty) in renumbered_opaques { - let cause = ObligationCause::dummy(); - ocx.infcx.insert_hidden_type( - opaque_type_key, - &cause, - param_env, - hidden_ty.ty, - &mut obligations, - )?; - - ocx.infcx.add_item_bounds_for_hidden_type( - opaque_type_key.def_id.to_def_id(), - opaque_type_key.args, - cause, - param_env, - hidden_ty.ty, - &mut obligations, - ); - } - - ocx.register_obligations(obligations); - Ok(()) - }, - "register pre-defined opaques", - ), - ); - - if result.is_err() { - self.infcx - .dcx() - .span_bug(self.body.span, "failed re-defining predefined opaques in mir typeck"); } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 94a546f87ee..b7ee860cf07 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -485,6 +485,19 @@ fn register_hidden_type( Ok(InferOk { value: (), obligations }) } + /// Insert a hidden type into the opaque type storage, making sure + /// it hasn't previously been defined. This does not emit any + /// constraints and it's the responsibility of the caller to make + /// sure that the item bounds of the opaque are checked. + pub fn inject_new_hidden_type_unchecked( + &self, + opaque_type_key: OpaqueTypeKey<'tcx>, + hidden_ty: OpaqueHiddenType<'tcx>, + ) { + let prev = self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty); + assert_eq!(prev, None); + } + /// Insert a hidden type into the opaque type storage, equating it /// with any previous entries if necessary. /// diff --git a/tests/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs b/tests/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs index 2dc19b9ad68..e9706b656f2 100644 --- a/tests/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs +++ b/tests/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs @@ -2,6 +2,9 @@ // when there are multiple inputs. The `dyn Bar` should default to `+ // 'static`. This used to erroneously generate an error (cc #62517). // +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@ check-pass trait Foo { diff --git a/tests/ui/impl-trait/in-trait/placeholder-implied-bounds.rs b/tests/ui/impl-trait/in-trait/placeholder-implied-bounds.rs index f7546a05bfd..df03150e29a 100644 --- a/tests/ui/impl-trait/in-trait/placeholder-implied-bounds.rs +++ b/tests/ui/impl-trait/in-trait/placeholder-implied-bounds.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@ check-pass pub fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-105826.rs b/tests/ui/impl-trait/issues/issue-105826.rs index e3488140dcc..33c5ed5fdeb 100644 --- a/tests/ui/impl-trait/issues/issue-105826.rs +++ b/tests/ui/impl-trait/issues/issue-105826.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@ check-pass use std::io::Write; diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr deleted file mode 100644 index 3c2bc0b9190..00000000000 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: internal compiler error: error performing operation: query type op - --> $DIR/illegal-upcast-from-impl-opaque.rs:25:1 - | -LL | fn illegal(x: &dyn Sub) -> &dyn Super { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: - --> $DIR/illegal-upcast-from-impl-opaque.rs:25:1 - | -LL | fn illegal(x: &dyn Sub) -> &dyn Super { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -query stack during panic: -end of query stack diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs deleted file mode 100644 index f344474054a..00000000000 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ revisions: current next -//@[next] compile-flags: -Znext-solver -//@[next] failure-status: 101 -//@[next] known-bug: unknown -//@[next] normalize-stderr-test "note: .*\n\n" -> "" -//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" -//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@[next] normalize-stderr-test "delayed at .*" -> "" -//@[next] rustc-env:RUST_BACKTRACE=0 - -#![feature(trait_upcasting, type_alias_impl_trait)] - -trait Super { - type Assoc; -} - -trait Sub: Super {} - -impl Super for T { - type Assoc = i32; -} - -type Foo = impl Sized; - -fn illegal(x: &dyn Sub) -> &dyn Super { - x //[current]~ mismatched types -} - -fn main() {} diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr similarity index 62% rename from tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr rename to tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr index c54a1c42bad..a259abb28ae 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr +++ b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr @@ -1,11 +1,11 @@ error[E0308]: mismatched types - --> $DIR/illegal-upcast-from-impl-opaque.rs:26:5 + --> $DIR/upcast-defining-opaque.rs:21:5 | LL | type Foo = impl Sized; | ---------- the found opaque type LL | -LL | fn illegal(x: &dyn Sub) -> &dyn Super { - | ----------------------- expected `&dyn Super` because of return type +LL | fn upcast(x: &dyn Sub) -> &dyn Super { + | ----------------------- expected `&dyn Super` because of return type LL | x | ^ expected trait `Super`, found trait `Sub` | diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs new file mode 100644 index 00000000000..cb1501a94a2 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs @@ -0,0 +1,24 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] check-pass + +#![feature(trait_upcasting, type_alias_impl_trait)] + +trait Super { + type Assoc; +} + +trait Sub: Super {} + +impl Super for T { + type Assoc = i32; +} + +type Foo = impl Sized; + +fn upcast(x: &dyn Sub) -> &dyn Super { + x //[current]~ mismatched types +} + +fn main() {} From 5714c1f364a29b0bd771934498e647145fd2d3f6 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 6 May 2024 16:19:32 +0000 Subject: [PATCH 3/3] switch new solver to directly inject opaque types --- .../src/solve/eval_ctxt/canonical.rs | 11 ++++------- .../rustc_trait_selection/src/solve/eval_ctxt/mod.rs | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index d6bf2b596ef..5f73432750d 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -236,7 +236,7 @@ pub(super) fn instantiate_and_apply_query_response( normalization_nested_goals, } = external_constraints.deref(); self.register_region_constraints(region_constraints); - self.register_new_opaque_types(param_env, opaque_types); + self.register_new_opaque_types(opaque_types); (normalization_nested_goals.clone(), certainty) } @@ -368,13 +368,10 @@ fn register_region_constraints(&mut self, region_constraints: &QueryRegionConstr assert!(region_constraints.member_constraints.is_empty()); } - fn register_new_opaque_types( - &mut self, - param_env: ty::ParamEnv<'tcx>, - opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)], - ) { + fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)]) { for &(key, ty) in opaque_types { - self.insert_hidden_type(key, param_env, ty).unwrap(); + let hidden_ty = ty::OpaqueHiddenType { ty, span: DUMMY_SP }; + self.infcx.inject_new_hidden_type_unchecked(key, hidden_ty); } } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 773babde0d7..f59393e221b 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -248,8 +248,8 @@ fn enter_canonical( }; for &(key, ty) in &input.predefined_opaques_in_body.opaque_types { - ecx.insert_hidden_type(key, input.goal.param_env, ty) - .expect("failed to prepopulate opaque types"); + let hidden_ty = ty::OpaqueHiddenType { ty, span: DUMMY_SP }; + ecx.infcx.inject_new_hidden_type_unchecked(key, hidden_ty); } if !ecx.nested_goals.is_empty() {