diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 64726eacca74..b9fa46ea883f 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 47c83e0bb2bb..abe57e26af46 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -23,9 +23,8 @@ use rustc_hir as hir; 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); @@ -187,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); @@ -440,13 +441,14 @@ fn do_mir_borrowck<'tcx>( (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()) } } @@ -492,18 +494,40 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { 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<'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 4aa32a61f7c3..49f50babdcb9 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 78465ad7975d..54574446b559 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 dca8df328002..f5757bcaa1d1 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -11,7 +11,7 @@ use rustc_span::Symbol; /// 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 @@ impl RegionCtxt { } 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 b67c5d858183..13acc672defb 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::tcx::PlaceTy; 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; @@ -122,7 +121,7 @@ mod relate_tys; /// - `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 +864,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { /// 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 +1019,7 @@ impl Locations { 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>, @@ -1028,7 +1027,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { 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 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { 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_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 070238fc3788..f8123535e2d0 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 @@ impl<'tcx> UniversalRegions<'tcx> { } 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 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } #[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, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 32e1b19eaaeb..9737e04028bc 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -344,7 +344,12 @@ fn check_opaque_meets_bounds<'tcx>( }; let param_env = tcx.param_env(defining_use_anchor); - let infcx = tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).build(); + let infcx = tcx + .infer_ctxt() + .with_opaque_type_mode(ty::OpaqueTypeMode::Reveal( + tcx.opaque_types_defined_by(defining_use_anchor), + )) + .build(); let ocx = ObligationCtxt::new(&infcx); let args = match *origin { @@ -358,42 +363,23 @@ fn check_opaque_meets_bounds<'tcx>( }), }; - let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); - - // `ReErased` regions appear in the "parent_args" of closures/coroutines. - // We're ignoring them here and replacing them with fresh region variables. - // See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs. - // - // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it - // here rather than using ReErased. - let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args); - let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() { - ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)), - _ => re, - }); - let misc_cause = traits::ObligationCause::misc(span, def_id); - - match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) { - Ok(()) => {} - Err(ty_err) => { - // Some types may be left "stranded" if they can't be reached - // from a lowered rustc_middle bound but they're mentioned in the HIR. - // This will happen, e.g., when a nested opaque is inside of a non- - // existent associated type, like `impl Trait`. - // See . - let ty_err = ty_err.to_string(tcx); - let guar = tcx.dcx().span_delayed_bug( - span, - format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"), - ); - return Err(guar); - } - } + let predicates: Vec<_> = tcx.item_bounds(def_id).iter_instantiated(tcx, args).collect(); + let predicates = ocx.normalize(&misc_cause, param_env, predicates); + ocx.register_obligations( + predicates + .into_iter() + .map(|clause| Obligation::new(tcx, misc_cause.clone(), param_env, clause)), + ); // Additionally 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 hidden_ty = + tcx.fold_regions(tcx.type_of(def_id).instantiate(tcx, args), |re, _| match *re { + ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)), + _ => re, + }); let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(hidden_ty.into()))); ocx.register_obligation(Obligation::new(tcx, misc_cause.clone(), param_env, predicate)); @@ -411,23 +397,7 @@ fn check_opaque_meets_bounds<'tcx>( let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?; - if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin { - // HACK: this should also fall through to the hidden type check below, but the original - // implementation had a bug where equivalent lifetimes are not identical. This caused us - // to reject existing stable code that is otherwise completely fine. The real fix is to - // compare the hidden types via our type equivalence/relation infra instead of doing an - // identity check. - let _ = infcx.take_opaque_types(); - Ok(()) - } else { - // Check that any hidden types found during wf checking match the hidden types that `type_of` sees. - for (mut key, mut ty) in infcx.take_opaque_types() { - ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty); - key = infcx.resolve_vars_if_possible(key); - sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?; - } - Ok(()) - } + Ok(()) } fn sanity_check_found_hidden_type<'tcx>( diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 0f21d3966c40..aec4839c3fd1 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -75,7 +75,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn fork_with_intercrate(&self, intercrate: bool) -> Self { Self { tcx: self.tcx, - defining_opaque_types: self.defining_opaque_types, + opaque_type_mode: self.opaque_type_mode, considering_regions: self.considering_regions, skip_leak_check: self.skip_leak_check, inner: self.inner.clone(), diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 4d712e9ffd37..86613f28ad8c 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -59,7 +59,7 @@ impl<'tcx> InferCtxt<'tcx> { }, ); - param_env.defining_opaque_types = self.defining_opaque_types; + param_env.opaque_type_mode = self.opaque_type_mode; Canonicalizer::canonicalize_with_base( param_env, @@ -543,7 +543,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { max_universe: ty::UniverseIndex::ROOT, variables: List::empty(), value: (), - defining_opaque_types: infcx.map(|i| i.defining_opaque_types).unwrap_or_default(), + opaque_type_mode: infcx.map(|i| i.opaque_type_mode).unwrap_or_default(), }; Canonicalizer::canonicalize_with_base( base, @@ -613,14 +613,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { .max() .unwrap_or(ty::UniverseIndex::ROOT); - assert!( - !infcx.is_some_and(|infcx| infcx.defining_opaque_types != base.defining_opaque_types) - ); + assert!(!infcx.is_some_and(|infcx| infcx.opaque_type_mode != base.opaque_type_mode)); Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value), - defining_opaque_types: base.defining_opaque_types, + opaque_type_mode: base.opaque_type_mode, } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bb53aec0b4d1..c460456a2d99 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -5,6 +5,8 @@ pub use relate::combine::CombineFields; pub use relate::combine::ObligationEmittingRelation; pub use relate::StructurallyRelateAliases; pub use rustc_macros::{TypeFoldable, TypeVisitable}; +use rustc_middle::traits::Reveal; +use rustc_middle::traits::TreatOpaque; pub use rustc_middle::ty::IntVarValue; pub use BoundRegionConversionTime::*; pub use RegionVariableOrigin::*; @@ -245,7 +247,7 @@ pub struct InferCtxt<'tcx> { pub tcx: TyCtxt<'tcx>, /// The `DefIds` of the opaque types that may have their hidden types constrained. - defining_opaque_types: &'tcx ty::List, + opaque_type_mode: ty::OpaqueTypeMode>, /// Whether this inference context should care about region obligations in /// the root universe. Most notably, this is used during hir typeck as region @@ -393,8 +395,8 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> { self.probe_const_var(vid).ok() } - fn defining_opaque_types(&self) -> &'tcx ty::List { - self.defining_opaque_types + fn opaque_type_mode(&self) -> ty::OpaqueTypeMode> { + self.opaque_type_mode } } @@ -610,7 +612,7 @@ impl fmt::Display for FixupError { /// Used to configure inference contexts before their creation. pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, - defining_opaque_types: &'tcx ty::List, + opaque_type_mode: ty::OpaqueTypeMode>, considering_regions: bool, skip_leak_check: bool, /// Whether we are in coherence mode. @@ -625,7 +627,7 @@ impl<'tcx> TyCtxt<'tcx> { fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> { InferCtxtBuilder { tcx: self, - defining_opaque_types: ty::List::empty(), + opaque_type_mode: Default::default(), considering_regions: true, skip_leak_check: false, intercrate: false, @@ -635,6 +637,14 @@ impl<'tcx> TyCtxt<'tcx> { } impl<'tcx> InferCtxtBuilder<'tcx> { + pub fn with_opaque_type_mode( + mut self, + opaque_type_mode: ty::OpaqueTypeMode>, + ) -> Self { + self.opaque_type_mode = opaque_type_mode; + self + } + /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types, /// you need to call this function. Otherwise the opaque type will be treated opaquely. /// @@ -642,15 +652,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> { /// (via `Inherited::build`) and for the inference context used /// in mir borrowck. pub fn with_opaque_type_inference(mut self, defining_anchor: LocalDefId) -> Self { - self.defining_opaque_types = self.tcx.opaque_types_defined_by(defining_anchor); - self - } - - pub fn with_defining_opaque_types( - mut self, - defining_opaque_types: &'tcx ty::List, - ) -> Self { - self.defining_opaque_types = defining_opaque_types; + let types = self.tcx.opaque_types_defined_by(defining_anchor); + self.opaque_type_mode = ty::OpaqueTypeMode::Define(types); self } @@ -689,7 +692,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { where T: TypeFoldable>, { - let infcx = self.with_defining_opaque_types(canonical.defining_opaque_types).build(); + let infcx = self.with_opaque_type_mode(canonical.opaque_type_mode).build(); let (value, args) = infcx.instantiate_canonical(span, canonical); (infcx, value, args) } @@ -697,7 +700,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { pub fn build(&mut self) -> InferCtxt<'tcx> { let InferCtxtBuilder { tcx, - defining_opaque_types, + opaque_type_mode: defining_opaque_types, considering_regions, skip_leak_check, intercrate, @@ -705,7 +708,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } = *self; InferCtxt { tcx, - defining_opaque_types, + opaque_type_mode: defining_opaque_types, considering_regions, skip_leak_check, inner: RefCell::new(InferCtxtInner::new()), @@ -1234,10 +1237,30 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow().opaque_type_storage.opaque_types.clone() } - #[inline(always)] - pub fn can_define_opaque_ty(&self, id: impl Into) -> bool { - let Some(id) = id.into().as_local() else { return false }; - self.defining_opaque_types.contains(&id) + pub fn treat_opaque_ty(&self, reveal: Reveal, def_id: DefId) -> TreatOpaque { + if self.intercrate { + return TreatOpaque::Ambiguous; + } + + match reveal { + Reveal::All => return TreatOpaque::Reveal, + Reveal::UserFacing => {} + } + + match self.opaque_type_mode { + ty::OpaqueTypeMode::Define(list) => { + if def_id.as_local().is_some_and(|def_id| list.contains(&def_id)) { + return TreatOpaque::Define; + } + } + ty::OpaqueTypeMode::Reveal(list) => { + if def_id.as_local().is_some_and(|def_id| list.contains(&def_id)) { + return TreatOpaque::Reveal; + } + } + } + + TreatOpaque::Rigid } pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 94a546f87eee..05a8a5b8211e 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -7,7 +7,7 @@ use hir::def_id::{DefId, LocalDefId}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::Lrc; use rustc_hir as hir; -use rustc_middle::traits::ObligationCause; +use rustc_middle::traits::{ObligationCause, TreatOpaque}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::GenericArgKind; @@ -59,7 +59,10 @@ impl<'tcx> InferCtxt<'tcx> { ct_op: |ct| ct, ty_op: |ty| match *ty.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) - if self.can_define_opaque_ty(def_id) && !ty.has_escaping_bound_vars() => + if matches!( + self.treat_opaque_ty(param_env.reveal(), def_id), + TreatOpaque::Define + ) && !ty.has_escaping_bound_vars() => { let def_span = self.tcx.def_span(def_id); let span = if span.contains(def_span) { def_span } else { span }; @@ -86,16 +89,6 @@ impl<'tcx> InferCtxt<'tcx> { ) -> InferResult<'tcx, ()> { let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { - let def_id = def_id.expect_local(); - if self.intercrate { - // See comment on `insert_hidden_type` for why this is sufficient in coherence - return Some(self.register_hidden_type( - OpaqueTypeKey { def_id, args }, - cause.clone(), - param_env, - b, - )); - } // Check that this is `impl Trait` type is // declared by `parent_def_id` -- i.e., one whose // value we are inferring. At present, this is @@ -130,8 +123,18 @@ impl<'tcx> InferCtxt<'tcx> { // let x = || foo(); // returns the Opaque assoc with `foo` // } // ``` - if !self.can_define_opaque_ty(def_id) { - return None; + match self.treat_opaque_ty(param_env.reveal(), def_id) { + TreatOpaque::Define => {} + TreatOpaque::Reveal | TreatOpaque::Rigid => return None, + TreatOpaque::Ambiguous => { + // See comment on `insert_hidden_type` for why this is sufficient in coherence + return Some(self.register_hidden_type( + OpaqueTypeKey { def_id: def_id.expect_local(), args }, + cause.clone(), + param_env, + b, + )); + } } if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() { @@ -140,8 +143,10 @@ impl<'tcx> InferCtxt<'tcx> { // no one encounters it in practice. // It does occur however in `fn fut() -> impl Future { async { 42 } }`, // where it is of no concern, so we only check for TAITs. - if self.can_define_opaque_ty(b_def_id) - && self.tcx.is_type_alias_impl_trait(b_def_id) + if matches!( + self.treat_opaque_ty(param_env.reveal(), b_def_id), + TreatOpaque::Define + ) && self.tcx.is_type_alias_impl_trait(b_def_id) { self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag { span: cause.span, @@ -151,7 +156,7 @@ impl<'tcx> InferCtxt<'tcx> { } } Some(self.register_hidden_type( - OpaqueTypeKey { def_id, args }, + OpaqueTypeKey { def_id: def_id.expect_local(), args }, cause.clone(), param_env, b, @@ -485,6 +490,19 @@ impl<'tcx> InferCtxt<'tcx> { 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/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 36f9dda7250c..50a43b4239e7 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -801,7 +801,7 @@ fn test_unstable_options_tracking_hash() { tracked!(mutable_noalias, false); tracked!( next_solver, - Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() }) + Some(NextSolverConfig { coherence: true, globally: true, dump_tree: Default::default() }) ); tracked!(no_generate_arange_section, true); tracked!(no_jump_tables, true); diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index aee97d772229..f6c54b1f610a 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -325,7 +325,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> { max_universe: ty::UniverseIndex::ROOT, variables: List::empty(), value: key, - defining_opaque_types: ty::List::empty(), + opaque_type_mode: Default::default(), }; } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 8a4e3ab0e619..6c4fcc33cbf9 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -325,7 +325,7 @@ macro_rules! define_callbacks { // Increase this limit if necessary, but do try to keep the size low if possible #[cfg(target_pointer_width = "64")] const _: () = { - if mem::size_of::>() > 72 { + if mem::size_of::>() > 84 { panic!("{}", concat!( "the query `", stringify!($name), diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 1ae037e09a75..2df0a13b5d9b 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -82,6 +82,13 @@ pub enum Reveal { All, } +pub enum TreatOpaque { + Reveal, + Define, + Rigid, + Ambiguous, +} + /// The reason why we incurred this obligation; used for error reporting. /// /// Non-misc `ObligationCauseCode`s are stored on the heap. This gives the diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index bade0d564156..a62d8e68f8ee 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -194,7 +194,7 @@ impl<'tcx> CapturedPlace<'tcx> { #[derive(Copy, Clone, Debug, HashStable)] pub struct ClosureTypeInfo<'tcx> { - user_provided_sig: ty::CanonicalPolyFnSig<'tcx>, + user_provided_sig: &'tcx ty::CanonicalPolyFnSig<'tcx>, captures: &'tcx ty::List<&'tcx ty::CapturedPlace<'tcx>>, kind_origin: Option<&'tcx (Span, HirPlace<'tcx>)>, } @@ -202,7 +202,7 @@ pub struct ClosureTypeInfo<'tcx> { fn closure_typeinfo<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ClosureTypeInfo<'tcx> { debug_assert!(tcx.is_closure_like(def.to_def_id())); let typeck_results = tcx.typeck(def); - let user_provided_sig = typeck_results.user_provided_sigs[&def]; + let user_provided_sig = &typeck_results.user_provided_sigs[&def]; let captures = typeck_results.closure_min_captures_flattened(def); let captures = tcx.mk_captures_from_iter(captures); let hir_id = tcx.local_def_id_to_hir_id(def); @@ -216,7 +216,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn closure_user_provided_sig(self, def_id: LocalDefId) -> ty::CanonicalPolyFnSig<'tcx> { - self.closure_typeinfo(def_id).user_provided_sig + *self.closure_typeinfo(def_id).user_provided_sig } pub fn closure_captures(self, def_id: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] { diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 6600b92fb318..d895d5434c1a 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -69,8 +69,8 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> Canonicalizer<'a, Infc let (max_universe, variables) = canonicalizer.finalize(); - let defining_opaque_types = infcx.defining_opaque_types(); - Canonical { defining_opaque_types, max_universe, variables, value } + let opaque_type_mode = infcx.opaque_type_mode(); + Canonical { opaque_type_mode, max_universe, variables, value } } fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVars) { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f2bdabbf3942..a1d2394a1c9a 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -790,6 +790,16 @@ pub struct NextSolverConfig { pub dump_tree: DumpSolverProofTree, } +impl Default for NextSolverConfig { + fn default() -> Self { + NextSolverConfig { + coherence: true, + globally: true, + dump_tree: DumpSolverProofTree::default(), + } + } +} + #[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum DumpSolverProofTree { Always, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 65660286dd73..15c06244813c 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -399,7 +399,7 @@ mod desc { pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; - pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error"; + pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `no`, `dump-tree`, `dump-tree-on-error"; pub const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = @@ -1061,6 +1061,10 @@ mod parse { let mut dump_tree = None; for c in config.split(',') { match c { + "no" => { + *slot = None; + return true; + } "globally" => globally = true, "coherence" => { globally = false; @@ -1815,7 +1819,7 @@ options! { "the size at which the `large_assignments` lint starts to be emitted"), mutable_noalias: bool = (true, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: yes)"), - next_solver: Option = (None, parse_next_solver_config, [TRACKED], + next_solver: Option = (Some(NextSolverConfig::default()), parse_next_solver_config, [TRACKED], "enable and configure the next generation trait solver used by rustc"), nll_facts: bool = (false, parse_bool, [UNTRACKED], "dump facts from NLL analysis into side files (default: no)"), diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index f2ca42a0be91..adf8b3c06583 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -846,7 +846,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let Some(result) = self.try_merge_responses(&responses) { return Ok(result); } else { - self.flounder(&responses) - } + let param_env_candidates = candidates.iter().filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))).map(|c| c.result).collect::>(); + if let Some(result) = self.try_merge_responses(¶m_env_candidates) { + return Ok(result); + } else { + self.flounder(&responses) + } + } } } 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 d6bf2b596ef1..6546c57c70e8 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -21,7 +21,7 @@ use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::RegionVariableOrigin; -use rustc_infer::infer::{InferCtxt, InferOk}; +use rustc_infer::infer::{InferCtxt,}; use rustc_infer::traits::solve::NestedNormalizationGoals; use rustc_middle::infer::canonical::Canonical; use rustc_middle::infer::unify_key::ConstVariableOrigin; @@ -236,7 +236,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { 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) } @@ -347,12 +347,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let cause = ObligationCause::dummy(); for (&orig, response) in iter::zip(original_values, var_values.var_values) { - let InferOk { value: (), obligations } = infcx + let _ = infcx .at(&cause, param_env) .trace(orig, response) - .eq_structurally_relating_aliases(orig, response) - .unwrap(); - assert!(obligations.is_empty()); + .eq_structurally_relating_aliases(orig, response); } } @@ -368,13 +366,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { 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 773babde0d7b..38bda77e3c19 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -4,11 +4,12 @@ use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{ - BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt, + BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, RegionVariableOrigin, + TyCtxtInferExt, }; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals}; -use rustc_infer::traits::ObligationCause; +use rustc_infer::traits::{ObligationCause, Reveal, TreatOpaque}; use rustc_macros::{extension, HashStable}; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::infer::unify_key::ConstVariableOrigin; @@ -248,8 +249,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { }; 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() { @@ -600,6 +601,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ty } + pub(super) fn next_region_infer(&mut self) -> ty::Region<'tcx> { + let ty = self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP)); + self.inspect.add_var_value(ty); + ty + } + pub(super) fn next_const_infer(&mut self, ty: Ty<'tcx>) -> ty::Const<'tcx> { let ct = self .infcx @@ -958,8 +965,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { .map(|is_knowable| is_knowable.is_ok()) } - pub(super) fn can_define_opaque_ty(&self, def_id: impl Into) -> bool { - self.infcx.can_define_opaque_ty(def_id) + pub(super) fn treat_opaque_ty(&self, reveal: Reveal, def_id: DefId) -> TreatOpaque { + self.infcx.treat_opaque_ty(reveal, def_id) } pub(super) fn insert_hidden_type( diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index b2b076e28e64..03621c6a1aac 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -305,6 +305,6 @@ fn response_no_constraints_raw<'tcx>( external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()), certainty, }, - defining_opaque_types: Default::default(), + opaque_type_mode: Default::default(), } } diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs index 9fdb280cdc6d..23af3a676bc6 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs @@ -3,11 +3,11 @@ //! the opaque is in a defining scope. use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; -use rustc_middle::traits::Reveal; +use rustc_middle::traits::TreatOpaque; use rustc_middle::ty; use rustc_middle::ty::util::NotUniqueParam; -use crate::solve::{EvalCtxt, SolverMode}; +use crate::solve::EvalCtxt; impl<'tcx> EvalCtxt<'_, 'tcx> { pub(super) fn normalize_opaque_type( @@ -18,17 +18,36 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let opaque_ty = goal.predicate.alias; let expected = goal.predicate.term.ty().expect("no such thing as an opaque const"); - match (goal.param_env.reveal(), self.solver_mode()) { - (Reveal::UserFacing, SolverMode::Normal) => { - let Some(opaque_ty_def_id) = opaque_ty.def_id.as_local() else { - return Err(NoSolution); - }; + match self.treat_opaque_ty(goal.param_env.reveal(), opaque_ty.def_id) { + TreatOpaque::Rigid => Err(NoSolution), + TreatOpaque::Ambiguous => { + // An impossible opaque type bound is the only way this goal will fail + // e.g. assigning `impl Copy := NotCopy` + self.add_item_bounds_for_hidden_type( + opaque_ty.def_id, + opaque_ty.args, + goal.param_env, + expected, + ); + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } + TreatOpaque::Reveal => { + // FIXME: Add an assertion that opaque type storage is empty. + let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args); + let actual = tcx.fold_regions(actual, |re, _| match *re { + ty::ReErased => self.next_region_infer(), + _ => re, + }); + self.eq(goal.param_env, expected, actual)?; + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + TreatOpaque::Define => { // FIXME: at some point we should call queries without defining // new opaque types but having the existing opaque type definitions. // This will require moving this below "Prefer opaques registered already". - if !self.can_define_opaque_ty(opaque_ty_def_id) { + let Some(opaque_ty_def_id) = opaque_ty.def_id.as_local() else { return Err(NoSolution); - } + }; // FIXME: This may have issues when the args contain aliases... match self.tcx().uses_unique_placeholders_ignoring_regions(opaque_ty.args) { Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => { @@ -68,23 +87,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } - (Reveal::UserFacing, SolverMode::Coherence) => { - // An impossible opaque type bound is the only way this goal will fail - // e.g. assigning `impl Copy := NotCopy` - self.add_item_bounds_for_hidden_type( - opaque_ty.def_id, - opaque_ty.args, - goal.param_env, - expected, - ); - self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - } - (Reveal::All, _) => { - // FIXME: Add an assertion that opaque type storage is empty. - let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args); - self.eq(goal.param_env, expected, actual)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } } } } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index d2b893d6383b..aa2527734e7d 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -12,7 +12,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::MaybeCause; use rustc_middle::traits::solve::inspect::ProbeKind; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult}; -use rustc_middle::traits::{BuiltinImplSource, Reveal}; +use rustc_middle::traits::{BuiltinImplSource, TreatOpaque}; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_middle::ty::{TraitPredicate, TypeVisitableExt}; @@ -145,7 +145,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // ideally we want to avoid, since we can make progress on this goal // via an alias bound or a locally-inferred hidden type instead. // - // Also, don't call `type_of` on a TAIT in `Reveal::All` mode, since + // Also, don't call `type_of` on a TAIT when it can be revealed, since // we already normalize the self type in // `assemble_candidates_after_normalizing_self_ty`, and we'd // just be registering an identical candidate here. @@ -155,10 +155,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // `assemble_candidates_after_normalizing_self_ty` due to normalizing // the TAIT. if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() { - if matches!(goal.param_env.reveal(), Reveal::All) - || matches!(ecx.solver_mode(), SolverMode::Coherence) - || ecx.can_define_opaque_ty(opaque_ty.def_id) - { + if matches!( + ecx.treat_opaque_ty(goal.param_env.reveal(), opaque_ty.def_id), + TreatOpaque::Reveal | TreatOpaque::Define | TreatOpaque::Ambiguous + ) { return Err(NoSolution); } } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 56f8b4b9cdb8..4f5d7b9edce3 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -389,6 +389,26 @@ pub fn normalize_param_env_or_error<'tcx>( let mut predicates = non_outlives_predicates; predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); + if tcx.next_trait_solver_globally() { + predicates.retain(|&p| { + if p.is_global() { + let infcx = tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); + let param_env = ty::ParamEnv::empty(); + ocx.register_obligation(Obligation::new(tcx, ObligationCause::dummy(), param_env, p)); + if !ocx.select_all_or_error().is_empty() { + true + } else if ocx.resolve_regions(&OutlivesEnvironment::new(param_env)).is_empty() { + // A trivially true global bound, ignore it. + false + } else { + true + } + } else { + true + } + }) + } ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()) } diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 43f4fa8e81ca..88f73d7c50ef 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -6,7 +6,9 @@ use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, Placeh use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; use rustc_infer::infer::InferOk; +use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::traits::PredicateObligation; +use rustc_infer::traits::TreatOpaque; use rustc_infer::traits::{FulfillmentError, Normalized, Obligation, TraitEngine}; use rustc_macros::extension; use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal}; @@ -100,21 +102,17 @@ where pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( value: &T, - reveal: Reveal, + _reveal: Reveal, ) -> bool { + //TODO: // This mirrors `ty::TypeFlags::HAS_ALIASES` except that we take `Reveal` into account. - - let mut flags = ty::TypeFlags::HAS_TY_PROJECTION - | ty::TypeFlags::HAS_TY_WEAK - | ty::TypeFlags::HAS_TY_INHERENT - | ty::TypeFlags::HAS_CT_PROJECTION; - - match reveal { - Reveal::UserFacing => {} - Reveal::All => flags |= ty::TypeFlags::HAS_TY_OPAQUE, - } - - value.has_type_flags(flags) + value.has_type_flags( + ty::TypeFlags::HAS_TY_PROJECTION + | ty::TypeFlags::HAS_TY_WEAK + | ty::TypeFlags::HAS_TY_INHERENT + | ty::TypeFlags::HAS_CT_PROJECTION + | ty::TypeFlags::HAS_TY_OPAQUE, + ) } struct AssocTypeNormalizer<'a, 'b, 'tcx> { @@ -205,11 +203,8 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx match kind { ty::Opaque => { - // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.param_env.reveal() { - Reveal::UserFacing => ty.super_fold_with(self), - - Reveal::All => { + match self.selcx.infcx.treat_opaque_ty(self.param_env.reveal(), data.def_id) { + TreatOpaque::Reveal => { let recursion_limit = self.interner().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( @@ -223,11 +218,21 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let args = data.args.fold_with(self); let generic_ty = self.interner().type_of(data.def_id); let concrete_ty = generic_ty.instantiate(self.interner(), args); + let concrete_ty = + self.interner().fold_regions(concrete_ty, |re, _| match *re { + ty::ReErased => self.selcx.infcx.next_region_var( + RegionVariableOrigin::MiscVariable(self.cause.span), + ), + _ => re, + }); self.depth += 1; let folded_ty = self.fold_ty(concrete_ty); self.depth -= 1; folded_ty } + TreatOpaque::Define | TreatOpaque::Rigid | TreatOpaque::Ambiguous => { + ty.super_fold_with(self) + } } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 8b39c23da56b..bca6745b760c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -9,10 +9,11 @@ use crate::traits::error_reporting::OverflowCause; use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::needs_normalization; use crate::traits::{BoundVarReplacer, PlaceholderReplacer}; -use crate::traits::{ObligationCause, PredicateObligation, Reveal}; +use crate::traits::{ObligationCause, PredicateObligation}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_infer::traits::Normalized; +use rustc_infer::infer::RegionVariableOrigin; +use rustc_infer::traits::{Normalized, TreatOpaque}; use rustc_macros::extension; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; @@ -208,44 +209,49 @@ impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> // Wrap this in a closure so we don't accidentally return from the outer function let res = match kind { - ty::Opaque => { - // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.param_env.reveal() { - Reveal::UserFacing => ty.try_super_fold_with(self)?, - - Reveal::All => { - let args = data.args.try_fold_with(self)?; - let recursion_limit = self.interner().recursion_limit(); - - if !recursion_limit.value_within_limit(self.anon_depth) { - let guar = self - .infcx - .err_ctxt() - .build_overflow_error( - OverflowCause::DeeplyNormalize(data), - self.cause.span, - true, - ) - .delay_as_bug(); - return Ok(Ty::new_error(self.interner(), guar)); - } - - let generic_ty = self.interner().type_of(data.def_id); - let mut concrete_ty = generic_ty.instantiate(self.interner(), args); - self.anon_depth += 1; - if concrete_ty == ty { - concrete_ty = Ty::new_error_with_message( - self.interner(), - DUMMY_SP, - "recursive opaque type", - ); - } - let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty)); - self.anon_depth -= 1; - folded_ty? + ty::Opaque => match self.infcx.treat_opaque_ty(self.param_env.reveal(), data.def_id) { + TreatOpaque::Reveal => { + let args = data.args.try_fold_with(self)?; + let recursion_limit = self.interner().recursion_limit(); + + if !recursion_limit.value_within_limit(self.anon_depth) { + let guar = self + .infcx + .err_ctxt() + .build_overflow_error( + OverflowCause::DeeplyNormalize(data), + self.cause.span, + true, + ) + .delay_as_bug(); + return Ok(Ty::new_error(self.interner(), guar)); } + + let generic_ty = self.interner().type_of(data.def_id); + let concrete_ty = generic_ty.instantiate(self.interner(), args); + let mut concrete_ty = + self.interner().fold_regions(concrete_ty, |re, _| match *re { + ty::ReErased => self.infcx.next_region_var( + RegionVariableOrigin::MiscVariable(self.cause.span), + ), + _ => re, + }); + self.anon_depth += 1; + if concrete_ty == ty { + concrete_ty = Ty::new_error_with_message( + self.interner(), + DUMMY_SP, + "recursive opaque type", + ); + } + let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty)); + self.anon_depth -= 1; + folded_ty? } - } + TreatOpaque::Define | TreatOpaque::Rigid | TreatOpaque::Ambiguous => { + ty.try_super_fold_with(self)? + } + }, ty::Projection | ty::Inherent | ty::Weak => { // See note in `rustc_trait_selection::traits::project` diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index f041c5831fc7..3547d65eb111 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -19,10 +19,31 @@ pub struct Canonical { pub value: V, pub max_universe: UniverseIndex, // FIXME(lcnr, oli-obk): try moving this into the query inputs instead - pub defining_opaque_types: I::DefiningOpaqueTypes, + pub opaque_type_mode: OpaqueTypeMode, pub variables: I::CanonicalVars, } +#[derive(derivative::Derivative)] +#[derivative( + Copy(bound = ""), + Clone(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub enum OpaqueTypeMode { + Define(I::DefiningOpaqueTypes), + Reveal(I::DefiningOpaqueTypes), +} + +impl Default for OpaqueTypeMode { + fn default() -> Self { + OpaqueTypeMode::Define(Default::default()) + } +} + impl Canonical { /// Allows you to map the `value` of a canonical while keeping the /// same set of bound variables. @@ -48,8 +69,8 @@ impl Canonical { /// let b: Canonical)> = a.unchecked_map(|v| (v, ty)); /// ``` pub fn unchecked_map(self, map_op: impl FnOnce(V) -> W) -> Canonical { - let Canonical { defining_opaque_types, max_universe, variables, value } = self; - Canonical { defining_opaque_types, max_universe, variables, value: map_op(value) } + let Canonical { opaque_type_mode, max_universe, variables, value } = self; + Canonical { opaque_type_mode, max_universe, variables, value: map_op(value) } } /// Allows you to map the `value` of a canonical while keeping the same set of @@ -58,8 +79,8 @@ impl Canonical { /// **WARNING:** This function is very easy to mis-use, hence the name! See /// the comment of [Canonical::unchecked_map] for more details. pub fn unchecked_rebind(self, value: W) -> Canonical { - let Canonical { defining_opaque_types, max_universe, variables, value: _ } = self; - Canonical { defining_opaque_types, max_universe, variables, value } + let Canonical { opaque_type_mode, max_universe, variables, value: _ } = self; + Canonical { opaque_type_mode, max_universe, variables, value } } } @@ -67,32 +88,32 @@ impl Eq for Canonical {} impl PartialEq for Canonical { fn eq(&self, other: &Self) -> bool { - let Self { value, max_universe, variables, defining_opaque_types } = self; + let Self { value, max_universe, variables, opaque_type_mode } = self; *value == other.value && *max_universe == other.max_universe && *variables == other.variables - && *defining_opaque_types == other.defining_opaque_types + && *opaque_type_mode == other.opaque_type_mode } } impl fmt::Display for Canonical { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; + let Self { value, max_universe, variables, opaque_type_mode } = self; write!( f, - "Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?}, defining_opaque_types: {defining_opaque_types:?} }}", + "Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?}, opaque_type_mode: {opaque_type_mode:?} }}", ) } } impl fmt::Debug for Canonical { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; + let Self { value, max_universe, variables, opaque_type_mode } = self; f.debug_struct("Canonical") .field("value", &value) .field("max_universe", &max_universe) .field("variables", &variables) - .field("defining_opaque_types", &defining_opaque_types) + .field("opaque_type_mode", &opaque_type_mode) .finish() } } @@ -108,7 +129,7 @@ where value: self.value.try_fold_with(folder)?, max_universe: self.max_universe.try_fold_with(folder)?, variables: self.variables.try_fold_with(folder)?, - defining_opaque_types: self.defining_opaque_types, + opaque_type_mode: self.opaque_type_mode, }) } } @@ -118,10 +139,9 @@ where I::CanonicalVars: TypeVisitable, { fn visit_with>(&self, folder: &mut F) -> F::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; + let Self { value, max_universe, variables, opaque_type_mode: _ } = self; try_visit!(value.visit_with(folder)); try_visit!(max_universe.visit_with(folder)); - try_visit!(defining_opaque_types.visit_with(folder)); variables.visit_with(folder) } } diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs index 9298360f749a..1122f52689e8 100644 --- a/compiler/rustc_type_ir/src/debug.rs +++ b/compiler/rustc_type_ir/src/debug.rs @@ -1,4 +1,4 @@ -use crate::{ConstVid, InferCtxtLike, Interner, TyVid, UniverseIndex}; +use crate::{ConstVid, InferCtxtLike, Interner, OpaqueTypeMode, TyVid, UniverseIndex}; use core::fmt; use std::marker::PhantomData; @@ -44,7 +44,7 @@ impl InferCtxtLike for NoInfcx { None } - fn defining_opaque_types(&self) -> ::DefiningOpaqueTypes { + fn opaque_type_mode(&self) -> OpaqueTypeMode { Default::default() } } diff --git a/compiler/rustc_type_ir/src/infcx.rs b/compiler/rustc_type_ir/src/infcx.rs index a53287c19878..f195c4574aec 100644 --- a/compiler/rustc_type_ir/src/infcx.rs +++ b/compiler/rustc_type_ir/src/infcx.rs @@ -1,4 +1,4 @@ -use crate::{ConstVid, Interner, TyVid, UniverseIndex}; +use crate::{ConstVid, Interner, OpaqueTypeMode, TyVid, UniverseIndex}; pub trait InferCtxtLike { type Interner: Interner; @@ -38,5 +38,5 @@ pub trait InferCtxtLike { /// Resolve `ConstVid` to its inferred type, if it has been equated with a non-infer type. fn probe_ct_var(&self, vid: ConstVid) -> Option<::Const>; - fn defining_opaque_types(&self) -> ::DefiningOpaqueTypes; + fn opaque_type_mode(&self) -> OpaqueTypeMode; } diff --git a/tests/crashes/118987.rs b/tests/crashes/118987.rs deleted file mode 100644 index 4382a7bcb639..000000000000 --- a/tests/crashes/118987.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #118987 -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete - -trait Assoc { - type Output; -} - -default impl Assoc for T { - type Output = bool; -} - -impl Assoc for u8 {} - -trait Foo {} - -impl Foo for ::Output {} -impl Foo for ::Output {} diff --git a/tests/crashes/119272.rs b/tests/crashes/119272.rs deleted file mode 100644 index 02e2cfd09e2f..000000000000 --- a/tests/crashes/119272.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ known-bug: #119272 -#![feature(type_alias_impl_trait)] -mod defining_scope { - use super::*; - pub type Alias = impl Sized; - - pub fn cast(x: Container, T>) -> Container { - x - } -} - -struct Container, U> { - x: >::Assoc, -} - -trait Trait { - type Assoc; -} - -impl Trait for T { - type Assoc = Box; -} -impl Trait for defining_scope::Alias { - type Assoc = usize; -} - -fn main() {} diff --git a/tests/crashes/74299.rs b/tests/crashes/74299.rs deleted file mode 100644 index 0e2ddce1c5b1..000000000000 --- a/tests/crashes/74299.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: #74299 -#![feature(specialization)] - -trait X { - type U; - fn f(&self) -> Self::U { - loop {} - } -} - -impl X for T { - default type U = (); -} - -trait Y { - fn g(&self) {} -} - -impl Y for <() as X>::U {} -impl Y for ::U {} - -fn main() { - ().f().g(); -} diff --git a/tests/ui/associated-types/associated-types-coherence-failure.stderr b/tests/ui/associated-types/associated-types-coherence-failure.stderr index 211613b37149..25c22e5f82ac 100644 --- a/tests/ui/associated-types/associated-types-coherence-failure.stderr +++ b/tests/ui/associated-types/associated-types-coherence-failure.stderr @@ -1,20 +1,20 @@ -error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `Cow<'_, _>` +error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `<_ as ToOwned>::Owned` --> $DIR/associated-types-coherence-failure.rs:21:1 | LL | impl<'a, B: ?Sized> IntoCow<'a, B> for ::Owned where B: ToOwned { | ----------------------------------------------------------------------------- first implementation here ... LL | impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Cow<'_, _>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<_ as ToOwned>::Owned` -error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `&_` +error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `<_ as ToOwned>::Owned` --> $DIR/associated-types-coherence-failure.rs:28:1 | LL | impl<'a, B: ?Sized> IntoCow<'a, B> for ::Owned where B: ToOwned { | ----------------------------------------------------------------------------- first implementation here ... LL | impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<_ as ToOwned>::Owned` error: aborting due to 2 previous errors diff --git a/tests/ui/closures/issue-72408-nested-closures-exponential.rs b/tests/ui/closures/issue-72408-nested-closures-exponential.rs index 682508f92808..6b5abe49a156 100644 --- a/tests/ui/closures/issue-72408-nested-closures-exponential.rs +++ b/tests/ui/closures/issue-72408-nested-closures-exponential.rs @@ -1,5 +1,5 @@ //@ build-pass -//@ ignore-compare-mode-next-solver (hangs) +//@ ignore-test (hangs) // Closures include captured types twice in a type tree. // diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr index dbb22d8937d5..1d28bb46812c 100644 --- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr +++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr @@ -5,6 +5,8 @@ LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} | ---------------------------------------------- first implementation here LL | impl<'a, T> MyTrait<'a> for &'a T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `MyPredicate<'_>` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr index dbb22d8937d5..1d28bb46812c 100644 --- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr +++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr @@ -5,6 +5,8 @@ LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} | ---------------------------------------------- first implementation here LL | impl<'a, T> MyTrait<'a> for &'a T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `MyPredicate<'_>` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr index 21c82eedd5df..c5bb695eb188 100644 --- a/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr +++ b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr @@ -5,6 +5,8 @@ LL | impl Foo for T {} | --------------------------- first implementation here LL | impl Foo for &U {} | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `std::ops::DerefMut` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr index 2ffb6000ec82..99abdf65abd5 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr @@ -12,7 +12,6 @@ LL | impl Trait for Box {} | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` | = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` - = note: downstream crates may implement trait `WhereBound` for type ` as WithAssoc<'a>>::Assoc` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr b/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr index f515c39ea8d1..bf1ffcb5f000 100644 --- a/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr +++ b/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr @@ -5,6 +5,8 @@ LL | impl Bar for T where T: Foo {} | ------------------------------ first implementation here LL | impl Bar for Box {} | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` + | + = note: downstream crates may implement trait `Foo` for type `std::boxed::Box<_>` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr index f24de10f6ac4..97e2e9759c17 100644 --- a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr +++ b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr @@ -6,6 +6,8 @@ LL | impl Bar for T where T: Foo {} ... LL | impl Bar for &T {} | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `Foo` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr index 832c56a45549..8d59cbc3466b 100644 --- a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr +++ b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr @@ -8,6 +8,7 @@ LL | impl FnMarker for fn(&T) {} | = warning: the behavior may change in a future release = note: for more information, see issue #56105 + = note: downstream crates may implement trait `Marker` for type `&_` = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details note: the lint level is defined here --> $DIR/negative-coherence-placeholder-region-constraints-on-unification.rs:4:11 diff --git a/tests/ui/coherence/normalize-for-errors.current.stderr b/tests/ui/coherence/normalize-for-errors.current.stderr index dcbb73bd1ff1..6c56a9177414 100644 --- a/tests/ui/coherence/normalize-for-errors.current.stderr +++ b/tests/ui/coherence/normalize-for-errors.current.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, _)` +error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)` --> $DIR/normalize-for-errors.rs:17:1 | LL | impl MyTrait for (T, S::Item) {} | ------------------------------------------------------ first implementation here LL | LL | impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, _)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)` | = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index 38a02c906d4f..c7af6b4be702 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,12 +1,8 @@ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } -error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` +error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:31:1 | LL | impl Overlap for T { @@ -16,7 +12,7 @@ LL | / impl Overlap fn(&'a (), Assoc<'a, T>)> for T LL | | LL | | where LL | | for<'a> *const T: ToUnit<'a>, - | |_________________________________^ conflicting implementation for `for<'a> fn(&'a (), _)` + | |_________________________________^ conflicting implementation for `for<'a> fn(&'a (), ())` | = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details diff --git a/tests/ui/coherence/occurs-check/opaques.current.stderr b/tests/ui/coherence/occurs-check/opaques.current.stderr new file mode 100644 index 000000000000..96ef7cd4322b --- /dev/null +++ b/tests/ui/coherence/occurs-check/opaques.current.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait<_>` + --> $DIR/opaques.rs:27:1 + | +LL | impl Trait for T { + | ---------------------- first implementation here +... +LL | impl Trait for defining_scope::Alias { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr index f6c5255a1869..cd7c2bf72c75 100644 --- a/tests/ui/coherence/occurs-check/opaques.next.stderr +++ b/tests/ui/coherence/occurs-check/opaques.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait<_>` - --> $DIR/opaques.rs:30:1 + --> $DIR/opaques.rs:27:1 | LL | impl Trait for T { | ---------------------- first implementation here @@ -8,7 +8,7 @@ LL | impl Trait for defining_scope::Alias { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0282]: type annotations needed - --> $DIR/opaques.rs:13:20 + --> $DIR/opaques.rs:10:20 | LL | pub fn cast(x: Container, T>) -> Container { | ^ cannot infer type for associated type `>::Assoc` diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs index 241a247c8413..d7032dd53d97 100644 --- a/tests/ui/coherence/occurs-check/opaques.rs +++ b/tests/ui/coherence/occurs-check/opaques.rs @@ -1,10 +1,7 @@ -//@revisions: old next +//@revisions: current next //@[next] compile-flags: -Znext-solver // A regression test for #105787 - -//@[old] known-bug: #105787 -//@[old] check-pass #![feature(type_alias_impl_trait)] mod defining_scope { use super::*; @@ -28,7 +25,7 @@ impl Trait for T { type Assoc = Box; } impl Trait for defining_scope::Alias { - //[next]~^ ERROR conflicting implementations of trait + //~^ ERROR conflicting implementations of trait type Assoc = usize; } diff --git a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr index 5eef3256b2c3..5de4cf626e48 100644 --- a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr +++ b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr @@ -9,19 +9,6 @@ help: indicate the anonymous lifetime LL | impl ToUnit<'_> for T {} | ++++ -error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied - --> $DIR/skip-reporting-if-references-err.rs:15:29 - | -LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()` - -error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied - --> $DIR/skip-reporting-if-references-err.rs:15:18 - | -LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0726. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/coherence/skip-reporting-if-references-err.rs b/tests/ui/coherence/skip-reporting-if-references-err.rs index f9eaa498232d..4bbcbec9ec64 100644 --- a/tests/ui/coherence/skip-reporting-if-references-err.rs +++ b/tests/ui/coherence/skip-reporting-if-references-err.rs @@ -1,7 +1,4 @@ // Regression test for #121006. -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver trait ToUnit<'a> { type Unit; @@ -13,7 +10,5 @@ impl ToUnit for T {} trait Overlap {} impl Overlap for fn(U) {} impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {} -//[current]~^ ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied -//[current]~| ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/coherence/skip-reporting-if-references-err.stderr b/tests/ui/coherence/skip-reporting-if-references-err.stderr new file mode 100644 index 000000000000..81b080334154 --- /dev/null +++ b/tests/ui/coherence/skip-reporting-if-references-err.stderr @@ -0,0 +1,14 @@ +error[E0726]: implicit elided lifetime not allowed here + --> $DIR/skip-reporting-if-references-err.rs:7:9 + | +LL | impl ToUnit for T {} + | ^^^^^^ expected lifetime parameter + | +help: indicate the anonymous lifetime + | +LL | impl ToUnit<'_> for T {} + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.rs b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs new file mode 100644 index 000000000000..342dd0f9ec65 --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs @@ -0,0 +1,14 @@ +// Added in #124532. While `(): Super` is knowable, `(): Sub` is not. +// +// We therefore elaborate super trait bounds in the implicit negative +// overlap check. + +trait Super {} +trait Sub: Super {} + +trait Overlap {} +impl> Overlap for U {} +impl Overlap for () {} +//~^ ERROR conflicting implementations of trait `Overlap<_>` for type `()` + +fn main() {} diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-1.stderr new file mode 100644 index 000000000000..3a275eda61a7 --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-1.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()` + --> $DIR/super-trait-knowable-1.rs:11:1 + | +LL | impl> Overlap for U {} + | ----------------------------------- first implementation here +LL | impl Overlap for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + | + = note: downstream crates may implement trait `Sub<_>` for type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-2.rs b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs new file mode 100644 index 000000000000..5c919b60bd61 --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs @@ -0,0 +1,29 @@ +// A regression test for pyella-0.1.5 which broke when +// enabling the new solver in coherence. +// +// `Tensor: TensorValue` is knowable while `Tensor: TensorOp` +// may be implemented downstream. We previously didn't check the +// super trait bound in coherence, causing these impls to overlap. +// +// However, we did fail to normalize ` {} +pub trait TensorOp: TensorValue {} + +pub struct Tensor; +impl TensorCompare for Tensor {} +impl TensorCompare for T1 +//~^ ERROR conflicting implementations +where + T1: TensorOp, + T1::Unmasked: Sized, +{} + + +fn main() {} diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-2.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-2.stderr new file mode 100644 index 000000000000..6a9e7e697325 --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-2.stderr @@ -0,0 +1,17 @@ +error[E0119]: conflicting implementations of trait `TensorCompare<_>` for type `Tensor` + --> $DIR/super-trait-knowable-2.rs:21:1 + | +LL | impl TensorCompare for Tensor {} + | ------------------------------------- first implementation here +LL | / impl TensorCompare for T1 +LL | | +LL | | where +LL | | T1: TensorOp, +LL | | T1::Unmasked: Sized, + | |________________________^ conflicting implementation for `Tensor` + | + = note: downstream crates may implement trait `TensorOp<_>` for type `Tensor` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-nested.current.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-nested.current.stderr new file mode 100644 index 000000000000..3cdf782286ae --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-nested.current.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()` + --> $DIR/super-trait-knowable-nested.rs:19:1 + | +LL | impl> Overlap for U {} + | ------------------------------------- first implementation here +LL | impl Overlap for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + | + = note: downstream crates may implement trait `Bound<_>` for type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-nested.next.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-nested.next.stderr new file mode 100644 index 000000000000..3cdf782286ae --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-nested.next.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()` + --> $DIR/super-trait-knowable-nested.rs:19:1 + | +LL | impl> Overlap for U {} + | ------------------------------------- first implementation here +LL | impl Overlap for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + | + = note: downstream crates may implement trait `Bound<_>` for type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-nested.rs b/tests/ui/coherence/super-traits/super-trait-knowable-nested.rs new file mode 100644 index 000000000000..73e7c9a12bea --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-nested.rs @@ -0,0 +1,22 @@ +// Unlike in `super-trait-knowable-1.rs`, the knowable +// super trait bound is in a nested goal and we currently +// only elaborate in the root. This can, and should, be# +// changed in the future. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +trait Super {} +trait Sub: Super {} + +trait Bound {} + +impl, U> Bound for T {} + +trait Overlap {} +impl> Overlap for U {} +impl Overlap for () {} +//~^ ERROR conflicting implementations of trait `Overlap<_>` for type `()` + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs index 51cae20df84d..8530dc12d687 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs @@ -22,6 +22,7 @@ mod v20 { impl v17<512, v0> { pub const fn v21() -> v18 {} //~^ ERROR cannot find type `v18` in this scope + //~| ERROR duplicate definitions with name `v21` } impl v17 { diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 39f022fbee9d..b336f2b3fca5 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -1,5 +1,5 @@ error[E0432]: unresolved import `v20::v13` - --> $DIR/unevaluated-const-ice-119731.rs:37:15 + --> $DIR/unevaluated-const-ice-119731.rs:38:15 | LL | pub use v20::{v13, v17}; | ^^^ @@ -23,7 +23,7 @@ LL | pub const fn v21() -> v18 {} | ^^^ help: a type alias with a similar name exists: `v11` error[E0412]: cannot find type `v18` in this scope - --> $DIR/unevaluated-const-ice-119731.rs:30:31 + --> $DIR/unevaluated-const-ice-119731.rs:31:31 | LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here @@ -32,7 +32,7 @@ LL | pub const fn v21() -> v18 { | ^^^ help: a type alias with a similar name exists: `v11` error[E0422]: cannot find struct, variant or union type `v18` in this scope - --> $DIR/unevaluated-const-ice-119731.rs:32:13 + --> $DIR/unevaluated-const-ice-119731.rs:33:13 | LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here @@ -73,20 +73,29 @@ LL + #![feature(adt_const_params)] | error: maximum number of nodes exceeded in constant v20::v17::::{constant#1} - --> $DIR/unevaluated-const-ice-119731.rs:27:37 + --> $DIR/unevaluated-const-ice-119731.rs:28:37 | LL | impl v17 { | ^^ error: maximum number of nodes exceeded in constant v20::v17::::{constant#1} - --> $DIR/unevaluated-const-ice-119731.rs:27:37 + --> $DIR/unevaluated-const-ice-119731.rs:28:37 | LL | impl v17 { | ^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 9 previous errors; 2 warnings emitted +error[E0592]: duplicate definitions with name `v21` + --> $DIR/unevaluated-const-ice-119731.rs:23:9 + | +LL | pub const fn v21() -> v18 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `v21` +... +LL | pub const fn v21() -> v18 { + | ------------------------- other definition for `v21` + +error: aborting due to 10 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0412, E0422, E0425, E0432. +Some errors have detailed explanations: E0412, E0422, E0425, E0432, E0592. For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs index dd0b1e8c9f71..81ac9979bd8c 100644 --- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs +++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs @@ -10,6 +10,5 @@ trait Trait {} impl Trait for A {} impl Trait for A {} -//~^ ERROR conflicting implementations of trait `Trait` for type `A<_>` pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr index 80ac96d48700..e29c49ff0422 100644 --- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr @@ -4,16 +4,6 @@ error[E0423]: expected value, found builtin type `u8` LL | struct A; | ^^ not a value -error[E0119]: conflicting implementations of trait `Trait` for type `A<_>` - --> $DIR/unknown-alias-defkind-anonconst-ice-116710.rs:12:1 - | -LL | impl Trait for A {} - | --------------------------------- first implementation here -LL | -LL | impl Trait for A {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A<_>` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0119, E0423. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/dyn-star/param-env-region-infer.rs b/tests/ui/dyn-star/param-env-region-infer.rs index c53861065c7d..c7344b77b341 100644 --- a/tests/ui/dyn-star/param-env-region-infer.rs +++ b/tests/ui/dyn-star/param-env-region-infer.rs @@ -1,7 +1,7 @@ //@ revisions: current //@ incremental -// FIXME(-Znext-solver): THis currently results in unstable query results: +// FIXME(-Znext-solver): This currently results in unstable query results: // `normalizes-to(opaque, opaque)` changes from `Maybe(Ambiguous)` to `Maybe(Overflow)` // once the hidden type of the opaque is already defined to be itself. diff --git a/tests/ui/error-codes/e0119/issue-23563.stderr b/tests/ui/error-codes/e0119/issue-23563.stderr index 86737742f749..a308769af131 100644 --- a/tests/ui/error-codes/e0119/issue-23563.stderr +++ b/tests/ui/error-codes/e0119/issue-23563.stderr @@ -1,4 +1,4 @@ -error[E0119]: conflicting implementations of trait `LolFrom<&[_]>` for type `LocalType<_>` +error[E0119]: conflicting implementations of trait `LolFrom<&[u8]>` for type `LocalType` --> $DIR/issue-23563.rs:13:1 | LL | impl<'a, T> LolFrom<&'a [T]> for LocalType { diff --git a/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr b/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr index ba076568088b..b32f54aaecfa 100644 --- a/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr +++ b/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr @@ -6,6 +6,8 @@ LL | impl Foo for T { } LL | LL | impl Foo for &T { } | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `std::ops::DerefMut` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs index 8df24702811d..698824509613 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.rs +++ b/tests/ui/higher-ranked/structually-relate-aliases.rs @@ -11,7 +11,6 @@ type Assoc<'a, T> = >::Unit; impl Overlap for T {} impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} -//~^ ERROR 13:17: 13:49: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied [E0277] -//~| ERROR 13:36: 13:48: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied [E0277] +//~^ ERROR conflicting implementations of trait `Overlap fn(&'a (), _)>` fn main() {} diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index 59fab52b221e..19dc14e396e7 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,27 +1,18 @@ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } -WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } -error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied - --> $DIR/structually-relate-aliases.rs:13:36 - | -LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` - | -help: consider restricting type parameter `T` - | -LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ++++++++++++++++++++ - -error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied - --> $DIR/structually-relate-aliases.rs:13:17 +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } +error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` + --> $DIR/structually-relate-aliases.rs:13:1 | +LL | impl Overlap for T {} + | ------------------------ first implementation here +LL | LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` - | -help: consider restricting type parameter `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)` | -LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ++++++++++++++++++++ + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/auto-trait-coherence.old.stderr b/tests/ui/impl-trait/auto-trait-coherence.old.stderr index 3f979d1a50b3..cd91bfcb48d7 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.old.stderr +++ b/tests/ui/impl-trait/auto-trait-coherence.old.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` --> $DIR/auto-trait-coherence.rs:24:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/auto-trait-coherence.rs b/tests/ui/impl-trait/auto-trait-coherence.rs index e3036fd0fe2c..0d7fef21cc92 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.rs +++ b/tests/ui/impl-trait/auto-trait-coherence.rs @@ -1,6 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - // Tests that type alias impls traits do not leak auto-traits for // the purposes of coherence checking #![feature(type_alias_impl_trait)] @@ -22,8 +19,7 @@ impl AnotherTrait for T {} // (We treat opaque types as "foreign types" that could grow more impls // in the future.) impl AnotherTrait for D { - //[old]~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` - //[next]~^^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>` } fn main() {} diff --git a/tests/ui/impl-trait/auto-trait-coherence.stderr b/tests/ui/impl-trait/auto-trait-coherence.stderr new file mode 100644 index 000000000000..e0f4c857717c --- /dev/null +++ b/tests/ui/impl-trait/auto-trait-coherence.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` + --> $DIR/auto-trait-coherence.rs:21:1 + | +LL | impl AnotherTrait for T {} + | -------------------------------- first implementation here +... +LL | impl AnotherTrait for D { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs index df47208bf367..e8c1fcdd2133 100644 --- a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs @@ -5,7 +5,7 @@ type T = impl Sized; struct Foo; impl Into for Foo { -//~^ ERROR conflicting implementations of trait `Into` for type `Foo` +//~^ ERROR conflicting implementations of trait `Into<_>` for type `Foo` fn into(self) -> T { Foo } diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr b/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr index faaad2769271..618bef1f2714 100644 --- a/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr @@ -1,4 +1,4 @@ -error[E0119]: conflicting implementations of trait `Into` for type `Foo` +error[E0119]: conflicting implementations of trait `Into<_>` for type `Foo` --> $DIR/coherence-treats-tait-ambig.rs:7:1 | LL | impl Into for Foo { 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 2dc19b9ad688..e9706b656f22 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 f7546a05bfdb..df03150e29ac 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 e3488140dcc7..33c5ed5fdebe 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/impl-trait/negative-reasoning.rs b/tests/ui/impl-trait/negative-reasoning.rs index 70e24a3a9d02..0474dc0beda6 100644 --- a/tests/ui/impl-trait/negative-reasoning.rs +++ b/tests/ui/impl-trait/negative-reasoning.rs @@ -17,7 +17,7 @@ impl AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Debug` impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>` } fn main() {} diff --git a/tests/ui/impl-trait/negative-reasoning.stderr b/tests/ui/impl-trait/negative-reasoning.stderr index 3cb4be16fc3f..631784c817b8 100644 --- a/tests/ui/impl-trait/negative-reasoning.stderr +++ b/tests/ui/impl-trait/negative-reasoning.stderr @@ -1,13 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` --> $DIR/negative-reasoning.rs:19:1 | LL | impl AnotherTrait for T {} | ------------------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` - | - = note: upstream crates may add a new impl of trait `std::marker::FnPtr` for type `OpaqueType` in future versions + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs index 9b18aceb4a73..e4e152a6a776 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.rs +++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs @@ -35,6 +35,7 @@ fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` +//~| ERROR mismatched types // This should resolve. fn one_hrtb_mention_fn_trait_param<'b>() -> impl for<'a> Foo<'a, Assoc = impl Qux<'b>> {} diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index 2fa036f35fab..85222bb04f35 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:57:77 + --> $DIR/nested-rpit-hrtb.rs:58:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:65:82 + --> $DIR/nested-rpit-hrtb.rs:66:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -86,8 +86,17 @@ note: lifetime declared here LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ +error[E0308]: mismatched types + --> $DIR/nested-rpit-hrtb.rs:36:35 + | +LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected reference `&'a ()` + found reference `&()` + error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:46:79 + --> $DIR/nested-rpit-hrtb.rs:47:79 | LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} | ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()` @@ -96,7 +105,7 @@ LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:50:93 + --> $DIR/nested-rpit-hrtb.rs:51:93 | LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -105,7 +114,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:61:64 + --> $DIR/nested-rpit-hrtb.rs:62:64 | LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()` @@ -114,7 +123,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:65:86 + --> $DIR/nested-rpit-hrtb.rs:66:86 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -122,7 +131,7 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si = note: `()` must implement `Bar<'a>` = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors -Some errors have detailed explanations: E0261, E0277, E0657. +Some errors have detailed explanations: E0261, E0277, E0308, E0657. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-unused-tps.rs b/tests/ui/impl-unused-tps.rs index 3eb9daedf76d..a5836db3c8e6 100644 --- a/tests/ui/impl-unused-tps.rs +++ b/tests/ui/impl-unused-tps.rs @@ -1,34 +1,35 @@ -//~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized - trait Foo { - fn get(&self, A: &A) { } + fn get(&self, A: &A) {} } trait Bar { type Out; } -impl Foo for [isize;0] { +impl Foo for [isize; 0] { // OK, T is used in `Foo`. } -impl Foo for [isize;1] { +impl Foo for [isize; 1] { //~^ ERROR the type parameter `U` is not constrained } -impl Foo for [isize;2] where T : Bar { +impl Foo for [isize; 2] +where + T: Bar, +{ // OK, `U` is now constrained by the output type parameter. } -impl,U> Foo for [isize;3] { +impl, U> Foo for [isize; 3] { // OK, same as above but written differently. } -impl Foo for U { +impl Foo for U { //~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]` } -impl Bar for T { +impl Bar for T { //~^ ERROR the type parameter `U` is not constrained type Out = U; @@ -36,28 +37,33 @@ impl Bar for T { // Using `U` in an associated type within the impl is not good enough! } -impl Bar for T - where T : Bar +impl Bar for T +where + T: Bar, { - //~^^^ ERROR the type parameter `U` is not constrained - + //~^^^^ ERROR the type parameter `U` is not constrained by the impl trait, self type, or predicates + //~| ERROR conflicting implementations of trait `Bar` // This crafty self-referential attempt is still no good. } -impl Foo for T - where (T,U): Bar +impl Foo for T +where + (T, U): Bar, { - //~^^^ ERROR the type parameter `U` is not constrained - //~| ERROR the type parameter `V` is not constrained + //~^^^^ ERROR the type parameter `U` is not constrained + //~| ERROR the type parameter `V` is not constrained + //~| ERROR conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]` // Here, `V` is bound by an output type parameter, but the inputs // are not themselves constrained. } -impl Foo<(T,U)> for T - where (T,U): Bar +impl Foo<(T, U)> for T +where + (T, U): Bar, { + //~^^^^ ERROR conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]` // As above, but both T and U ARE constrained. } -fn main() { } +fn main() {} diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/impl-unused-tps.stderr index af427cb5f3e3..da4589dee827 100644 --- a/tests/ui/impl-unused-tps.stderr +++ b/tests/ui/impl-unused-tps.stderr @@ -1,56 +1,76 @@ error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]` - --> $DIR/impl-unused-tps.rs:27:1 + --> $DIR/impl-unused-tps.rs:28:1 | -LL | impl Foo for [isize;0] { - | ---------------------------- first implementation here +LL | impl Foo for [isize; 0] { + | ----------------------------- first implementation here ... -LL | impl Foo for U { - | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` +LL | impl Foo for U { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` -error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized` +error[E0119]: conflicting implementations of trait `Bar` + --> $DIR/impl-unused-tps.rs:40:1 | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`) -note: required for `([isize; 0], _)` to implement `Bar` - --> $DIR/impl-unused-tps.rs:31:11 +LL | impl Bar for T { + | -------------------- first implementation here +... +LL | / impl Bar for T +LL | | where +LL | | T: Bar, + | |____________________^ conflicting implementation + +error[E0119]: conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]` + --> $DIR/impl-unused-tps.rs:49:1 + | +LL | impl Foo for [isize; 0] { + | ----------------------------- first implementation here +... +LL | / impl Foo for T +LL | | where +LL | | (T, U): Bar, + | |_________________________^ conflicting implementation for `[isize; 0]` + +error[E0119]: conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]` + --> $DIR/impl-unused-tps.rs:61:1 | -LL | impl Bar for T { - | - ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: 126 redundant requirements hidden - = note: required for `([isize; 0], _)` to implement `Bar` +LL | impl Foo for [isize; 0] { + | ----------------------------- first implementation here +... +LL | / impl Foo<(T, U)> for T +LL | | where +LL | | (T, U): Bar, + | |_________________________^ conflicting implementation for `[isize; 0]` error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:15:8 + --> $DIR/impl-unused-tps.rs:13:9 | -LL | impl Foo for [isize;1] { - | ^ unconstrained type parameter +LL | impl Foo for [isize; 1] { + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:31:8 + --> $DIR/impl-unused-tps.rs:32:9 | -LL | impl Bar for T { - | ^ unconstrained type parameter +LL | impl Bar for T { + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:39:8 + --> $DIR/impl-unused-tps.rs:40:9 | -LL | impl Bar for T - | ^ unconstrained type parameter +LL | impl Bar for T + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:47:8 + --> $DIR/impl-unused-tps.rs:49:9 | -LL | impl Foo for T - | ^ unconstrained type parameter +LL | impl Foo for T + | ^ unconstrained type parameter error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:47:10 + --> $DIR/impl-unused-tps.rs:49:12 | -LL | impl Foo for T - | ^ unconstrained type parameter +LL | impl Foo for T + | ^ unconstrained type parameter -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0119, E0207, E0275. +Some errors have detailed explanations: E0119, E0207. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/crashes/118987-2.rs b/tests/ui/specialization/defaultimpl/coherence-ice-issue-118987.rs similarity index 69% rename from tests/crashes/118987-2.rs rename to tests/ui/specialization/defaultimpl/coherence-ice-issue-118987.rs index 4382a7bcb639..2f876db81ff3 100644 --- a/tests/crashes/118987-2.rs +++ b/tests/ui/specialization/defaultimpl/coherence-ice-issue-118987.rs @@ -1,4 +1,5 @@ -//@ known-bug: #118987 +//@ check-pass +// Regression test for #118987 which previously caused an ICE. #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Assoc { @@ -14,4 +15,6 @@ impl Assoc for u8 {} trait Foo {} impl Foo for ::Output {} -impl Foo for ::Output {} +impl Foo for u16 {} + +fn main() {} diff --git a/tests/ui/specialization/defaultimpl/coherence-ice-issue-118987.stderr b/tests/ui/specialization/defaultimpl/coherence-ice-issue-118987.stderr new file mode 100644 index 000000000000..3b587dd7029e --- /dev/null +++ b/tests/ui/specialization/defaultimpl/coherence-ice-issue-118987.stderr @@ -0,0 +1,12 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/coherence-ice-issue-118987.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.rs b/tests/ui/specialization/defaultimpl/specialization-no-default.rs index 661724eef8a4..ba17b68039d3 100644 --- a/tests/ui/specialization/defaultimpl/specialization-no-default.rs +++ b/tests/ui/specialization/defaultimpl/specialization-no-default.rs @@ -71,7 +71,8 @@ impl Redundant for T { } default impl Redundant for i32 { - fn redundant(&self) {} //~ ERROR E0520 + // FIXME(specialization): figure out why this does not error. + fn redundant(&self) {} } fn main() {} diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr index f9e62a99baee..87169d4049c9 100644 --- a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr @@ -52,17 +52,6 @@ LL | fn baz(&self) {} | = note: to specialize, `baz` in the parent `impl` must be marked `default` -error[E0520]: `redundant` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/specialization-no-default.rs:74:5 - | -LL | impl Redundant for T { - | ------------------------------ parent `impl` is here -... -LL | fn redundant(&self) {} - | ^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` - | - = note: to specialize, `redundant` in the parent `impl` must be marked `default` - -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0520`. diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr new file mode 100644 index 000000000000..c4dd57c243cd --- /dev/null +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Overlap` for type `u32` + --> $DIR/specialization-default-items-drop-coherence.rs:28:1 + | +LL | impl Overlap for u32 { + | -------------------- first implementation here +... +LL | impl Overlap for ::Id { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr index 78d77a78e0ee..e52b19b645a8 100644 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Overlap` for type `u32` - --> $DIR/specialization-default-items-drop-coherence.rs:29:1 + --> $DIR/specialization-default-items-drop-coherence.rs:28:1 | LL | impl Overlap for u32 { | -------------------- first implementation here @@ -8,7 +8,7 @@ LL | impl Overlap for ::Id { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` error[E0282]: type annotations needed - --> $DIR/specialization-default-items-drop-coherence.rs:18:23 + --> $DIR/specialization-default-items-drop-coherence.rs:17:23 | LL | default type Id = T; | ^ cannot infer type for associated type `::Id` diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs index fad041f2ee10..18d6f2054fc0 100644 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.rs +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs @@ -1,11 +1,10 @@ -//@ revisions: classic coherence next +//@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[coherence] compile-flags: -Znext-solver=coherence -//@[classic] check-pass -//@[classic] known-bug: #105782 // Should fail. Default items completely drop candidates instead of ambiguity, // which is unsound during coherence, since coherence requires completeness. +// +// A regression test for #105782. #![feature(specialization)] #![allow(incomplete_features)] @@ -27,8 +26,7 @@ impl Overlap for u32 { } impl Overlap for ::Id { - //[coherence]~^ ERROR conflicting implementations of trait `Overlap` for type `u32` - //[next]~^^ ERROR conflicting implementations of trait `Overlap` for type `u32` + //~^ ERROR conflicting implementations of trait `Overlap` for type `u32` type Assoc = Box; } diff --git a/tests/ui/specialization/specialization-overlap-projection.current.stderr b/tests/ui/specialization/specialization-overlap-projection.current.stderr index a69826fa96b0..cd343354bf77 100644 --- a/tests/ui/specialization/specialization-overlap-projection.current.stderr +++ b/tests/ui/specialization/specialization-overlap-projection.current.stderr @@ -1,5 +1,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes +<<<<<<< HEAD:tests/ui/specialization/specialization-overlap-projection.current.stderr --> $DIR/specialization-overlap-projection.rs:10:12 +======= + --> $DIR/specialization-overlap-projection.rs:9:12 +>>>>>>> acb48a636d9 (stabilize `-Znext-solver=coherence`):tests/ui/specialization/specialization-overlap-projection.stderr | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -8,5 +12,23 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:24:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:25:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +LL | impl Foo for ::Output {} +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error: aborting due to 2 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs index 78e75f623c4b..22e91041a7c7 100644 --- a/tests/ui/specialization/specialization-overlap-projection.rs +++ b/tests/ui/specialization/specialization-overlap-projection.rs @@ -1,12 +1,10 @@ -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@[current] check-pass +// FIXME(specialization): default associated types in the new solver +// cause an ambiguous candidate even if there is a leaf impl which +// always applies. // Test that impls on projected self types can resolve overlap, even when the // projections involve specialization, so long as the associated type is // provided by the most specialized impl. - #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Assoc { @@ -15,19 +13,16 @@ trait Assoc { impl Assoc for T { default type Output = bool; - //[next]~^ ERROR type annotations needed } impl Assoc for u8 { type Output = u8; } -//[next]~^ ERROR type annotations needed impl Assoc for u16 { type Output = u16; } -//[next]~^ ERROR type annotations needed trait Foo {} impl Foo for u32 {} impl Foo for ::Output {} -//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32` +//~^ ERROR conflicting implementations of trait `Foo` for type `u32` impl Foo for ::Output {} -//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32` +//~^ ERROR conflicting implementations of trait `Foo` for type `u32` fn main() {} diff --git a/tests/ui/specialization/specialization-overlap-projection.stderr b/tests/ui/specialization/specialization-overlap-projection.stderr new file mode 100644 index 000000000000..584e38554e28 --- /dev/null +++ b/tests/ui/specialization/specialization-overlap-projection.stderr @@ -0,0 +1,30 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-overlap-projection.rs:8:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:23:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:25:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +... +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/alias/issue-83613.rs b/tests/ui/traits/alias/issue-83613.rs index 2462e703a716..6f0012bf0896 100644 --- a/tests/ui/traits/alias/issue-83613.rs +++ b/tests/ui/traits/alias/issue-83613.rs @@ -8,5 +8,5 @@ fn mk_opaque() -> OpaqueType { trait AnotherTrait {} impl AnotherTrait for T {} impl AnotherTrait for OpaqueType {} -//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +//~^ ERROR conflicting implementations of trait `AnotherTrait` fn main() {} diff --git a/tests/ui/traits/alias/issue-83613.stderr b/tests/ui/traits/alias/issue-83613.stderr index 847fda417766..47181c3f33ed 100644 --- a/tests/ui/traits/alias/issue-83613.stderr +++ b/tests/ui/traits/alias/issue-83613.stderr @@ -1,10 +1,10 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +error[E0119]: conflicting implementations of trait `AnotherTrait` --> $DIR/issue-83613.rs:10:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here LL | impl AnotherTrait for OpaqueType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs index 89b2da4452a5..f7576cafaa2c 100644 --- a/tests/ui/traits/issue-105231.rs +++ b/tests/ui/traits/issue-105231.rs @@ -1,4 +1,3 @@ -//~ ERROR overflow evaluating the requirement `A>>>>>>: Send` struct A(B); //~^ ERROR recursive types `A` and `B` have infinite size //~| ERROR `T` is never used @@ -7,5 +6,5 @@ struct B(A>); trait Foo {} impl Foo for T where T: Send {} impl Foo for B {} - +//~^ ERROR conflicting implementations of trait `Foo` for type `B` fn main() {} diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr index 6467a438375c..edfda4e5fd9f 100644 --- a/tests/ui/traits/issue-105231.stderr +++ b/tests/ui/traits/issue-105231.stderr @@ -1,5 +1,5 @@ error[E0072]: recursive types `A` and `B` have infinite size - --> $DIR/issue-105231.rs:2:1 + --> $DIR/issue-105231.rs:1:1 | LL | struct A(B); | ^^^^^^^^^^^ ---- recursive without indirection @@ -16,7 +16,7 @@ LL ~ struct B(Box>>); | error[E0392]: type parameter `T` is never used - --> $DIR/issue-105231.rs:2:10 + --> $DIR/issue-105231.rs:1:10 | LL | struct A(B); | ^ unused type parameter @@ -25,7 +25,7 @@ LL | struct A(B); = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0392]: type parameter `T` is never used - --> $DIR/issue-105231.rs:5:10 + --> $DIR/issue-105231.rs:4:10 | LL | struct B(A>); | ^ unused type parameter @@ -33,16 +33,18 @@ LL | struct B(A>); = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error[E0275]: overflow evaluating the requirement `A>>>>>>: Send` +error[E0119]: conflicting implementations of trait `Foo` for type `B` + --> $DIR/issue-105231.rs:8:1 | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`) -note: required because it appears within the type `B>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-105231.rs:5:8 +LL | impl Foo for T where T: Send {} + | ------------------------------- first implementation here +LL | impl Foo for B {} + | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `B` | -LL | struct B(A>); - | ^ + = note: overflow evaluating the requirement `B: Send` + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`) error: aborting due to 4 previous errors -Some errors have detailed explanations: E0072, E0275, E0392. +Some errors have detailed explanations: E0072, E0119, E0392. For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs index d37943b929a1..43443be88df7 100644 --- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs +++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs @@ -1,4 +1,3 @@ -//~ ERROR overflow // A regression test for #111729 checking that we correctly // track recursion depth for obligations returned by confirmation. use std::panic::RefUnwindSafe; @@ -18,6 +17,7 @@ impl Database for T { type Storage = SalsaStorage; } impl Database for RootDatabase { + //~^ ERROR conflicting implementations of trait `Database` for type `RootDatabase` type Storage = SalsaStorage; } diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr index 2ab150fc0f62..1da7671b4519 100644 --- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr +++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr @@ -1,24 +1,12 @@ -error[E0275]: overflow evaluating the requirement `Runtime: RefUnwindSafe` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_via_builtin_auto_trait_impl`) -note: required because it appears within the type `RootDatabase` - --> $DIR/cycle-via-builtin-auto-trait-impl.rs:13:8 - | -LL | struct RootDatabase { - | ^^^^^^^^^^^^ -note: required for `RootDatabase` to implement `Database` - --> $DIR/cycle-via-builtin-auto-trait-impl.rs:17:24 +error[E0119]: conflicting implementations of trait `Database` for type `RootDatabase` + --> $DIR/cycle-via-builtin-auto-trait-impl.rs:19:1 | LL | impl Database for T { - | ------------- ^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required because it appears within the type `Runtime` - --> $DIR/cycle-via-builtin-auto-trait-impl.rs:24:8 - | -LL | struct Runtime { - | ^^^^^^^ + | ------------------------------------- first implementation here +... +LL | impl Database for RootDatabase { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `RootDatabase` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0119`. 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 3c2bc0b91906..000000000000 --- 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 f344474054a2..000000000000 --- 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 c54a1c42badd..a259abb28ae3 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 000000000000..cb1501a94a2a --- /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() {} diff --git a/tests/crashes/124207.rs b/tests/ui/transmutability/opaque-type-layout-ice-issue-124207.rs similarity index 52% rename from tests/crashes/124207.rs rename to tests/ui/transmutability/opaque-type-layout-ice-issue-124207.rs index a4e1c5518900..79ad570c3d35 100644 --- a/tests/crashes/124207.rs +++ b/tests/ui/transmutability/opaque-type-layout-ice-issue-124207.rs @@ -1,9 +1,14 @@ -//@ known-bug: #124207 +// A regression test for #124207. +// +// This previous caused an ICE in the old solver. #![feature(transmutability)] #![feature(type_alias_impl_trait)] trait OpaqueTrait {} type OpaqueType = impl OpaqueTrait; +//~^ ERROR unconstrained opaque type trait AnotherTrait {} impl> AnotherTrait for T {} +//~^ ERROR type provided when a constant was expected impl AnotherTrait for OpaqueType {} +//~^ ERROR conflicting implementations of trait `AnotherTrait` pub fn main() {} diff --git a/tests/ui/transmutability/opaque-type-layout-ice-issue-124207.stderr b/tests/ui/transmutability/opaque-type-layout-ice-issue-124207.stderr new file mode 100644 index 000000000000..51b6c3e9fcc6 --- /dev/null +++ b/tests/ui/transmutability/opaque-type-layout-ice-issue-124207.stderr @@ -0,0 +1,27 @@ +error: unconstrained opaque type + --> $DIR/opaque-type-layout-ice-issue-124207.rs:7:19 + | +LL | type OpaqueType = impl OpaqueTrait; + | ^^^^^^^^^^^^^^^^ + | + = note: `OpaqueType` must be used in combination with a concrete type within the same module + +error[E0747]: type provided when a constant was expected + --> $DIR/opaque-type-layout-ice-issue-124207.rs:10:45 + | +LL | impl> AnotherTrait for T {} + | ^^ + +error[E0119]: conflicting implementations of trait `AnotherTrait` + --> $DIR/opaque-type-layout-ice-issue-124207.rs:12:1 + | +LL | impl> AnotherTrait for T {} + | ------------------------------------------------------------------- first implementation here +LL | +LL | impl AnotherTrait for OpaqueType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0119, E0747. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr index e35913be899f..3dddfb6a9a01 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr @@ -15,8 +15,6 @@ LL | impl Bop for Bar<()> {} ... LL | impl Bop for Barr {} | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` - | - = note: upstream crates may add a new impl of trait `std::marker::FnPtr` for type `Barr` in future versions error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` --> $DIR/impl_trait_for_same_tait.rs:30:1 @@ -26,6 +24,8 @@ LL | impl Bop for Bar<()> {} ... LL | impl Bop for i32 {} | ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` + | + = note: upstream crates may add a new impl of trait `std::marker::FnPtr` for type `i32` in future versions error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/issue-104817.rs b/tests/ui/type-alias-impl-trait/issue-104817.rs index 4679d025fce0..491463216145 100644 --- a/tests/ui/type-alias-impl-trait/issue-104817.rs +++ b/tests/ui/type-alias-impl-trait/issue-104817.rs @@ -14,6 +14,6 @@ fn mk_opaque() -> OpaqueType { trait AnotherTrait {} impl AnotherTrait for T {} impl AnotherTrait for OpaqueType {} -//[stock]~^ conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +//[stock]~^ conflicting implementations of trait `AnotherTrait` fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr index 41c5206d9e88..df5a6c320a8a 100644 --- a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr +++ b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr @@ -1,10 +1,10 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +error[E0119]: conflicting implementations of trait `AnotherTrait` --> $DIR/issue-104817.rs:16:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here LL | impl AnotherTrait for OpaqueType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error