diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index db9df8a84f4e5..4a85859c2f05c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -119,7 +119,7 @@ pub fn provide(providers: &mut Providers) { fn mir_borrowck( tcx: TyCtxt<'_>, def: LocalDefId, -) -> Result<&DefinitionSiteHiddenTypes<'_>, ErrorGuaranteed> { +) -> Result<&FxIndexMap>, ErrorGuaranteed> { assert!(!tcx.is_typeck_child(def.to_def_id())); let (input_body, _) = tcx.mir_promoted(def); debug!("run query mir_borrowck: {}", tcx.def_path_str(def)); @@ -130,7 +130,7 @@ fn mir_borrowck( Err(guar) } else if input_body.should_skip() { debug!("Skipping borrowck because of injected body"); - let opaque_types = DefinitionSiteHiddenTypes(Default::default()); + let opaque_types = Default::default(); Ok(tcx.arena.alloc(opaque_types)) } else { let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 67d1d44b1e1f8..0c4a82f3d2f36 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -8,11 +8,11 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, OpaqueTypeStorageEntries}; use rustc_infer::traits::ObligationCause; use rustc_macros::extension; -use rustc_middle::mir::{Body, ConstraintCategory, DefinitionSiteHiddenTypes}; +use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::ty::{ - self, DefiningScopeKind, EarlyBinder, FallibleTypeFolder, GenericArg, GenericArgsRef, - OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable, - TypeSuperFoldable, TypeVisitableExt, fold_regions, + self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg, + GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt, + TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions, }; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::Span; @@ -48,7 +48,7 @@ pub(crate) enum DeferredOpaqueTypeError<'tcx> { /// The opaque type. opaque_type_key: OpaqueTypeKey<'tcx>, /// The hidden type containing the member region. - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, /// The unexpected region. member_region: Region<'tcx>, }, @@ -67,7 +67,7 @@ pub(crate) fn clone_and_resolve_opaque_types<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, universal_region_relations: &Frozen>, constraints: &mut MirTypeckRegionConstraints<'tcx>, -) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>) { +) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>) { let opaque_types = infcx.clone_opaque_types(); let opaque_types_storage_num_entries = infcx.inner.borrow_mut().opaque_types().num_entries(); let opaque_types = opaque_types @@ -131,27 +131,26 @@ fn nll_var_to_universal_region<'tcx>( /// and errors if we end up with distinct hidden types. fn add_hidden_type<'tcx>( tcx: TyCtxt<'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, + hidden_types: &mut FxIndexMap>, def_id: LocalDefId, - hidden_ty: OpaqueHiddenType<'tcx>, + hidden_ty: ty::DefinitionSiteHiddenType<'tcx>, ) { // Sometimes two opaque types are the same only after we remap the generic parameters // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to // `(X, Y)` and `OpaqueType` mapped to `(Y, X)`, and those are the same, but we // only know that once we convert the generic parameters to those of the opaque type. - if let Some(prev) = hidden_types.0.get_mut(&def_id) { - if prev.ty != hidden_ty.ty { - let guar = hidden_ty.ty.error_reported().err().unwrap_or_else(|| { - let (Ok(e) | Err(e)) = prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit()); - e - }); - prev.ty = Ty::new_error(tcx, guar); + if let Some(prev) = hidden_types.get_mut(&def_id) { + if prev.ty == hidden_ty.ty { + // Pick a better span if there is one. + // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. + prev.span = prev.span.substitute_dummy(hidden_ty.span); + } else { + let (Ok(guar) | Err(guar)) = + prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit()); + *prev = ty::DefinitionSiteHiddenType::new_error(tcx, guar); } - // Pick a better span if there is one. - // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. - prev.span = prev.span.substitute_dummy(hidden_ty.span); } else { - hidden_types.0.insert(def_id, hidden_ty); + hidden_types.insert(def_id, hidden_ty); } } @@ -162,7 +161,7 @@ struct DefiningUse<'tcx> { /// to interact with code outside of `rustc_borrowck`. opaque_type_key: OpaqueTypeKey<'tcx>, arg_regions: Vec, - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, } /// This computes the actual hidden types of the opaque types and maps them to their @@ -181,8 +180,8 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( universal_region_relations: &Frozen>, constraints: &MirTypeckRegionConstraints<'tcx>, location_map: Rc, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, - opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], + hidden_types: &mut FxIndexMap>, + opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], ) -> Vec> { let mut errors = Vec::new(); // When computing the hidden type we need to track member constraints. @@ -216,8 +215,8 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( #[instrument(level = "debug", skip_all, ret)] fn collect_defining_uses<'tcx>( rcx: &mut RegionCtxt<'_, 'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, - opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], + hidden_types: &mut FxIndexMap>, + opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], errors: &mut Vec>, ) -> Vec> { let infcx = rcx.infcx; @@ -240,7 +239,7 @@ fn collect_defining_uses<'tcx>( infcx.tcx, hidden_types, opaque_type_key.def_id, - OpaqueHiddenType::new_error(infcx.tcx, guar), + DefinitionSiteHiddenType::new_error(infcx.tcx, guar), ), _ => debug!(?non_nll_opaque_type_key, ?err, "ignoring non-defining use"), } @@ -276,7 +275,7 @@ fn collect_defining_uses<'tcx>( #[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))] fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( rcx: &RegionCtxt<'_, 'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, + hidden_types: &mut FxIndexMap>, defining_uses: &[DefiningUse<'tcx>], errors: &mut Vec>, ) { @@ -303,21 +302,20 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( hidden_type.span, "opaque type with non-universal region args", ); - ty::OpaqueHiddenType::new_error(tcx, guar) + ty::ProvisionalHiddenType::new_error(tcx, guar) } }; // Now that we mapped the member regions to their final value, // map the arguments of the opaque type key back to the parameters // of the opaque type definition. - let ty = infcx + let hidden_type = infcx .infer_opaque_definition_from_instantiation(opaque_type_key, hidden_type) .unwrap_or_else(|_| { - Ty::new_error_with_message( - rcx.infcx.tcx, - hidden_type.span, - "deferred invalid opaque type args", - ) + let guar = tcx + .dcx() + .span_delayed_bug(hidden_type.span, "deferred invalid opaque type args"); + DefinitionSiteHiddenType::new_error(tcx, guar) }); // Sometimes, when the hidden type is an inference variable, it can happen that @@ -325,7 +323,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( // usage of the opaque type and we can ignore it. This check is mirrored in typeck's // writeback. if !rcx.infcx.tcx.use_typing_mode_borrowck() { - if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() + if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.skip_binder().kind() && alias_ty.def_id == opaque_type_key.def_id.to_def_id() && alias_ty.args == opaque_type_key.args { @@ -357,12 +355,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( }, )); } - add_hidden_type( - tcx, - hidden_types, - opaque_type_key.def_id, - OpaqueHiddenType { span: hidden_type.span, ty }, - ); + add_hidden_type(tcx, hidden_types, opaque_type_key.def_id, hidden_type); } } @@ -495,14 +488,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( region_bound_pairs: &RegionBoundPairs<'tcx>, known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>], constraints: &mut MirTypeckRegionConstraints<'tcx>, - hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, - opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], + hidden_types: &mut FxIndexMap>, + opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], ) -> Vec> { let tcx = infcx.tcx; let mut errors = Vec::new(); for &(key, hidden_type) in opaque_types { - let Some(expected) = hidden_types.0.get(&key.def_id).map(|ty| EarlyBinder::bind(*ty)) - else { + let Some(expected) = hidden_types.get(&key.def_id) else { if !tcx.use_typing_mode_borrowck() { if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind() && alias_ty.def_id == key.def_id.to_def_id() @@ -521,20 +513,26 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( hidden_type.span, "non-defining use in the defining scope with no defining uses", ); - add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar)); + add_hidden_type( + tcx, + hidden_types, + key.def_id, + DefinitionSiteHiddenType::new_error(tcx, guar), + ); continue; }; // We erase all non-member region of the opaque and need to treat these as existentials. - let expected = ty::fold_regions(tcx, expected.instantiate(tcx, key.args), |re, _dbi| { - match re.kind() { - ty::ReErased => infcx.next_nll_region_var( - NllRegionVariableOrigin::Existential { name: None }, - || crate::RegionCtxt::Existential(None), - ), - _ => re, - } - }); + let expected_ty = + ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| { + match re.kind() { + ty::ReErased => infcx.next_nll_region_var( + NllRegionVariableOrigin::Existential { name: None }, + || crate::RegionCtxt::Existential(None), + ), + _ => re, + } + }); // We now simply equate the expected with the actual hidden type. let locations = Locations::All(hidden_type.span); @@ -555,13 +553,18 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( ); // We need to normalize both types in the old solver before equatingt them. let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty); - let expected_ty = ocx.normalize(&cause, infcx.param_env, expected.ty); + let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty); ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution) }, "equating opaque types", ), ) { - add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar)); + add_hidden_type( + tcx, + hidden_types, + key.def_id, + DefinitionSiteHiddenType::new_error(tcx, guar), + ); } } errors @@ -676,8 +679,8 @@ impl<'tcx> InferCtxt<'tcx> { fn infer_opaque_definition_from_instantiation( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - instantiated_ty: OpaqueHiddenType<'tcx>, - ) -> Result, NonDefiningUseReason<'tcx>> { + instantiated_ty: ProvisionalHiddenType<'tcx>, + ) -> Result, NonDefiningUseReason<'tcx>> { opaque_type_has_defining_use_args( self, opaque_type_key, @@ -685,15 +688,12 @@ impl<'tcx> InferCtxt<'tcx> { DefiningScopeKind::MirBorrowck, )?; - let definition_ty = instantiated_ty - .remap_generic_params_to_declaration_params( - opaque_type_key, - self.tcx, - DefiningScopeKind::MirBorrowck, - ) - .ty; - - definition_ty.error_reported()?; + let definition_ty = instantiated_ty.remap_generic_params_to_declaration_params( + opaque_type_key, + self.tcx, + DefiningScopeKind::MirBorrowck, + ); + definition_ty.ty.skip_binder().error_reported()?; Ok(definition_ty) } } diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index 21c11e1287353..c3ff8cba94722 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -17,9 +17,8 @@ use crate::region_infer::opaque_types::{ }; use crate::type_check::{Locations, constraint_conversion}; use crate::{ - ClosureRegionRequirements, CollectRegionConstraintsResult, DefinitionSiteHiddenTypes, - PropagatedBorrowCheckResults, borrowck_check_region_constraints, - borrowck_collect_region_constraints, + ClosureRegionRequirements, CollectRegionConstraintsResult, PropagatedBorrowCheckResults, + borrowck_check_region_constraints, borrowck_collect_region_constraints, }; /// The shared context used by both the root as well as all its nested @@ -27,7 +26,7 @@ use crate::{ pub(super) struct BorrowCheckRootCtxt<'tcx> { pub tcx: TyCtxt<'tcx>, root_def_id: LocalDefId, - hidden_types: DefinitionSiteHiddenTypes<'tcx>, + hidden_types: FxIndexMap>, /// The region constraints computed by [borrowck_collect_region_constraints]. This uses /// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before /// their parents. @@ -72,7 +71,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { &self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars } - pub(super) fn finalize(self) -> Result<&'tcx DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> { + pub(super) fn finalize( + self, + ) -> Result<&'tcx FxIndexMap>, ErrorGuaranteed> + { if let Some(guar) = self.tainted_by_errors { Err(guar) } else { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index c082a82306848..49d38e05c8b06 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -16,7 +16,6 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; -use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers, @@ -1458,10 +1457,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { match &fn_abi.ret.mode { PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(), - PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call), - mode @ PassMode::Cast { .. } => { - bug!("Encountered `PassMode::{mode:?}` during codegen") - } + PassMode::Direct(_) | PassMode::Pair { .. } | PassMode::Cast { .. } => self.ret(call), } } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e2241a77d186c..0d1e27a34dc5b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1063,7 +1063,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs); target.map(|target| (return_dest, target)) } - CallKind::Tail => None, + CallKind::Tail => { + if fn_abi.ret.is_indirect() { + match self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs) { + ReturnDest::Nothing => {} + _ => bug!( + "tail calls to functions with indirect returns cannot store into a destination" + ), + } + } + None + } }; // Split the rust-call tupled arguments off. diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 25ab91ebc9cfa..cc6598916eec6 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -430,7 +430,7 @@ fn best_definition_site_of_opaque<'tcx>( .tcx .mir_borrowck(item_def_id) .ok() - .and_then(|opaque_types| opaque_types.0.get(&self.opaque_def_id)) + .and_then(|opaque_types| opaque_types.get(&self.opaque_def_id)) { ControlFlow::Break((hidden_ty.span, item_def_id)) } else { @@ -493,7 +493,7 @@ fn best_definition_site_of_opaque<'tcx>( fn sanity_check_found_hidden_type<'tcx>( tcx: TyCtxt<'tcx>, key: ty::OpaqueTypeKey<'tcx>, - mut ty: ty::OpaqueHiddenType<'tcx>, + mut ty: ty::ProvisionalHiddenType<'tcx>, ) -> Result<(), ErrorGuaranteed> { if ty.ty.is_ty_var() { // Nothing was actually constrained. @@ -529,7 +529,7 @@ fn sanity_check_found_hidden_type<'tcx>( Ok(()) } else { let span = tcx.def_span(key.def_id); - let other = ty::OpaqueHiddenType { ty: hidden_ty, span }; + let other = ty::ProvisionalHiddenType { ty: hidden_ty, span }; Err(ty.build_mismatch_error(&other, tcx)?.emit()) } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 8cbf17162e321..e93725e136137 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -345,7 +345,7 @@ pub(super) fn type_of_opaque( def_id: DefId, ) -> Result>, CyclePlaceholder> { if let Some(def_id) = def_id.as_local() { - Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { + Ok(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { opaque::find_opaque_ty_constraints_for_tait( tcx, @@ -378,7 +378,7 @@ pub(super) fn type_of_opaque( DefiningScopeKind::MirBorrowck, ) } - })) + }) } else { // Foreign opaque type will go through the foreign provider // and load the type from metadata. @@ -390,7 +390,7 @@ pub(super) fn type_of_opaque_hir_typeck( tcx: TyCtxt<'_>, def_id: LocalDefId, ) -> ty::EarlyBinder<'_, Ty<'_>> { - ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { + match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin { hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { opaque::find_opaque_ty_constraints_for_tait(tcx, def_id, DefiningScopeKind::HirTypeck) } @@ -419,7 +419,7 @@ pub(super) fn type_of_opaque_hir_typeck( DefiningScopeKind::HirTypeck, ) } - }) + } } fn infer_placeholder_type<'tcx>( diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 870a7b6563860..03216d009c2e7 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -3,7 +3,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, DefiningScopeKind, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, DefiningScopeKind, EarlyBinder, Ty, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::opaque_types::report_item_does_not_constrain_error; use tracing::{debug, instrument, trace}; @@ -16,7 +16,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_types_from: DefiningScopeKind, -) -> Ty<'_> { +) -> EarlyBinder<'_, Ty<'_>> { let mut parent_def_id = def_id; while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy { // Account for `type Alias = impl Trait;` (#116031) @@ -49,7 +49,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( name: tcx.item_ident(parent_def_id.to_def_id()), what: "impl", }); - Ty::new_error(tcx, guar) + EarlyBinder::bind(Ty::new_error(tcx, guar)) } } @@ -76,7 +76,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait( tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_types_from: DefiningScopeKind, -) -> Ty<'_> { +) -> EarlyBinder<'_, Ty<'_>> { let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from }; tcx.hir_walk_toplevel_module(&mut locator); @@ -94,7 +94,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait( name: tcx.item_ident(parent_def_id.to_def_id()), what: "crate", }); - Ty::new_error(tcx, guar) + EarlyBinder::bind(Ty::new_error(tcx, guar)) } } @@ -109,18 +109,18 @@ struct TaitConstraintLocator<'tcx> { /// with the first type that we find, and then later types are /// checked against it (we also carry the span of that first /// type). - found: Option>, + found: Option>, opaque_types_from: DefiningScopeKind, } impl<'tcx> TaitConstraintLocator<'tcx> { - fn insert_found(&mut self, hidden_ty: ty::OpaqueHiddenType<'tcx>) { + fn insert_found(&mut self, hidden_ty: ty::DefinitionSiteHiddenType<'tcx>) { if let Some(prev) = &mut self.found { if hidden_ty.ty != prev.ty { let (Ok(guar) | Err(guar)) = prev.build_mismatch_error(&hidden_ty, self.tcx).map(|d| d.emit()); - prev.ty = Ty::new_error(self.tcx, guar); + *prev = ty::DefinitionSiteHiddenType::new_error(self.tcx, guar); } } else { self.found = Some(hidden_ty); @@ -133,7 +133,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> { // with the new solver. assert!(!self.tcx.next_trait_solver_globally()); let guar = report_item_does_not_constrain_error(self.tcx, item_def_id, self.def_id, None); - self.insert_found(ty::OpaqueHiddenType::new_error(self.tcx, guar)); + self.insert_found(ty::DefinitionSiteHiddenType::new_error(self.tcx, guar)); } #[instrument(skip(self), level = "debug")] @@ -168,7 +168,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> { hir_sig.decl.output.span(), "inferring return types and opaque types do not mix well", ); - self.found = Some(ty::OpaqueHiddenType::new_error(tcx, guar)); + self.found = Some(ty::DefinitionSiteHiddenType::new_error(tcx, guar)); return; } @@ -176,7 +176,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> { DefiningScopeKind::HirTypeck => { let tables = tcx.typeck(item_def_id); if let Some(guar) = tables.tainted_by_errors { - self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)); + self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)); } else if let Some(&hidden_type) = tables.hidden_types.get(&self.def_id) { self.insert_found(hidden_type); } else { @@ -184,17 +184,15 @@ impl<'tcx> TaitConstraintLocator<'tcx> { } } DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) { - Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)), + Err(guar) => self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)), Ok(hidden_types) => { - if let Some(&hidden_type) = hidden_types.0.get(&self.def_id) { + if let Some(&hidden_type) = hidden_types.get(&self.def_id) { debug!(?hidden_type, "found constraint"); self.insert_found(hidden_type); - } else if let Err(guar) = tcx - .type_of_opaque_hir_typeck(self.def_id) - .instantiate_identity() - .error_reported() + } else if let Err(guar) = + tcx.type_of_opaque_hir_typeck(self.def_id).skip_binder().error_reported() { - self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)); + self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)); } else { self.non_defining_use_in_defining_scope(item_def_id); } @@ -241,7 +239,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( def_id: LocalDefId, owner_def_id: LocalDefId, opaque_types_from: DefiningScopeKind, -) -> Ty<'tcx> { +) -> EarlyBinder<'tcx, Ty<'tcx>> { // When an opaque type is stranded, its hidden type cannot be inferred // so we should not continue. if !tcx.opaque_types_defined_by(owner_def_id).contains(&def_id) { @@ -249,14 +247,14 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( let guar = tcx .dcx() .span_delayed_bug(opaque_type_span, "cannot infer type for stranded opaque type"); - return Ty::new_error(tcx, guar); + return EarlyBinder::bind(Ty::new_error(tcx, guar)); } match opaque_types_from { DefiningScopeKind::HirTypeck => { let tables = tcx.typeck(owner_def_id); if let Some(guar) = tables.tainted_by_errors { - Ty::new_error(tcx, guar) + EarlyBinder::bind(Ty::new_error(tcx, guar)) } else if let Some(hidden_ty) = tables.hidden_types.get(&def_id) { hidden_ty.ty } else { @@ -267,24 +265,24 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( // so we can just make the hidden type be `!`. // For backwards compatibility reasons, we fall back to // `()` until we the diverging default is changed. - Ty::new_diverging_default(tcx) + EarlyBinder::bind(Ty::new_diverging_default(tcx)) } } DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) { Ok(hidden_types) => { - if let Some(hidden_ty) = hidden_types.0.get(&def_id) { + if let Some(hidden_ty) = hidden_types.get(&def_id) { hidden_ty.ty } else { - let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity(); - if let Err(guar) = hir_ty.error_reported() { - Ty::new_error(tcx, guar) + let hir_ty = tcx.type_of_opaque_hir_typeck(def_id); + if let Err(guar) = hir_ty.skip_binder().error_reported() { + EarlyBinder::bind(Ty::new_error(tcx, guar)) } else { assert!(!tcx.next_trait_solver_globally()); hir_ty } } } - Err(guar) => Ty::new_error(tcx, guar), + Err(guar) => EarlyBinder::bind(Ty::new_error(tcx, guar)), }, } } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index a3f6803c5dc2c..a8457134031c9 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -584,8 +584,8 @@ pub(crate) fn method_autoderef_steps<'tcx>( value: query::MethodAutoderefSteps { predefined_opaques_in_body, self_ty }, } = goal; for (key, ty) in predefined_opaques_in_body { - let prev = - infcx.register_hidden_type_in_storage(key, ty::OpaqueHiddenType { span: DUMMY_SP, ty }); + let prev = infcx + .register_hidden_type_in_storage(key, ty::ProvisionalHiddenType { span: DUMMY_SP, ty }); // It may be possible that two entries in the opaque type storage end up // with the same key after resolving contained inference variables. // diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index 05b5b1a8af803..18c1bf39a7c13 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -1,8 +1,8 @@ use rustc_hir::def::DefKind; use rustc_infer::traits::ObligationCause; use rustc_middle::ty::{ - self, DefiningScopeKind, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, TypeVisitableExt, - TypingMode, + self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueTypeKey, ProvisionalHiddenType, + TypeVisitableExt, TypingMode, }; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; use rustc_trait_selection::opaque_types::{ @@ -57,9 +57,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> { #[derive(Copy, Clone, Debug)] enum UsageKind<'tcx> { None, - NonDefiningUse(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>), - UnconstrainedHiddenType(OpaqueHiddenType<'tcx>), - HasDefiningUse(OpaqueHiddenType<'tcx>), + NonDefiningUse(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>), + UnconstrainedHiddenType(ProvisionalHiddenType<'tcx>), + HasDefiningUse(DefinitionSiteHiddenType<'tcx>), } impl<'tcx> UsageKind<'tcx> { @@ -88,7 +88,7 @@ impl<'tcx> UsageKind<'tcx> { impl<'tcx> FnCtxt<'_, 'tcx> { fn compute_definition_site_hidden_types( &mut self, - mut opaque_types: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>, + mut opaque_types: Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>, error_on_missing_defining_use: bool, ) { for entry in opaque_types.iter_mut() { @@ -131,7 +131,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { continue; } - let expected = EarlyBinder::bind(ty.ty).instantiate(tcx, opaque_type_key.args); + let expected = ty.ty.instantiate(tcx, opaque_type_key.args); self.demand_eqtype(hidden_type.span, expected, hidden_type.ty); } @@ -191,7 +191,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { self.typeck_results .borrow_mut() .hidden_types - .insert(def_id, OpaqueHiddenType::new_error(tcx, guar)); + .insert(def_id, DefinitionSiteHiddenType::new_error(tcx, guar)); self.set_tainted_by_errors(guar); } } @@ -200,7 +200,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fn consider_opaque_type_use( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, ) -> UsageKind<'tcx> { if let Err(err) = opaque_type_has_defining_use_args( &self, @@ -210,7 +210,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> { ) { match err { NonDefiningUseReason::Tainted(guar) => { - return UsageKind::HasDefiningUse(OpaqueHiddenType::new_error(self.tcx, guar)); + return UsageKind::HasDefiningUse(DefinitionSiteHiddenType::new_error( + self.tcx, guar, + )); } _ => return UsageKind::NonDefiningUse(opaque_type_key, hidden_type), }; @@ -230,7 +232,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { Ok(hidden_type) => hidden_type, Err(errors) => { let guar = self.err_ctxt().report_fulfillment_errors(errors); - OpaqueHiddenType::new_error(self.tcx, guar) + ProvisionalHiddenType::new_error(self.tcx, guar) } }; let hidden_type = hidden_type.remap_generic_params_to_declaration_params( diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 50b6fe1ad5ecb..3235aa396df4f 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -21,7 +21,7 @@ use rustc_infer::traits::solve::Goal; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::{ - self, DefiningScopeKind, OpaqueHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder, + self, DefiningScopeKind, DefinitionSiteHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, fold_regions, }; @@ -550,10 +550,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn visit_opaque_types_next(&mut self) { let mut fcx_typeck_results = self.fcx.typeck_results.borrow_mut(); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); - for hidden_ty in fcx_typeck_results.hidden_types.values() { - assert!(!hidden_ty.has_infer()); - } - assert_eq!(self.typeck_results.hidden_types.len(), 0); self.typeck_results.hidden_types = mem::take(&mut fcx_typeck_results.hidden_types); } @@ -589,7 +585,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { ) { self.typeck_results.hidden_types.insert( opaque_type_key.def_id, - ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)), + ty::DefinitionSiteHiddenType::new_error(tcx, err.report(self.fcx)), ); } @@ -603,15 +599,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.typeck_results.hidden_types.insert(opaque_type_key.def_id, hidden_type) { let entry = - &mut self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap(); + self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap(); if prev.ty != hidden_type.ty { - if let Some(guar) = self.typeck_results.tainted_by_errors { - entry.ty = Ty::new_error(tcx, guar); + let guar = if let Some(guar) = self.typeck_results.tainted_by_errors { + guar } else { let (Ok(guar) | Err(guar)) = prev.build_mismatch_error(&hidden_type, tcx).map(|d| d.emit()); - entry.ty = Ty::new_error(tcx, guar); - } + guar + }; + *entry = DefinitionSiteHiddenType::new_error(tcx, guar); } // Pick a better span if there is one. @@ -627,6 +624,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { .filter(|&(&def_id, hidden_ty)| { hidden_ty .ty + .instantiate_identity() .visit_with(&mut HasRecursiveOpaque { def_id, seen: Default::default(), @@ -646,7 +644,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { .emit(); self.typeck_results .hidden_types - .insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) }); + .insert(def_id, DefinitionSiteHiddenType::new_error(tcx, guar)); } } @@ -1045,7 +1043,7 @@ impl<'tcx> TypeFolder> for EagerlyNormalizeConsts<'tcx> { struct HasRecursiveOpaque<'a, 'tcx> { def_id: LocalDefId, seen: FxHashSet, - opaques: &'a FxIndexMap>, + opaques: &'a FxIndexMap>, tcx: TyCtxt<'tcx>, } @@ -1063,9 +1061,7 @@ impl<'tcx> TypeVisitor> for HasRecursiveOpaque<'_, 'tcx> { if self.seen.insert(def_id) && let Some(hidden_ty) = self.opaques.get(&def_id) { - ty::EarlyBinder::bind(hidden_ty.ty) - .instantiate(self.tcx, alias_ty.args) - .visit_with(self)?; + hidden_ty.ty.instantiate(self.tcx, alias_ty.args).visit_with(self)?; } } diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 5ffa7304efaff..09403513aa08c 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -314,7 +314,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { ) -> Option> { self.register_hidden_type_in_storage( opaque_type_key, - ty::OpaqueHiddenType { span, ty: hidden_ty }, + ty::ProvisionalHiddenType { span, ty: hidden_ty }, ) } fn add_duplicate_opaque_type( @@ -326,7 +326,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.inner .borrow_mut() .opaque_types() - .add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty }) + .add_duplicate(opaque_type_key, ty::ProvisionalHiddenType { span, ty: hidden_ty }) } fn reset_opaque_types(&self) { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f3ebfde06ab6b..dc4ee0d88a06c 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -28,7 +28,7 @@ use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, - GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueHiddenType, OpaqueTypeKey, + GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueTypeKey, ProvisionalHiddenType, PseudoCanonicalInput, Term, TermKind, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions, }; @@ -978,12 +978,12 @@ impl<'tcx> InferCtxt<'tcx> { } #[instrument(level = "debug", skip(self), ret)] - pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> { + pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> { self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect() } #[instrument(level = "debug", skip(self), ret)] - pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> { + pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> { self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect() } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 220e025c3f7d6..9579abf7ec53c 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -5,7 +5,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, BottomUpFolder, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, + self, BottomUpFolder, OpaqueTypeKey, ProvisionalHiddenType, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, }; use rustc_span::Span; @@ -199,7 +199,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn register_hidden_type_in_storage( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - hidden_ty: OpaqueHiddenType<'tcx>, + hidden_ty: ProvisionalHiddenType<'tcx>, ) -> Option> { self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty) } @@ -237,7 +237,7 @@ impl<'tcx> InferCtxt<'tcx> { .inner .borrow_mut() .opaque_types() - .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span }); + .register(opaque_type_key, ProvisionalHiddenType { ty: hidden_ty, span }); if let Some(prev) = prev { goals.extend( self.at(&ObligationCause::dummy_with_span(span), param_env) @@ -253,7 +253,7 @@ impl<'tcx> InferCtxt<'tcx> { .inner .borrow_mut() .opaque_types() - .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span }); + .register(opaque_type_key, ProvisionalHiddenType { ty: hidden_ty, span }); // We either equate the new hidden type with the previous entry or with the type // inferred by HIR typeck. diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index df5a66243fc15..55c00a8695fa5 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -3,15 +3,15 @@ use std::ops::Deref; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::bug; -use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}; +use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType, Ty}; use tracing::instrument; use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog}; #[derive(Default, Debug, Clone)] pub struct OpaqueTypeStorage<'tcx> { - opaque_types: FxIndexMap, OpaqueHiddenType<'tcx>>, - duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>, + opaque_types: FxIndexMap, ProvisionalHiddenType<'tcx>>, + duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>, } /// The number of entries in the opaque type storage at a given point. @@ -35,7 +35,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { pub(crate) fn remove( &mut self, key: OpaqueTypeKey<'tcx>, - prev: Option>, + prev: Option>, ) { if let Some(prev) = prev { *self.opaque_types.get_mut(&key).unwrap() = prev; @@ -60,7 +60,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { pub(crate) fn take_opaque_types( &mut self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries)) } @@ -75,7 +75,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { pub fn opaque_types_added_since( &self, prev_entries: OpaqueTypeStorageEntries, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { self.opaque_types .iter() .skip(prev_entries.opaque_types) @@ -90,7 +90,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { /// to also consider duplicate entries. pub fn iter_lookup_table( &self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { self.opaque_types.iter().map(|(k, v)| (*k, *v)) } @@ -101,13 +101,13 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { /// accesses them. pub fn iter_duplicate_entries( &self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { self.duplicate_entries.iter().copied() } pub fn iter_opaque_types( &self, - ) -> impl Iterator, OpaqueHiddenType<'tcx>)> { + ) -> impl Iterator, ProvisionalHiddenType<'tcx>)> { let OpaqueTypeStorage { opaque_types, duplicate_entries } = self; opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied()) } @@ -146,7 +146,7 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { pub fn register( &mut self, key: OpaqueTypeKey<'tcx>, - hidden_type: OpaqueHiddenType<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, ) -> Option> { if let Some(entry) = self.storage.opaque_types.get_mut(&key) { let prev = std::mem::replace(entry, hidden_type); @@ -158,7 +158,11 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> { None } - pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>) { + pub fn add_duplicate( + &mut self, + key: OpaqueTypeKey<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, + ) { self.storage.duplicate_entries.push((key, hidden_type)); self.undo_log.push(UndoLog::DuplicateOpaqueType); } diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 22c815fb87c62..c859d64133c49 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use rustc_data_structures::undo_log::{Rollback, UndoLogs}; use rustc_data_structures::{snapshot_vec as sv, unify as ut}; -use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey}; +use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType}; use tracing::debug; use crate::infer::unify_key::{ConstVidKey, RegionVidKey}; @@ -19,7 +19,7 @@ pub struct Snapshot<'tcx> { #[derive(Clone)] pub(crate) enum UndoLog<'tcx> { DuplicateOpaqueType, - OpaqueTypes(OpaqueTypeKey<'tcx>, Option>), + OpaqueTypes(OpaqueTypeKey<'tcx>, Option>), TypeVariables(type_variable::UndoLog<'tcx>), ConstUnificationTable(sv::UndoLog>>), IntUnificationTable(sv::UndoLog>), diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 9082db4f4488c..9dd35b6de3080 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -2,6 +2,7 @@ use rustc_data_structures::snapshot_map::{self, SnapshotMapRef, SnapshotMapStorage}; use rustc_data_structures::undo_log::Rollback; +use rustc_macros::TypeVisitable; use rustc_middle::traits::EvaluationResult; use rustc_middle::ty; use tracing::{debug, info}; @@ -12,7 +13,7 @@ use crate::infer::snapshot::undo_log::InferCtxtUndoLogs; pub(crate) type UndoLog<'tcx> = snapshot_map::UndoLog, ProjectionCacheEntry<'tcx>>; -#[derive(Clone)] +#[derive(Clone, TypeVisitable)] pub struct MismatchedProjectionTypes<'tcx> { pub err: ty::error::TypeError<'tcx>, } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index feaad5bb96eb9..66ee88f0e5220 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -27,7 +27,10 @@ macro_rules! arena_types { rustc_middle::mir::Body<'tcx> >, [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, - [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>, + [decode] borrowck_result: rustc_data_structures::fx::FxIndexMap< + rustc_hir::def_id::LocalDefId, + rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, + >, [] resolver: rustc_data_structures::steal::Steal<( rustc_middle::ty::ResolverAstLowering, std::sync::Arc, diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 2e6c9f207e26b..7629ae9817fea 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -3,16 +3,14 @@ use std::fmt::{self, Debug}; use rustc_abi::{FieldIdx, VariantIdx}; -use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::LocalDefId; use rustc_index::IndexVec; use rustc_index::bit_set::BitMatrix; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::{Span, Symbol}; use super::{ConstValue, SourceInfo}; -use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty}; +use crate::ty::{self, CoroutineArgsExt, Ty}; rustc_index::newtype_index! { #[derive(HashStable)] @@ -84,11 +82,6 @@ impl Debug for CoroutineLayout<'_> { } } -/// All the opaque types that have had their hidden type fully computed. -/// Unlike the value in `TypeckResults`, this has unerased regions. -#[derive(Default, Debug, TyEncodable, TyDecodable, HashStable)] -pub struct DefinitionSiteHiddenTypes<'tcx>(pub FxIndexMap>); - /// The result of the `mir_const_qualif` query. /// /// Each field (except `tainted_by_errors`) corresponds to an implementer of the `Qualif` trait in diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 30d4cc8b3c8d6..d59ac85ad05fc 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1244,7 +1244,10 @@ rustc_queries! { /// Borrow-checks the given typeck root, e.g. functions, const/static items, /// and its children, e.g. closures, inline consts. - query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> { + query mir_borrowck(key: LocalDefId) -> Result< + &'tcx FxIndexMap>, + ErrorGuaranteed + > { desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 905874f05628f..2b9079da1830b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -725,7 +725,7 @@ impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> { } #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] -pub struct OpaqueHiddenType<'tcx> { +pub struct ProvisionalHiddenType<'tcx> { /// The span of this particular definition of the opaque type. So /// for example: /// @@ -767,9 +767,9 @@ pub enum DefiningScopeKind { MirBorrowck, } -impl<'tcx> OpaqueHiddenType<'tcx> { - pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> OpaqueHiddenType<'tcx> { - OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) } +impl<'tcx> ProvisionalHiddenType<'tcx> { + pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> ProvisionalHiddenType<'tcx> { + ProvisionalHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) } } pub fn build_mismatch_error( @@ -798,7 +798,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> { opaque_type_key: OpaqueTypeKey<'tcx>, tcx: TyCtxt<'tcx>, defining_scope_kind: DefiningScopeKind, - ) -> Self { + ) -> DefinitionSiteHiddenType<'tcx> { let OpaqueTypeKey { def_id, args } = opaque_type_key; // Use args to build up a reverse map from regions to their @@ -821,15 +821,68 @@ impl<'tcx> OpaqueHiddenType<'tcx> { // // We erase regions when doing this during HIR typeck. We manually use `fold_regions` // here as we do not want to anonymize bound variables. - let this = match defining_scope_kind { - DefiningScopeKind::HirTypeck => fold_regions(tcx, self, |_, _| tcx.lifetimes.re_erased), - DefiningScopeKind::MirBorrowck => self, + let ty = match defining_scope_kind { + DefiningScopeKind::HirTypeck => { + fold_regions(tcx, self.ty, |_, _| tcx.lifetimes.re_erased) + } + DefiningScopeKind::MirBorrowck => self.ty, }; - let result = this.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span)); + let result_ty = ty.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span)); if cfg!(debug_assertions) && matches!(defining_scope_kind, DefiningScopeKind::HirTypeck) { - assert_eq!(result.ty, fold_regions(tcx, result.ty, |_, _| tcx.lifetimes.re_erased)); + assert_eq!(result_ty, fold_regions(tcx, result_ty, |_, _| tcx.lifetimes.re_erased)); + } + DefinitionSiteHiddenType { span: self.span, ty: ty::EarlyBinder::bind(result_ty) } + } +} + +#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)] +pub struct DefinitionSiteHiddenType<'tcx> { + /// The span of the definition of the opaque type. So for example: + /// + /// ```ignore (incomplete snippet) + /// type Foo = impl Baz; + /// fn bar() -> Foo { + /// // ^^^ This is the span we are looking for! + /// } + /// ``` + /// + /// In cases where the fn returns `(impl Trait, impl Trait)` or + /// other such combinations, the result is currently + /// over-approximated, but better than nothing. + pub span: Span, + + /// The final type of the opaque. + pub ty: ty::EarlyBinder<'tcx, Ty<'tcx>>, +} + +impl<'tcx> DefinitionSiteHiddenType<'tcx> { + pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> DefinitionSiteHiddenType<'tcx> { + DefinitionSiteHiddenType { + span: DUMMY_SP, + ty: ty::EarlyBinder::bind(Ty::new_error(tcx, guar)), } - result + } + + pub fn build_mismatch_error( + &self, + other: &Self, + tcx: TyCtxt<'tcx>, + ) -> Result, ErrorGuaranteed> { + let self_ty = self.ty.instantiate_identity(); + let other_ty = other.ty.instantiate_identity(); + (self_ty, other_ty).error_reported()?; + // Found different concrete types for the opaque type. + let sub_diag = if self.span == other.span { + TypeMismatchReason::ConflictType { span: self.span } + } else { + TypeMismatchReason::PreviousUse { span: self.span } + }; + Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch { + self_ty, + other_ty, + other_span: other.span, + sub: sub_diag, + })) } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 96f5697971a47..5300be58f04e6 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -168,7 +168,7 @@ pub struct TypeckResults<'tcx> { /// We also store the type here, so that the compiler can use it as a hint /// for figuring out hidden types, even if they are only set in dead code /// (which doesn't show up in MIR). - pub hidden_types: FxIndexMap>, + pub hidden_types: FxIndexMap>, /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 0652461e97501..8df34ee941b21 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -148,7 +148,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { self.typeck_results .hidden_types .get(&key.def_id) - .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args)) + .map(|x| x.ty.instantiate(self.tcx, key.args)) } // This can take a non-revealed `Ty` because it reveals opaques itself. pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 8e4c7cec0dcf0..b98547c42789d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -20,7 +20,7 @@ use rustc_infer::traits::{ PredicateObligation, SelectionError, }; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span}; use tracing::{info, instrument}; @@ -253,7 +253,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { for from_expansion in [false, true] { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { - if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { + if !suppressed + && error.obligation.cause.span.from_expansion() == from_expansion + && !error.references_error() + { let guar = self.report_fulfillment_error(error); self.infcx.set_tainted_by_errors(guar); reported = Some(guar); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 0f3b38ef66751..308d533e68991 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -29,6 +29,7 @@ use std::ops::ControlFlow; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; pub use rustc_infer::traits::*; +use rustc_macros::TypeVisitable; use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -75,7 +76,7 @@ use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::regions::InferCtxtRegionExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -#[derive(Debug)] +#[derive(Debug, TypeVisitable)] pub struct FulfillmentError<'tcx> { pub obligation: PredicateObligation<'tcx>, pub code: FulfillmentErrorCode<'tcx>, @@ -107,7 +108,7 @@ impl<'tcx> FulfillmentError<'tcx> { } } -#[derive(Clone)] +#[derive(Clone, TypeVisitable)] pub enum FulfillmentErrorCode<'tcx> { /// Inherently impossible to fulfill; this trait is implemented if and only /// if it is already implemented. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 0248688733952..96c1034f9735f 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2725,6 +2725,38 @@ impl [T] { None } + /// Returns a subslice with the prefix and suffix removed. + /// + /// If the slice starts with `prefix` and ends with `suffix`, returns the subslice after the + /// prefix and before the suffix, wrapped in `Some`. + /// + /// If the slice does not start with `prefix` or does not end with `suffix`, returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(strip_circumfix)] + /// + /// let v = &[10, 50, 40, 30]; + /// assert_eq!(v.strip_circumfix(&[10], &[30]), Some(&[50, 40][..])); + /// assert_eq!(v.strip_circumfix(&[10], &[40, 30]), Some(&[50][..])); + /// assert_eq!(v.strip_circumfix(&[10, 50], &[40, 30]), Some(&[][..])); + /// assert_eq!(v.strip_circumfix(&[50], &[30]), None); + /// assert_eq!(v.strip_circumfix(&[10], &[40]), None); + /// assert_eq!(v.strip_circumfix(&[], &[40, 30]), Some(&[10, 50][..])); + /// assert_eq!(v.strip_circumfix(&[10, 50], &[]), Some(&[40, 30][..])); + /// ``` + #[must_use = "returns the subslice without modifying the original"] + #[unstable(feature = "strip_circumfix", issue = "147946")] + pub fn strip_circumfix(&self, prefix: &P, suffix: &S) -> Option<&[T]> + where + T: PartialEq, + S: SlicePattern + ?Sized, + P: SlicePattern + ?Sized, + { + self.strip_prefix(prefix)?.strip_suffix(suffix) + } + /// Returns a subslice with the optional prefix removed. /// /// If the slice starts with `prefix`, returns the subslice after the prefix. If `prefix` diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 82019b9b3afe5..37dc401ed0098 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2447,6 +2447,42 @@ impl str { suffix.strip_suffix_of(self) } + /// Returns a string slice with the prefix and suffix removed. + /// + /// If the string starts with the pattern `prefix` and ends with the pattern `suffix`, returns + /// the substring after the prefix and before the suffix, wrapped in `Some`. + /// Unlike [`trim_start_matches`] and [`trim_end_matches`], this method removes both the prefix + /// and suffix exactly once. + /// + /// If the string does not start with `prefix` or does not end with `suffix`, returns `None`. + /// + /// Each [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a + /// function or closure that determines if a character matches. + /// + /// [`char`]: prim@char + /// [pattern]: self::pattern + /// [`trim_start_matches`]: Self::trim_start_matches + /// [`trim_end_matches`]: Self::trim_end_matches + /// + /// # Examples + /// + /// ``` + /// #![feature(strip_circumfix)] + /// + /// assert_eq!("bar:hello:foo".strip_circumfix("bar:", ":foo"), Some("hello")); + /// assert_eq!("bar:foo".strip_circumfix("foo", "foo"), None); + /// assert_eq!("foo:bar;".strip_circumfix("foo:", ';'), Some("bar")); + /// ``` + #[must_use = "this returns the remaining substring as a new slice, \ + without modifying the original"] + #[unstable(feature = "strip_circumfix", issue = "147946")] + pub fn strip_circumfix(&self, prefix: P, suffix: S) -> Option<&str> + where + for<'a> S::Searcher<'a>: ReverseSearcher<'a>, + { + self.strip_prefix(prefix)?.strip_suffix(suffix) + } + /// Returns a string slice with the optional prefix removed. /// /// If the string starts with the pattern `prefix`, returns the substring after the prefix. diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 0827d3d9319c5..39bf9c7776401 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -444,7 +444,7 @@ target | std | host | notes `x86_64-uwp-windows-gnu` | ✓ | | [`x86_64-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [`x86_64-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 64-bit Windows 7 support -[`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support +[`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | ✓ | 64-bit Windows 7 support [`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) [`xtensa-esp32-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32 diff --git a/src/doc/rustc/src/platform-support/win7-windows-msvc.md b/src/doc/rustc/src/platform-support/win7-windows-msvc.md index 56fe0f6401664..b14424ddbf3a4 100644 --- a/src/doc/rustc/src/platform-support/win7-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/win7-windows-msvc.md @@ -16,7 +16,8 @@ Target triples: This target supports all of core, alloc, std and test. This is automatically tested every night on private infrastructure hosted by the maintainer. Host -tools may also work, though those are not currently tested. +tools may also work, though it is not guaranteed. Last known success built +version of rustc with host tools (x86_64) is 1.91.0. Those targets follow Windows calling convention for extern "C". diff --git a/src/etc/rust-lldb b/src/etc/rust-lldb index bce72f1bad698..f8f31903060c3 100755 --- a/src/etc/rust-lldb +++ b/src/etc/rust-lldb @@ -4,7 +4,7 @@ set -e # Find the host triple so we can find lldb in rustlib. -host=$(rustc -vV | sed -n -e 's/^host: //p') +host=$(rustc --print host-tuple) # Find out where to look for the pretty printer Python module RUSTC_SYSROOT=$(rustc --print sysroot) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index b82a533271c17..611380a35ae7c 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -18,7 +18,6 @@ use crate::common::{ CompareMode, Config, Debugger, FailMode, PassMode, RunFailMode, RunResult, TestMode, TestPaths, TestSuite, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, expected_output_path, incremental_dir, output_base_dir, output_base_name, - output_testname_unique, }; use crate::directives::TestProps; use crate::errors::{Error, ErrorKind, load_errors}; @@ -563,7 +562,7 @@ impl<'test> TestCx<'test> { self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags); rustc.args(&self.props.compile_flags); - self.compose_and_run_compiler(rustc, Some(src), self.testpaths) + self.compose_and_run_compiler(rustc, Some(src)) } fn maybe_add_external_args(&self, cmd: &mut Command, args: &Vec) { @@ -994,37 +993,41 @@ impl<'test> TestCx<'test> { passes, ); - self.compose_and_run_compiler(rustc, None, self.testpaths) + self.compose_and_run_compiler(rustc, None) } /// `root_out_dir` and `root_testpaths` refer to the parameters of the actual test being run. /// Auxiliaries, no matter how deep, have the same root_out_dir and root_testpaths. - fn document( + fn document(&self, root_out_dir: &Utf8Path, kind: DocKind) -> ProcRes { + self.document_inner(&self.testpaths.file, root_out_dir, kind) + } + + /// Like `document`, but takes an explicit `file_to_doc` argument so that + /// it can also be used for documenting auxiliaries, in addition to + /// documenting the main test file. + fn document_inner( &self, + file_to_doc: &Utf8Path, root_out_dir: &Utf8Path, - root_testpaths: &TestPaths, kind: DocKind, ) -> ProcRes { if self.props.build_aux_docs { assert_eq!(kind, DocKind::Html, "build-aux-docs only make sense for html output"); for rel_ab in &self.props.aux.builds { - let aux_testpaths = self.compute_aux_test_paths(root_testpaths, rel_ab); - let props_for_aux = - self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let aux_path = self.resolve_aux_path(rel_ab); + let props_for_aux = self.props.from_aux_file(&aux_path, self.revision, self.config); let aux_cx = TestCx { config: self.config, stdout: self.stdout, stderr: self.stderr, props: &props_for_aux, - testpaths: &aux_testpaths, + testpaths: self.testpaths, revision: self.revision, }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); - // use root_testpaths here, because aux-builds should have the - // same --out-dir and auxiliary directory. - let auxres = aux_cx.document(&root_out_dir, root_testpaths, kind); + let auxres = aux_cx.document_inner(&aux_path, &root_out_dir, kind); if !auxres.status.success() { return auxres; } @@ -1038,7 +1041,7 @@ impl<'test> TestCx<'test> { // actual --out-dir given to the auxiliary or test, as opposed to the root out dir for the entire // test let out_dir: Cow<'_, Utf8Path> = if self.props.unique_doc_out_dir { - let file_name = self.testpaths.file.file_stem().expect("file name should not be empty"); + let file_name = file_to_doc.file_stem().expect("file name should not be empty"); let out_dir = Utf8PathBuf::from_iter([ root_out_dir, Utf8Path::new("docs"), @@ -1052,7 +1055,7 @@ impl<'test> TestCx<'test> { }; let mut rustdoc = Command::new(rustdoc_path); - let current_dir = output_base_dir(self.config, root_testpaths, self.safe_revision()); + let current_dir = self.output_base_dir(); rustdoc.current_dir(current_dir); rustdoc .arg("-L") @@ -1063,7 +1066,7 @@ impl<'test> TestCx<'test> { .arg(out_dir.as_ref()) .arg("--deny") .arg("warnings") - .arg(&self.testpaths.file) + .arg(file_to_doc) .arg("-A") .arg("internal_features") .args(&self.props.compile_flags) @@ -1080,7 +1083,7 @@ impl<'test> TestCx<'test> { rustdoc.arg(format!("-Clinker={}", linker)); } - self.compose_and_run_compiler(rustdoc, None, root_testpaths) + self.compose_and_run_compiler(rustdoc, None) } fn exec_compiled_test(&self) -> ProcRes { @@ -1195,24 +1198,21 @@ impl<'test> TestCx<'test> { /// For each `aux-build: foo/bar` annotation, we check to find the file in an `auxiliary` /// directory relative to the test itself (not any intermediate auxiliaries). - fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> TestPaths { - let test_ab = - of.file.parent().expect("test file path has no parent").join("auxiliary").join(rel_ab); - if !test_ab.exists() { - self.fatal(&format!("aux-build `{}` source not found", test_ab)) + fn resolve_aux_path(&self, relative_aux_path: &str) -> Utf8PathBuf { + let aux_path = self + .testpaths + .file + .parent() + .expect("test file path has no parent") + .join("auxiliary") + .join(relative_aux_path); + if !aux_path.exists() { + self.fatal(&format!( + "auxiliary source file `{relative_aux_path}` not found at `{aux_path}`" + )); } - TestPaths { - file: test_ab, - relative_dir: of - .relative_dir - .join(self.output_testname_unique()) - .join("auxiliary") - .join(rel_ab) - .parent() - .expect("aux-build path has no parent") - .to_path_buf(), - } + aux_path } fn is_vxworks_pure_static(&self) -> bool { @@ -1258,13 +1258,13 @@ impl<'test> TestCx<'test> { aux_dir } - fn build_all_auxiliary(&self, of: &TestPaths, aux_dir: &Utf8Path, rustc: &mut Command) { + fn build_all_auxiliary(&self, aux_dir: &Utf8Path, rustc: &mut Command) { for rel_ab in &self.props.aux.builds { - self.build_auxiliary(of, rel_ab, &aux_dir, None); + self.build_auxiliary(rel_ab, &aux_dir, None); } for rel_ab in &self.props.aux.bins { - self.build_auxiliary(of, rel_ab, &aux_dir, Some(AuxType::Bin)); + self.build_auxiliary(rel_ab, &aux_dir, Some(AuxType::Bin)); } let path_to_crate_name = |path: &str| -> String { @@ -1283,12 +1283,12 @@ impl<'test> TestCx<'test> { }; for (aux_name, aux_path) in &self.props.aux.crates { - let aux_type = self.build_auxiliary(of, &aux_path, &aux_dir, None); + let aux_type = self.build_auxiliary(&aux_path, &aux_dir, None); add_extern(rustc, aux_name, aux_path, aux_type); } for proc_macro in &self.props.aux.proc_macros { - self.build_auxiliary(of, proc_macro, &aux_dir, Some(AuxType::ProcMacro)); + self.build_auxiliary(proc_macro, &aux_dir, Some(AuxType::ProcMacro)); let crate_name = path_to_crate_name(proc_macro); add_extern(rustc, &crate_name, proc_macro, AuxType::ProcMacro); } @@ -1296,7 +1296,7 @@ impl<'test> TestCx<'test> { // Build any `//@ aux-codegen-backend`, and pass the resulting library // to `-Zcodegen-backend` when compiling the test file. if let Some(aux_file) = &self.props.aux.codegen_backend { - let aux_type = self.build_auxiliary(of, aux_file, aux_dir, None); + let aux_type = self.build_auxiliary(aux_file, aux_dir, None); if let Some(lib_name) = get_lib_name(aux_file.trim_end_matches(".rs"), aux_type) { let lib_path = aux_dir.join(&lib_name); rustc.arg(format!("-Zcodegen-backend={}", lib_path)); @@ -1306,12 +1306,7 @@ impl<'test> TestCx<'test> { /// `root_testpaths` refers to the path of the original test. the auxiliary and the test with an /// aux-build have the same `root_testpaths`. - fn compose_and_run_compiler( - &self, - mut rustc: Command, - input: Option, - root_testpaths: &TestPaths, - ) -> ProcRes { + fn compose_and_run_compiler(&self, mut rustc: Command, input: Option) -> ProcRes { if self.props.add_core_stubs { let minicore_path = self.build_minicore(); rustc.arg("--extern"); @@ -1319,7 +1314,7 @@ impl<'test> TestCx<'test> { } let aux_dir = self.aux_output_dir(); - self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc); + self.build_all_auxiliary(&aux_dir, &mut rustc); rustc.envs(self.props.rustc_env.clone()); self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); @@ -1364,14 +1359,12 @@ impl<'test> TestCx<'test> { /// If `aux_type` is `None`, then this will determine the aux-type automatically. fn build_auxiliary( &self, - of: &TestPaths, source_path: &str, aux_dir: &Utf8Path, aux_type: Option, ) -> AuxType { - let aux_testpaths = self.compute_aux_test_paths(of, source_path); - let mut aux_props = - self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let aux_path = self.resolve_aux_path(source_path); + let mut aux_props = self.props.from_aux_file(&aux_path, self.revision, self.config); if aux_type == Some(AuxType::ProcMacro) { aux_props.force_host = true; } @@ -1388,21 +1381,20 @@ impl<'test> TestCx<'test> { stdout: self.stdout, stderr: self.stderr, props: &aux_props, - testpaths: &aux_testpaths, + testpaths: self.testpaths, revision: self.revision, }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); - let input_file = &aux_testpaths.file; let mut aux_rustc = aux_cx.make_compile_args( - input_file, + &aux_path, aux_output, Emit::None, AllowUnused::No, LinkToAux::No, Vec::new(), ); - aux_cx.build_all_auxiliary(of, &aux_dir, &mut aux_rustc); + aux_cx.build_all_auxiliary(&aux_dir, &mut aux_rustc); aux_rustc.envs(aux_props.rustc_env.clone()); for key in &aux_props.unset_rustc_env { @@ -1471,7 +1463,7 @@ impl<'test> TestCx<'test> { ); if !auxres.status.success() { self.fatal_proc_rec( - &format!("auxiliary build of {} failed to compile: ", aux_testpaths.file), + &format!("auxiliary build of {aux_path} failed to compile: "), &auxres, ); } @@ -2033,11 +2025,6 @@ impl<'test> TestCx<'test> { self.aux_output_dir_name().join("bin") } - /// Generates a unique name for the test, such as `testname.revision.mode`. - fn output_testname_unique(&self) -> Utf8PathBuf { - output_testname_unique(self.config, self.testpaths, self.safe_revision()) - } - /// The revision, ignored for incremental compilation since it wants all revisions in /// the same directory. fn safe_revision(&self) -> Option<&str> { @@ -2132,7 +2119,7 @@ impl<'test> TestCx<'test> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustc, None); (proc_res, output_path) } @@ -2210,9 +2197,9 @@ impl<'test> TestCx<'test> { Vec::new(), ); let aux_dir = new_rustdoc.aux_output_dir(); - new_rustdoc.build_all_auxiliary(&new_rustdoc.testpaths, &aux_dir, &mut rustc); + new_rustdoc.build_all_auxiliary(&aux_dir, &mut rustc); - let proc_res = new_rustdoc.document(&compare_dir, &new_rustdoc.testpaths, DocKind::Html); + let proc_res = new_rustdoc.document(&compare_dir, DocKind::Html); if !proc_res.status.success() { writeln!(self.stderr, "failed to run nightly rustdoc"); return; diff --git a/src/tools/compiletest/src/runtest/assembly.rs b/src/tools/compiletest/src/runtest/assembly.rs index 91d4f620f7194..c805b4c7a59e0 100644 --- a/src/tools/compiletest/src/runtest/assembly.rs +++ b/src/tools/compiletest/src/runtest/assembly.rs @@ -43,7 +43,7 @@ impl TestCx<'_> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustc, None); (proc_res, output_path) } } diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index d0a0c960b4512..5b94d9567d8fc 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -197,7 +197,7 @@ impl<'test> TestCx<'test> { rustdoc_cmd.arg(&self.testpaths.file); - let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc --test failed!", &proc_res) } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 9175a38ffa5c9..bc597597ce12e 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -8,7 +8,6 @@ use tracing::debug; use super::debugger::DebuggerCommands; use super::{Debugger, Emit, ProcRes, TestCx, Truncated, WillExecute}; -use crate::common::Config; use crate::debuggers::{extract_gdb_version, is_android_gdb_target}; impl TestCx<'_> { @@ -21,18 +20,6 @@ impl TestCx<'_> { } fn run_debuginfo_cdb_test(&self) { - let config = Config { - target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), - host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - ..self.config.clone() - }; - - let test_cx = TestCx { config: &config, ..*self }; - - test_cx.run_debuginfo_cdb_test_no_opt(); - } - - fn run_debuginfo_cdb_test_no_opt(&self) { let exe_file = self.make_exe_name(); // Existing PDB files are update in-place. When changing the debuginfo @@ -118,18 +105,6 @@ impl TestCx<'_> { } fn run_debuginfo_gdb_test(&self) { - let config = Config { - target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), - host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - ..self.config.clone() - }; - - let test_cx = TestCx { config: &config, ..*self }; - - test_cx.run_debuginfo_gdb_test_no_opt(); - } - - fn run_debuginfo_gdb_test_no_opt(&self) { let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "gdb") .unwrap_or_else(|e| self.fatal(&e)); let mut cmds = dbg_cmds.commands.join("\n"); @@ -355,18 +330,6 @@ impl TestCx<'_> { self.fatal("Can't run LLDB test because LLDB's python path is not set."); } - let config = Config { - target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), - host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - ..self.config.clone() - }; - - let test_cx = TestCx { config: &config, ..*self }; - - test_cx.run_debuginfo_lldb_test_no_opt(); - } - - fn run_debuginfo_lldb_test_no_opt(&self) { // compile test file (it should have 'compile-flags:-g' in the directive) let should_run = self.run_if_enabled(); let compile_result = self.compile_test(should_run, Emit::None); @@ -501,11 +464,4 @@ impl TestCx<'_> { .env("PYTHONPATH", pythonpath), ) } - - fn cleanup_debug_info_options(&self, options: &Vec) -> Vec { - // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS. - let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()]; - - options.iter().filter(|x| !options_to_remove.contains(x)).cloned().collect() - } } diff --git a/src/tools/compiletest/src/runtest/js_doc.rs b/src/tools/compiletest/src/runtest/js_doc.rs index f7c2e6f01180a..53c40515af74f 100644 --- a/src/tools/compiletest/src/runtest/js_doc.rs +++ b/src/tools/compiletest/src/runtest/js_doc.rs @@ -7,7 +7,7 @@ impl TestCx<'_> { if let Some(nodejs) = &self.config.nodejs { let out_dir = self.output_base_dir(); - self.document(&out_dir, &self.testpaths, DocKind::Html); + self.document(&out_dir, DocKind::Html); let file_stem = self.testpaths.file.file_stem().expect("no file stem"); let res = self.run_command_to_procres( diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 32b1823961bea..a4558de5f1c0c 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -11,7 +11,7 @@ impl TestCx<'_> { panic!("failed to remove and recreate output directory `{out_dir}`: {e}") }); - let proc_res = self.document(&out_dir, &self.testpaths, DocKind::Html); + let proc_res = self.document(&out_dir, DocKind::Html); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index dd7ebe9efaeef..6cb0c2a040535 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -13,7 +13,7 @@ impl TestCx<'_> { panic!("failed to remove and recreate output directory `{out_dir}`: {e}") }); - let proc_res = self.document(&out_dir, &self.testpaths, DocKind::Json); + let proc_res = self.document(&out_dir, DocKind::Json); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index c0adb6302e9d0..9147471c5bbcb 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -253,7 +253,7 @@ impl TestCx<'_> { rustc.arg(crate_name); } - let res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let res = self.compose_and_run_compiler(rustc, None); if !res.status.success() { self.fatal_proc_rec("failed to compile fixed code", &res); } diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs index 427c84679ba1c..c3f4fd63bac70 100644 --- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs @@ -4,8 +4,3 @@ trait X { fn f<'a>(arg : Box = &'a ()>>) {} //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments //~| ERROR associated type takes 0 generic arguments but 1 generic argument -//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments -//~| ERROR associated type takes 0 generic arguments but 1 generic argument -//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments -//~| ERROR associated type takes 0 generic arguments but 1 generic argument -//~| ERROR trait `X` is not dyn compatible diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr index 2c25589a55314..a29cf5bf5ad92 100644 --- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr @@ -28,87 +28,6 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/invalid_const_in_lifetime_position.rs:4:26 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/invalid_const_in_lifetime_position.rs:4:20 - | -LL | fn f<'a>(arg : Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/invalid_const_in_lifetime_position.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 7 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/compiletest-self-test/aux-has-props.rs b/tests/ui/compiletest-self-test/aux-has-props.rs new file mode 100644 index 0000000000000..73ec2e169f4fe --- /dev/null +++ b/tests/ui/compiletest-self-test/aux-has-props.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 +//@ aux-build: aux_with_props.rs +//@ compile-flags: --check-cfg=cfg(this_is_aux) +//@ run-pass + +// Test that auxiliaries are built using the directives in the auxiliary file, +// and don't just accidentally use the directives of the main test file. + +extern crate aux_with_props; + +fn main() { + assert!(!cfg!(this_is_aux)); + assert!(aux_with_props::aux_directives_are_respected()); +} diff --git a/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs b/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs new file mode 100644 index 0000000000000..31a5a05a7144f --- /dev/null +++ b/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs @@ -0,0 +1,6 @@ +//@ edition: 2024 +//@ compile-flags: --cfg=this_is_aux + +pub fn aux_directives_are_respected() -> bool { + cfg!(this_is_aux) +} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs index 882b27a418e55..18a9b53cf7681 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs @@ -9,11 +9,6 @@ const _: () = { fn f2<'a>(arg: Box = &'a ()>>) {} //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR `X` is not dyn compatible }; fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr index 57b61006631f9..8e972100173f8 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr @@ -28,87 +28,6 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/issue-102768.rs:9:30 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/issue-102768.rs:5:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/issue-102768.rs:9:24 - | -LL | fn f2<'a>(arg: Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-102768.rs:5:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 7 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/explicit-tail-calls/become-cast-return.rs b/tests/ui/explicit-tail-calls/become-cast-return.rs new file mode 100644 index 0000000000000..212a0ddcbca15 --- /dev/null +++ b/tests/ui/explicit-tail-calls/become-cast-return.rs @@ -0,0 +1,20 @@ +//@ run-pass +//@ ignore-backends: gcc +#![expect(incomplete_features)] +#![feature(explicit_tail_calls)] + +#[inline(never)] +fn leaf(_: &Box) -> [u8; 1] { + [1] +} + +#[inline(never)] +fn dispatch(param: &Box) -> [u8; 1] { + become leaf(param) +} + +fn main() { + let data = Box::new(0); + let out = dispatch(&data); + assert_eq!(out, [1]); +} diff --git a/tests/ui/explicit-tail-calls/become-indirect-return.rs b/tests/ui/explicit-tail-calls/become-indirect-return.rs new file mode 100644 index 0000000000000..7eec34f3b95c9 --- /dev/null +++ b/tests/ui/explicit-tail-calls/become-indirect-return.rs @@ -0,0 +1,20 @@ +//@ run-pass +//@ ignore-backends: gcc +#![expect(incomplete_features)] +#![feature(explicit_tail_calls)] + +#[inline(never)] +fn op_dummy(_param: &Box) -> [u8; 24] { + [1; 24] +} + +#[inline(never)] +fn dispatch(param: &Box) -> [u8; 24] { + become op_dummy(param) +} + +fn main() { + let param = Box::new(0); + let result = dispatch(¶m); + assert_eq!(result, [1; 24]); +} diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs index b02739a7d0acb..86b164ba7d8a8 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs +++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs @@ -6,7 +6,4 @@ fn main() { fn _f(arg : Box X = &'a [u32]>>) {} //~^ ERROR: use of undeclared lifetime name `'x` //~| ERROR: binding for associated type `Y` references lifetime - //~| ERROR: binding for associated type `Y` references lifetime - //~| ERROR: binding for associated type `Y` references lifetime - //~| ERROR: the trait `X` is not dyn compatible } diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr index c9b46de5c33c4..b77f10084c928 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr @@ -20,39 +20,7 @@ error[E0582]: binding for associated type `Y` references lifetime `'a`, which do LL | fn _f(arg : Box X = &'a [u32]>>) {} | ^^^^^^^^^^^^^^^^^ -error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33 - | -LL | fn _f(arg : Box X = &'a [u32]>>) {} - | ^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33 - | -LL | fn _f(arg : Box X = &'a [u32]>>) {} - | ^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:19 - | -LL | fn _f(arg : Box X = &'a [u32]>>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:2:8 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'x>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0261, E0582. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0261, E0582. +For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs index 294fb6743fbcd..22f4918fb1919 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -7,19 +7,10 @@ fn foo<'a>(arg: Box>) {} //~| ERROR: parenthesized generic arguments cannot be used //~| ERROR associated type takes 0 generic arguments but 1 generic argument //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR at least one trait is required - //~| ERROR: the trait `X` is not dyn compatible fn bar<'a>(arg: Box>) {} //~^ ERROR: parenthesized generic arguments cannot be used //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR: the trait `X` is not dyn compatible fn main() {} diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index e18d8198c9455..23199fae28b59 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -22,7 +22,7 @@ LL + fn foo<'a>(arg: Box = &'a ()>>) {} | error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 + --> $DIR/gat-trait-path-parenthesised-args.rs:12:27 | LL | fn bar<'a>(arg: Box>) {} | ^-- @@ -60,109 +60,7 @@ LL | type Y<'a>; | ^ error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn foo<'a>(arg: Box>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^---- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn foo<'a>(arg: Box>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 - | -LL | fn foo<'a>(arg: Box>) {} - | ^---- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0224]: at least one trait is required for an object type - --> $DIR/gat-trait-path-parenthesised-args.rs:5:29 - | -LL | fn foo<'a>(arg: Box>) {} - | ^^ - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/gat-trait-path-parenthesised-args.rs:5:21 - | -LL | fn foo<'a>(arg: Box>) {} - | ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 - | -LL | fn bar<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- -help: add missing lifetime argument - | -LL | fn bar<'a>(arg: Box>) {} - | ++ - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 + --> $DIR/gat-trait-path-parenthesised-args.rs:12:27 | LL | fn bar<'a>(arg: Box>) {} | ^ expected 1 lifetime argument @@ -172,46 +70,11 @@ note: associated type defined here, with 1 lifetime parameter: `'a` | LL | type Y<'a>; | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add missing lifetime argument | LL | fn bar<'a>(arg: Box>) {} | ++ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/gat-trait-path-parenthesised-args.rs:18:27 - | -LL | fn bar<'a>(arg: Box>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn bar<'a>(arg: Box>) {} - | ++ - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/gat-trait-path-parenthesised-args.rs:18:21 - | -LL | fn bar<'a>(arg: Box>) {} - | ^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/gat-trait-path-parenthesised-args.rs:2:8 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 15 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0038, E0107, E0224. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/issue-67510.rs b/tests/ui/generic-associated-types/issue-67510.rs index 5c3150a77ed1b..2db9fb82aaec4 100644 --- a/tests/ui/generic-associated-types/issue-67510.rs +++ b/tests/ui/generic-associated-types/issue-67510.rs @@ -5,6 +5,5 @@ trait X { fn f(x: Box = &'a ()>>) {} //~^ ERROR: use of undeclared lifetime name `'a` //~| ERROR: use of undeclared lifetime name `'a` -//~| ERROR: the trait `X` is not dyn compatible [E0038] fn main() {} diff --git a/tests/ui/generic-associated-types/issue-67510.stderr b/tests/ui/generic-associated-types/issue-67510.stderr index f5c494788ea58..34d867621d7e0 100644 --- a/tests/ui/generic-associated-types/issue-67510.stderr +++ b/tests/ui/generic-associated-types/issue-67510.stderr @@ -29,23 +29,6 @@ help: consider introducing lifetime `'a` here LL | fn f<'a>(x: Box = &'a ()>>) {} | ++++ -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/issue-67510.rs:5:13 - | -LL | fn f(x: Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-67510.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0261. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs index 8ecfa93750d48..f0e162d825f9d 100644 --- a/tests/ui/generic-associated-types/issue-71176.rs +++ b/tests/ui/generic-associated-types/issue-71176.rs @@ -9,14 +9,10 @@ impl Provider for () { struct Holder { inner: Box>, //~^ ERROR: missing generics for associated type - //~| ERROR: missing generics for associated type - //~| ERROR: missing generics for associated type - //~| ERROR: the trait `Provider` is not dyn compatible } fn main() { Holder { inner: Box::new(()), - //~^ ERROR: the trait `Provider` is not dyn compatible }; } diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index f231056a2eed8..ed837f3475338 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -14,75 +14,6 @@ help: add missing lifetime argument LL | inner: Box = B>>, | ++++ -error[E0107]: missing generics for associated type `Provider::A` - --> $DIR/issue-71176.rs:10:27 - | -LL | inner: Box>, - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-71176.rs:2:10 - | -LL | type A<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | inner: Box = B>>, - | ++++ - -error[E0107]: missing generics for associated type `Provider::A` - --> $DIR/issue-71176.rs:10:27 - | -LL | inner: Box>, - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-71176.rs:2:10 - | -LL | type A<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | inner: Box = B>>, - | ++++ - -error[E0038]: the trait `Provider` is not dyn compatible - --> $DIR/issue-71176.rs:10:14 - | -LL | inner: Box>, - | ^^^^^^^^^^^^^^^^^^^ `Provider` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-71176.rs:2:10 - | -LL | trait Provider { - | -------- this trait is not dyn compatible... -LL | type A<'a>; - | ^ ...because it contains the generic associated type `A` - = help: consider moving `A` to another trait - = help: only type `()` implements `Provider`; consider using it directly instead. - -error[E0038]: the trait `Provider` is not dyn compatible - --> $DIR/issue-71176.rs:19:16 - | -LL | inner: Box::new(()), - | ^^^^^^^^^^^^ `Provider` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/issue-71176.rs:2:10 - | -LL | trait Provider { - | -------- this trait is not dyn compatible... -LL | type A<'a>; - | ^ ...because it contains the generic associated type `A` - = help: consider moving `A` to another trait - = help: only type `()` implements `Provider`; consider using it directly instead. - -error: aborting due to 5 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.rs b/tests/ui/generic-associated-types/missing_lifetime_args.rs index e0f2db5eb21ed..331511ba61a48 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.rs +++ b/tests/ui/generic-associated-types/missing_lifetime_args.rs @@ -10,9 +10,6 @@ struct Foo<'a, 'b, 'c> { fn foo<'c, 'd>(_arg: Box>) {} //~^ ERROR missing generics for associated type -//~| ERROR missing generics for associated type -//~| ERROR missing generics for associated type -//~| ERROR the trait `X` is not dyn compatible fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {} //~^ ERROR struct takes 3 lifetime arguments but 2 lifetime diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr index 7b6888817f4f4..1a7a2e787a1a9 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr +++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr @@ -14,58 +14,8 @@ help: add missing lifetime arguments LL | fn foo<'c, 'd>(_arg: Box = (&'c u32, &'d u32)>>) {} | ++++++++ -error[E0107]: missing generics for associated type `X::Y` - --> $DIR/missing_lifetime_args.rs:11:32 - | -LL | fn foo<'c, 'd>(_arg: Box>) {} - | ^ expected 2 lifetime arguments - | -note: associated type defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/missing_lifetime_args.rs:2:10 - | -LL | type Y<'a, 'b>; - | ^ -- -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime arguments - | -LL | fn foo<'c, 'd>(_arg: Box = (&'c u32, &'d u32)>>) {} - | ++++++++ - -error[E0107]: missing generics for associated type `X::Y` - --> $DIR/missing_lifetime_args.rs:11:32 - | -LL | fn foo<'c, 'd>(_arg: Box>) {} - | ^ expected 2 lifetime arguments - | -note: associated type defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/missing_lifetime_args.rs:2:10 - | -LL | type Y<'a, 'b>; - | ^ -- -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime arguments - | -LL | fn foo<'c, 'd>(_arg: Box = (&'c u32, &'d u32)>>) {} - | ++++++++ - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/missing_lifetime_args.rs:11:26 - | -LL | fn foo<'c, 'd>(_arg: Box>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/missing_lifetime_args.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a, 'b>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - error[E0107]: struct takes 3 lifetime arguments but 2 lifetime arguments were supplied - --> $DIR/missing_lifetime_args.rs:17:26 + --> $DIR/missing_lifetime_args.rs:14:26 | LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {} | ^^^ -- -- supplied 2 lifetime arguments @@ -83,7 +33,7 @@ LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {} | ++++ error[E0107]: struct takes 3 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/missing_lifetime_args.rs:20:16 + --> $DIR/missing_lifetime_args.rs:17:16 | LL | fn f<'a>(_arg: Foo<'a>) {} | ^^^ -- supplied 1 lifetime argument @@ -100,7 +50,6 @@ help: add missing lifetime arguments LL | fn f<'a>(_arg: Foo<'a, 'a, 'a>) {} | ++++++++ -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs index c828691bb3058..c58f9cf1dfc8e 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs @@ -6,11 +6,6 @@ const _: () = { fn f2<'a>(arg : Box = &'a ()>>) {} //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR associated type takes 0 generic arguments but 1 generic argument - //~| ERROR the trait `X` is not dyn compatible }; fn main() {} diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr index 45bca1a76287d..682fa27ab5d65 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr @@ -28,87 +28,6 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ -- - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add missing lifetime argument - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | +++ - -error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/trait-path-type-error-once-implemented.rs:6:29 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^--- help: remove the unnecessary generics - | | - | expected 0 generic arguments - | -note: associated type defined here, with 0 generic parameters - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | type Y<'a>; - | ^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0038]: the trait `X` is not dyn compatible - --> $DIR/trait-path-type-error-once-implemented.rs:6:23 - | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/trait-path-type-error-once-implemented.rs:2:10 - | -LL | trait X { - | - this trait is not dyn compatible... -LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` - = help: consider moving `Y` to another trait - -error: aborting due to 7 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 33884617acbf8..07ff3d3c0e3ee 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -8,8 +8,6 @@ static FOO: (dyn AsRef, u8) = ("hello", 42); const BAR: (&Path, [u8], usize) = ("hello", [], 42); //~^ ERROR cannot find type `Path` in this scope -//~| ERROR the size for values of type `[u8]` cannot be known at compilation time -//~| ERROR the size for values of type `[u8]` cannot be known at compilation time //~| ERROR mismatched types static BAZ: ([u8], usize) = ([], 0); diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 62a6ae341fa6e..08acc3d3b2579 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -21,16 +21,7 @@ LL + use std::path::Path; | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:9:12 - | -LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); - | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: only the last element of a tuple may have a dynamically sized type - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:15:13 + --> $DIR/issue-84108.rs:13:13 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -38,16 +29,6 @@ LL | static BAZ: ([u8], usize) = ([], 0); = help: the trait `Sized` is not implemented for `[u8]` = note: only the last element of a tuple may have a dynamically sized type -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:9:12 - | -LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); - | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: only the last element of a tuple may have a dynamically sized type - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0308]: mismatched types --> $DIR/issue-84108.rs:9:45 | @@ -57,7 +38,7 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); = note: expected slice `[u8]` found array `[_; 0]` -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout b/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout deleted file mode 100644 index 8643722158985..0000000000000 --- a/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout +++ /dev/null @@ -1 +0,0 @@ -("Hello", 1) [(("Hello", 1),)] "Hello" "Hello" "Hello" ("Hello", 1) ("Hello", 1) ("Hello", 1) diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.rs b/tests/ui/lifetimes/temporary-lifetime-extension.rs index 86c478af317c9..d101aa476d060 100644 --- a/tests/ui/lifetimes/temporary-lifetime-extension.rs +++ b/tests/ui/lifetimes/temporary-lifetime-extension.rs @@ -12,9 +12,7 @@ //@ run-pass //@ check-run-results -//@ revisions: edition2021 edition2024 -//@ [edition2021] edition: 2021 -//@ [edition2024] edition: 2024 +//@ edition: 2015.. fn temp() -> (String, i32) { (String::from("Hello"), 1) diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout b/tests/ui/lifetimes/temporary-lifetime-extension.run.stdout similarity index 100% rename from tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout rename to tests/ui/lifetimes/temporary-lifetime-extension.run.stdout diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index fe336766891da..84e2f4c94386d 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -18,7 +18,5 @@ impl Overlap for T {} impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} //~^ ERROR cannot find type `Missing` in this scope -//~| ERROR the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied -//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index ce4f742a3fa97..e934c5cdc7494 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,30 +26,7 @@ LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a)), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. } -error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied - --> $DIR/issue-118950-root-region.rs:19:9 - | -LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T` - | -help: this trait has no implementations, consider adding one - --> $DIR/issue-118950-root-region.rs:8:1 - | -LL | trait ToUnit<'a> { - | ^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied - --> $DIR/issue-118950-root-region.rs:19:47 - | -LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^ the trait `Overlap fn(Assoc<'a, T>)>` is not implemented for `T` - | -help: consider further restricting type parameter `T` with trait `Overlap` - | -LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap, T: Overlap fn(Assoc<'a, T>)> {} - | ++++++++++++++++++++++++++++++++++++++ - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs index b801e2355404c..afd8aba51ce94 100644 --- a/tests/ui/transmutability/issue-101739-1.rs +++ b/tests/ui/transmutability/issue-101739-1.rs @@ -6,7 +6,6 @@ mod assert { pub fn is_transmutable() where Dst: TransmuteFrom, //~ ERROR cannot find type `Dst` in this scope - //~| ERROR the constant `ASSUME_ALIGNMENT` is not of type `Assume` { } } diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index b3c640a00b4c4..20bc8af47f8d9 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -4,15 +4,6 @@ error[E0412]: cannot find type `Dst` in this scope LL | Dst: TransmuteFrom, | ^^^ not found in this scope -error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` - --> $DIR/issue-101739-1.rs:8:14 - | -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` - | -note: required by a const generic parameter in `TransmuteFrom` - --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0412`.