diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md index 0e0fdc5ca864e..e4bdcd212f381 100644 --- a/.github/ISSUE_TEMPLATE/tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/tracking_issue.md @@ -1,6 +1,6 @@ --- name: Tracking Issue -about: A tracking issue for an accepted feature or RFC in Rust. +about: A tracking issue for an unstable feature in Rust. title: Tracking Issue for XXX labels: C-tracking-issue --- @@ -8,19 +8,27 @@ labels: C-tracking-issue NOTE: For library features, please use the "Library Tracking Issue" template instead. Thank you for creating a tracking issue! 📜 Tracking issues are for tracking a -feature from implementation to stabilisation. Make sure to include the relevant -RFC for the feature if it has one. Otherwise provide a short summary of the -feature and link any relevant PRs or issues, and remove any sections that are -not relevant to the feature. +feature from implementation to stabilisation. Remember to add team labels to the tracking issue. -For a language team feature, this would e.g., be `T-lang`. +For a language team feature, this would e.g., be `T-lang`: + +> @rustbot label T-lang + Such a feature should also be labeled with e.g., `F-my_feature`. This label is used to associate issues (e.g., bugs and design questions) to the feature. --> -This is a tracking issue for the RFC "XXX" (rust-lang/rfcs#NNN). -The feature gate for the issue is `#![feature(FFF)]`. +This is a tracking issue for `#![feature(FFF)]`. +The RFC for this feature is rust-lang/rfcs#NNN. + + ### About tracking issues @@ -38,8 +46,8 @@ implementing a feature, followed by a PR that stabilises the feature. However for larger features an implementation could be broken up into multiple PRs. --> -- [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring - instructions?) +- [ ] Create the feature gate +- [ ] Implement the feature - [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) - [ ] Style updates for any new syntax ([nightly-style-procedure]) - [ ] Style team decision on new formatting @@ -59,8 +67,8 @@ stabilised. It is useful to link related discussions and conculsions as they develop. --> -- [ ] list all the "unresolved questions" found in the RFC to ensure they are - not forgotten. +- [ ] List any unresolved questions, including those listed in the RFC if there is one, + to ensure they are not forgotten. ### Implementation history diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 45fa1863e715f..1176d6e1398f0 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -5,6 +5,7 @@ use rustc_attr_parsing::AttributeParser; use rustc_errors::msg; use rustc_feature::{DependentFeature, Features}; use rustc_session::Session; +use rustc_session::config::NextSolverConfig; use rustc_session::diagnostics::{feature_err, feature_warn}; use rustc_span::{Span, Spanned, sym}; @@ -698,7 +699,7 @@ fn check_dependent_features(sess: &Session, features: &Features) { } fn warn_next_solver_and_gce(sess: &Session, features: &Features) { - if !sess.opts.unstable_opts.next_solver.globally { + if sess.opts.unstable_opts.next_solver != NextSolverConfig::Globally { return; } @@ -716,7 +717,7 @@ fn warn_next_solver_and_gce(sess: &Session, features: &Features) { } fn check_features_requiring_new_solver(sess: &Session, features: &Features) { - if sess.opts.unstable_opts.next_solver.globally { + if sess.opts.unstable_opts.next_solver == NextSolverConfig::Globally { return; } diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 0bece36c64ed0..0df2e9b5fd0ae 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -91,9 +91,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { self.project_downcast_named(&field_dest, sym::Slice)?; variant } - ty::Adt(adt_def, generics) => { - self.write_adt_type_info(&field_dest, (ty, *adt_def), generics)? - } + ty::Adt(adt_def, _) => self.write_adt_type_info(&field_dest, *adt_def)?, ty::Bool => { let (variant, _variant_place) = self.project_downcast_named(&field_dest, sym::Bool)?; diff --git a/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs index 281d7b0a921ba..4ff1b37e953d4 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs @@ -1,13 +1,12 @@ use rustc_abi::{FieldIdx, VariantIdx}; -use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{ - AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty, VariantDef, + AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty, }; use rustc_span::{bug, span_bug, sym}; use crate::const_eval::CompileTimeMachine; use crate::interpret::{ - CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Scalar, Writeable, interp_ok, + CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Writeable, interp_ok, }; impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { @@ -15,190 +14,25 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { pub(crate) fn write_adt_type_info( &mut self, place: &impl Writeable<'tcx, CtfeProvenance>, - adt: (Ty<'tcx>, AdtDef<'tcx>), - generics: &'tcx GenericArgs<'tcx>, + adt_def: AdtDef<'tcx>, ) -> InterpResult<'tcx, VariantIdx> { - let (adt_ty, adt_def) = adt; let variant_idx = match adt_def.adt_kind() { AdtKind::Struct => { - let (variant, variant_place) = self.project_downcast_named(place, sym::Struct)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_struct_type_info( - place, - (adt_ty, adt_def.variant(VariantIdx::ZERO)), - generics, - )?; + let (variant, _) = self.project_downcast_named(place, sym::Struct)?; variant } AdtKind::Union => { - let (variant, variant_place) = self.project_downcast_named(place, sym::Union)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_union_type_info( - place, - (adt_ty, adt_def.variant(VariantIdx::ZERO)), - generics, - )?; + let (variant, _) = self.project_downcast_named(place, sym::Union)?; variant } AdtKind::Enum => { - let (variant, variant_place) = self.project_downcast_named(place, sym::Enum)?; - let place = self.project_field(&variant_place, FieldIdx::ZERO)?; - self.write_enum_type_info(place, adt, generics)?; + let (variant, _) = self.project_downcast_named(place, sym::Enum)?; variant } }; interp_ok(variant_idx) } - pub(crate) fn write_struct_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - struct_: (Ty<'tcx>, &'tcx VariantDef), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (struct_ty, struct_def) = struct_; - let struct_layout = self.layout_of(struct_ty)?; - - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - sym::generics => self.write_generics(&field_place, generics)?, - sym::fields => { - self.write_variant_fields(field_place, struct_def, struct_layout, generics)? - } - sym::non_exhaustive => { - let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - - pub(crate) fn write_union_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - union_: (Ty<'tcx>, &'tcx VariantDef), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (union_ty, union_def) = union_; - let union_layout = self.layout_of(union_ty)?; - - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - sym::generics => self.write_generics(&field_place, generics)?, - sym::fields => { - self.write_variant_fields(field_place, union_def, union_layout, generics)? - } - sym::non_exhaustive => { - let is_non_exhaustive = union_def.is_field_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - - pub(crate) fn write_enum_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - enum_: (Ty<'tcx>, AdtDef<'tcx>), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (enum_ty, enum_def) = enum_; - let enum_layout = self.layout_of(enum_ty)?; - - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - sym::generics => self.write_generics(&field_place, generics)?, - sym::type_id_variants => { - self.allocate_fill_and_write_slice_ptr( - &field_place, - enum_def.variants().len() as u64, - |this, i, place| { - let variant_idx = VariantIdx::from_usize(i as usize); - let variant_def = &enum_def.variants()[variant_idx]; - let variant_layout = enum_layout.for_variant(this, variant_idx); - this.write_enum_variant(place, (variant_layout, &variant_def), generics) - }, - )?; - } - sym::non_exhaustive => { - let is_non_exhaustive = enum_def.is_variant_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - - fn write_enum_variant( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - variant: (TyAndLayout<'tcx>, &'tcx VariantDef), - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - let (variant_layout, variant_def) = variant; - - for (field_idx, field_def) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - match field_def.name { - sym::name => { - let name_place = self.allocate_str_dedup(variant_def.name.as_str())?; - let ptr = self.mplace_to_imm_ptr(&name_place, None)?; - self.write_immediate(*ptr, &field_place)? - } - sym::fields => { - self.write_variant_fields(field_place, &variant_def, variant_layout, generics)? - } - sym::non_exhaustive => { - let is_non_exhaustive = variant_def.is_field_list_non_exhaustive(); - self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? - } - other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), - } - } - interp_ok(()) - } - - // Write fields for struct, enum variants - fn write_variant_fields( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - variant_def: &'tcx VariantDef, - variant_layout: TyAndLayout<'tcx>, - generics: &'tcx GenericArgs<'tcx>, - ) -> InterpResult<'tcx> { - self.allocate_fill_and_write_slice_ptr( - &place, - variant_def.fields.len() as u64, - |this, i, place| { - let field_def = &variant_def.fields[FieldIdx::from_usize(i as usize)]; - let field_ty = field_def.ty(*this.tcx, generics).skip_norm_wip(); - this.write_field(field_ty, place, variant_layout, Some(field_def.name), i) - }, - ) - } - pub(super) fn write_generics( &mut self, place: &impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 496994096d69b..d2c3a08eb714f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -321,7 +321,7 @@ fn orphan_check<'tcx>( // (1) Instantiate all generic params with fresh inference vars. let infcx = tcx .infer_ctxt() - .with_next_trait_solver(tcx.next_trait_solver_in_coherence()) + .with_next_trait_solver(true) .enable_next_solver_overflow_fcw(false) .build(TypingMode::Coherence); let cause = traits::ObligationCause::dummy(); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2f9489ac67ad4..8c241f51dfbfd 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -859,7 +859,7 @@ fn test_unstable_options_tracking_hash() { // tidy-alphabetical-end // FIXME(#160895): We don't test this when the next-solver is enabled by default. if option_env!("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY").is_none() { - tracked!(next_solver, NextSolverConfig { coherence: true, globally: true }); + tracked!(next_solver, NextSolverConfig::Globally); } // tidy-alphabetical-start tracked!(no_generate_arange_section, true); @@ -948,7 +948,7 @@ fn test_edition_parsing() { #[test] fn test_assumptions_on_binders_enables_next_solver_globally() { - let globally = NextSolverConfig { coherence: true, globally: true }; + let globally = NextSolverConfig::Globally; let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); // `-Zassumptions-on-binders` alone enables the next solver globally. @@ -957,18 +957,6 @@ fn test_assumptions_on_binders_enables_next_solver_globally() { assert!(opts.unstable_opts.assumptions_on_binders); assert_eq!(opts.unstable_opts.next_solver, globally); - // Flag order must not matter when both `-Zassumptions-on-binders` and `-Znext-solver` - // are present. - for args in [ - ["-Zassumptions-on-binders".to_string(), "-Znext-solver=coherence".to_string()], - ["-Znext-solver=coherence".to_string(), "-Zassumptions-on-binders".to_string()], - ] { - let matches = optgroups().parse(&args).unwrap(); - let opts = build_session_options(&mut early_dcx, &matches); - assert!(opts.unstable_opts.assumptions_on_binders); - assert_eq!(opts.unstable_opts.next_solver, globally); - } - // `-Zassumptions-on-binders` overrides `-Znext-solver=no` regardless of order, since // the assumptions implementation requires the next solver. This also emits an early // warning (covered by the UI test `next-solver-no-overridden`). diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9062cc3125413..aa7fe0872f20c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -40,6 +40,7 @@ use rustc_index::IndexVec; use rustc_lint_defs::Lint; use rustc_lint_defs::builtin::UNUSED_FEATURES; use rustc_macros::Diagnostic; +use rustc_session::config::NextSolverConfig; use rustc_session::{IncrCompSession, Session}; use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym}; @@ -2816,11 +2817,8 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn next_trait_solver_globally(self) -> bool { - self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs() - } - - pub fn next_trait_solver_in_coherence(self) -> bool { - self.sess.opts.unstable_opts.next_solver.coherence + self.sess.opts.unstable_opts.next_solver == NextSolverConfig::Globally + && !self.features().generic_const_exprs() } pub fn disable_trait_solver_fast_paths(self) -> bool { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 798dcaf969965..8c9cfd76e08fb 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1037,13 +1037,11 @@ impl ExternEntry { } } +/// Where the new trait solver should be enabled only in coherence or everywhere. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct NextSolverConfig { - /// Whether the new trait solver should be enabled in coherence. - pub coherence: bool = true, - /// Whether the new trait solver should be enabled everywhere. - /// This is only `true` if `coherence` is also enabled. - pub globally: bool = false, +pub enum NextSolverConfig { + Coherence, + Globally, } // FIXME(#160895): Using -Znext-solver as default on nightly @@ -1051,9 +1049,9 @@ pub struct NextSolverConfig { impl Default for NextSolverConfig { fn default() -> Self { if option_env!("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY").is_some() { - Self { coherence: true, globally: true } + Self::Globally } else { - Self { coherence: true, globally: false } + Self::Coherence } } } @@ -2715,17 +2713,22 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M // `-Zassumptions-on-binders` requires the next trait solver globally. Normalize after // parsing so the effective config is independent of flag order and so consumers that - // read `next_solver.globally` directly (e.g. feature-gate checks) see the right value. + // read `next_solver` directly (e.g. feature-gate checks) see the right value. if unstable_opts.assumptions_on_binders { - // `NextSolverConfig::default()` has `coherence: true`; the only way `coherence` is - // false here is an explicit `-Znext-solver=no`. - if !unstable_opts.next_solver.coherence { + // Only warn when the last `-Znext-solver` given has a value that doesn't enable + // the solver globally, so a later `-Znext-solver=globally` overrides an earlier one. + let no_next_solver = matches + .opt_strs("Z") + .iter() + .rfind(|arg| arg.starts_with("next-solver")) + .is_some_and(|arg| *arg == "next-solver=no" || *arg == "next-solver=coherence"); + if no_next_solver { early_dcx.early_warn( "-Zassumptions-on-binders unconditionally enables the next trait solver; \ `-Znext-solver=no` is ignored", ); } - unstable_opts.next_solver = NextSolverConfig { coherence: true, globally: true }; + unstable_opts.next_solver = NextSolverConfig::Globally; } if unstable_opts.staticlib_hide_internal_symbols && !crate_types.contains(&CrateType::StaticLib) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 4c153cbb8c031..9a3e74c28348d 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -877,7 +877,7 @@ mod desc { pub(crate) const parse_unpretty: &str = "`string` or `string=string`"; pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; pub(crate) const parse_next_solver_config: &str = - "either `globally` (when used without an argument), `coherence` (default) or `no`"; + "either `globally` (when used without an argument), or `coherence` (default)"; pub(crate) const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub(crate) const parse_linker_plugin_lto: &str = @@ -1795,13 +1795,12 @@ pub mod parse { pub(crate) fn parse_next_solver_config(slot: &mut NextSolverConfig, v: Option<&str>) -> bool { if let Some(config) = v { *slot = match config { - "no" => NextSolverConfig { coherence: false, globally: false }, - "coherence" => NextSolverConfig { coherence: true, globally: false }, - "globally" => NextSolverConfig { coherence: true, globally: true }, + "no" | "coherence" => NextSolverConfig::Coherence, + "globally" => NextSolverConfig::Globally, _ => return false, }; } else { - *slot = NextSolverConfig { coherence: true, globally: true }; + *slot = NextSolverConfig::Globally; } true diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 2ee7dea9f8af3..5272ed2df59b3 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -1062,26 +1062,28 @@ const XTENSA_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ /// /// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator! pub fn all_rust_features() -> impl Iterator { - std::iter::empty() - .chain(ARM_FEATURES) - .chain(AARCH64_FEATURES) - .chain(X86_FEATURES) - .chain(HEXAGON_FEATURES) - .chain(POWERPC_FEATURES) - .chain(MIPS_FEATURES) - .chain(NVPTX_FEATURES) - .chain(RISCV_FEATURES) - .chain(WASM_FEATURES) - .chain(BPF_FEATURES) - .chain(XTENSA_FEATURES) - .chain(CSKY_FEATURES) - .chain(LOONGARCH_FEATURES) - .chain(IBMZ_FEATURES) - .chain(SPARC_FEATURES) - .chain(M68K_FEATURES) - .chain(AVR_FEATURES) - .cloned() - .map(|(f, s, _)| (f, s)) + [ + ARM_FEATURES, + AARCH64_FEATURES, + X86_FEATURES, + HEXAGON_FEATURES, + POWERPC_FEATURES, + MIPS_FEATURES, + NVPTX_FEATURES, + RISCV_FEATURES, + WASM_FEATURES, + BPF_FEATURES, + XTENSA_FEATURES, + CSKY_FEATURES, + LOONGARCH_FEATURES, + IBMZ_FEATURES, + SPARC_FEATURES, + M68K_FEATURES, + AVR_FEATURES, + ] + .into_iter() + .flatten() + .map(|(f, s, _)| (*f, *s)) } /// Find which target architectures a feature belongs to. diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 9a3948f0ac440..9364d65968dd0 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,7 +11,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(unwrap_infallible))] #![feature(associated_type_defaults)] #![feature(default_field_values)] #![feature(deref_patterns)] diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index d3c118b33e8ce..df21f682d7380 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -33,8 +33,7 @@ use crate::solve::{SolverDelegate, deeply_normalize_for_diagnostics, inspect}; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{ - FulfillmentErrorCode, NormalizeExt, Obligation, ObligationCause, PredicateObligation, - SelectionContext, SkipLeakCheck, util, + FulfillmentErrorCode, Obligation, ObligationCause, PredicateObligation, SkipLeakCheck, util, }; /// The "header" of an impl is everything outside the body: a Self type, a trait @@ -79,21 +78,6 @@ pub(crate) fn suggest_increasing_recursion_limit<'tcx>( suggest_new_overflow_limit(tcx, err); } -#[derive(Debug, Clone, Copy)] -enum TrackAmbiguityCauses { - Yes, - No, -} - -impl TrackAmbiguityCauses { - fn is_yes(self) -> bool { - match self { - TrackAmbiguityCauses::Yes => true, - TrackAmbiguityCauses::No => false, - } - } -} - /// If there are types that satisfy both impls, returns `Some` /// with a suitably-freshened `ImplHeader` with those types /// instantiated. Otherwise, returns `None`. @@ -157,42 +141,7 @@ fn overlapping_impls( overlap_mode: OverlapMode, is_of_trait: bool, ) -> Option> { - if tcx.next_trait_solver_in_coherence() { - overlap( - tcx, - TrackAmbiguityCauses::Yes, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - is_of_trait, - ) - } else { - let _overlap_with_bad_diagnostics = overlap( - tcx, - TrackAmbiguityCauses::No, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - is_of_trait, - )?; - - // In the case where we detect an error, run the check again, but - // this time tracking intercrate ambiguity causes for better - // diagnostics. (These take time and can lead to false errors.) - let overlap = overlap( - tcx, - TrackAmbiguityCauses::Yes, - skip_leak_check, - impl1_def_id, - impl2_def_id, - overlap_mode, - is_of_trait, - ) - .unwrap(); - Some(overlap) - } + overlap(tcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode, is_of_trait) } fn fresh_impl_header<'tcx>( @@ -217,27 +166,11 @@ fn fresh_impl_header<'tcx>( } } -fn fresh_impl_header_normalized<'tcx>( - infcx: &InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - impl_def_id: DefId, - is_of_trait: bool, -) -> ImplHeader<'tcx> { - let header = fresh_impl_header(infcx, impl_def_id, is_of_trait); - - let InferOk { value: mut header, obligations } = - infcx.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(header)); - - header.predicates.extend(obligations.into_iter().map(|o| o.predicate)); - header -} - /// Can both impl `a` and impl `b` be satisfied by a common type (including /// where-clauses)? If so, returns an `ImplHeader` that unifies the two impls. #[instrument(level = "debug", skip(tcx))] fn overlap<'tcx>( tcx: TyCtxt<'tcx>, - track_ambiguity_causes: TrackAmbiguityCauses, skip_leak_check: SkipLeakCheck, impl1_def_id: DefId, impl2_def_id: DefId, @@ -260,13 +193,9 @@ fn overlap<'tcx>( let infcx = tcx .infer_ctxt() .skip_leak_check(skip_leak_check.is_yes()) - .with_next_trait_solver(tcx.next_trait_solver_in_coherence()) + .with_next_trait_solver(true) .enable_next_solver_overflow_fcw(false) .build(TypingMode::Coherence); - let selcx = &mut SelectionContext::new(&infcx); - if track_ambiguity_causes.is_yes() { - selcx.enable_tracking_intercrate_ambiguity_causes(); - } // For the purposes of this check, we don't bring any placeholder // types into scope; instead, we replace the generic types with @@ -274,21 +203,12 @@ fn overlap<'tcx>( // empty environment. let param_env = ty::ParamEnv::empty(); - let impl1_header = if tcx.next_trait_solver_in_coherence() { - fresh_impl_header(selcx.infcx, impl1_def_id, is_of_trait) - } else { - fresh_impl_header_normalized(selcx.infcx, param_env, impl1_def_id, is_of_trait) - }; - let impl2_header = if tcx.next_trait_solver_in_coherence() { - fresh_impl_header(selcx.infcx, impl2_def_id, is_of_trait) - } else { - fresh_impl_header_normalized(selcx.infcx, param_env, impl2_def_id, is_of_trait) - }; + let impl1_header = fresh_impl_header(&infcx, impl1_def_id, is_of_trait); + let impl2_header = fresh_impl_header(&infcx, impl2_def_id, is_of_trait); // Equate the headers to find their intersection (the general type, with infer vars, // that may apply both impls). - let mut obligations = - equate_impl_headers(selcx.infcx, param_env, &impl1_header, &impl2_header)?; + let mut obligations = equate_impl_headers(&infcx, param_env, &impl1_header, &impl2_header)?; debug!("overlap: unification check succeeded"); obligations.extend( @@ -299,7 +219,7 @@ fn overlap<'tcx>( let mut overflowing_predicates = Vec::new(); if overlap_mode.use_implicit_negative() { - match impl_intersection_has_impossible_obligation(selcx, &obligations) { + match impl_intersection_has_impossible_obligation(&infcx, &obligations) { IntersectionHasImpossibleObligations::Yes => return None, IntersectionHasImpossibleObligations::No { overflowing_predicates: p } => { overflowing_predicates = p @@ -316,10 +236,8 @@ fn overlap<'tcx>( let intercrate_ambiguity_causes = if !overlap_mode.use_implicit_negative() { Default::default() - } else if infcx.next_trait_solver() { - compute_intercrate_ambiguity_causes(&infcx, &obligations) } else { - selcx.take_intercrate_ambiguity_causes() + compute_intercrate_ambiguity_causes(&infcx, &obligations) }; debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes); @@ -335,9 +253,7 @@ fn overlap<'tcx>( let mut impl_header = infcx.deeply_resolve_ignoring_regions(impl1_header); // Deeply normalize the impl header for diagnostics, ignoring any errors if this fails. - if infcx.next_trait_solver() { - impl_header = deeply_normalize_for_diagnostics(&infcx, param_env, impl_header); - } + impl_header = deeply_normalize_for_diagnostics(&infcx, param_env, impl_header); Some(OverlapResult { impl_header, @@ -375,7 +291,7 @@ fn equate_impl_headers<'tcx>( enum IntersectionHasImpossibleObligations<'tcx> { Yes, No { - /// With `-Znext-solver=coherence`, some obligations may + /// With the next solver, some obligations may /// fail if only the user increased the recursion limit. /// /// We return those obligations here and mention them in the @@ -402,78 +318,53 @@ enum IntersectionHasImpossibleObligations<'tcx> { /// of the two impls above to be empty. /// /// Importantly, this works even if there isn't a `impl !Error for MyLocalType`. -#[instrument(level = "debug", skip(selcx), ret)] -fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'tcx>, +#[instrument(level = "debug", skip(infcx), ret)] +fn impl_intersection_has_impossible_obligation<'a, 'tcx>( + infcx: &InferCtxt<'tcx>, obligations: &'a [PredicateObligation<'tcx>], ) -> IntersectionHasImpossibleObligations<'tcx> { - let infcx = selcx.infcx; - - if infcx.next_trait_solver() { - // A fast path optimization, try evaluating all goals with - // a very low recursion depth and bail if any of them don't - // hold. - if !obligations.iter().all(|o| { - <&SolverDelegate<'tcx>>::from(infcx) - .root_goal_may_hold_with_depth(8, Goal::new(infcx.tcx, o.param_env, o.predicate)) - }) { - return IntersectionHasImpossibleObligations::Yes; - } - - let ocx = ObligationCtxt::new(infcx); - ocx.register_obligations(obligations.iter().cloned()); - let hard_errors = ocx.try_evaluate_obligations(); - if let TraitErrors::HasErrors(hard_errors) = hard_errors { - assert!( - hard_errors.iter().all(|e| e.is_true_error()), - "should not have detected ambiguity during first pass" - ); - return IntersectionHasImpossibleObligations::Yes; - } + // A fast path optimization, try evaluating all goals with + // a very low recursion depth and bail if any of them don't + // hold. + if !obligations.iter().all(|o| { + <&SolverDelegate<'tcx>>::from(infcx) + .root_goal_may_hold_with_depth(8, Goal::new(infcx.tcx, o.param_env, o.predicate)) + }) { + return IntersectionHasImpossibleObligations::Yes; + } - // Make a new `ObligationCtxt` and re-prove the ambiguities with a richer - // `FulfillmentError`. This is so that we can detect overflowing obligations - // without needing to run the `BestObligation` visitor on true errors. - let ambiguities = ocx.into_pending_obligations(); - let ocx = ObligationCtxt::new_with_diagnostics(infcx); - ocx.register_obligations(ambiguities); - let errors_and_ambiguities = ocx.evaluate_obligations_error_on_ambiguity(); - // We only care about the obligations that are *definitely* true errors. - // Ambiguities do not prove the disjointness of two impls. - let (errors, ambiguities): (Vec<_>, Vec<_>) = - errors_and_ambiguities.into_iter().partition(|error| error.is_true_error()); - assert!(errors.is_empty(), "should not have ambiguities during second pass"); - - IntersectionHasImpossibleObligations::No { - overflowing_predicates: ambiguities - .into_iter() - .filter(|error| { - matches!(error.code, FulfillmentErrorCode::Ambiguity { overflow: Some(true) }) - }) - .map(|e| infcx.deeply_resolve_ignoring_regions(e.obligation.predicate)) - .collect(), - } - } else { - for obligation in obligations { - // We use `evaluate_root_obligation` to correctly track intercrate - // ambiguity clauses. - let evaluation_result = selcx.evaluate_root_obligation(obligation); - - match evaluation_result { - Ok(result) => { - if !result.may_apply() { - return IntersectionHasImpossibleObligations::Yes; - } - } - // If overflow occurs, we need to conservatively treat the goal as possibly holding, - // since there can be instantiations of this goal that don't overflow and result in - // success. While this isn't much of a problem in the old solver, since we treat overflow - // fatally, this still can be encountered: . - Err(_overflow) => {} - } - } + let ocx = ObligationCtxt::new(infcx); + ocx.register_obligations(obligations.iter().cloned()); + let hard_errors = ocx.try_evaluate_obligations(); + if let TraitErrors::HasErrors(hard_errors) = hard_errors { + assert!( + hard_errors.iter().all(|e| e.is_true_error()), + "should not have detected ambiguity during first pass" + ); + return IntersectionHasImpossibleObligations::Yes; + } - IntersectionHasImpossibleObligations::No { overflowing_predicates: Vec::new() } + // Make a new `ObligationCtxt` and re-prove the ambiguities with a richer + // `FulfillmentError`. This is so that we can detect overflowing obligations + // without needing to run the `BestObligation` visitor on true errors. + let ambiguities = ocx.into_pending_obligations(); + let ocx = ObligationCtxt::new_with_diagnostics(infcx); + ocx.register_obligations(ambiguities); + let errors_and_ambiguities = ocx.evaluate_obligations_error_on_ambiguity(); + // We only care about the obligations that are *definitely* true errors. + // Ambiguities do not prove the disjointness of two impls. + let (errors, ambiguities): (Vec<_>, Vec<_>) = + errors_and_ambiguities.into_iter().partition(|error| error.is_true_error()); + assert!(errors.is_empty(), "should not have ambiguities during second pass"); + + IntersectionHasImpossibleObligations::No { + overflowing_predicates: ambiguities + .into_iter() + .filter(|error| { + matches!(error.code, FulfillmentErrorCode::Ambiguity { overflow: Some(true) }) + }) + .map(|e| infcx.deeply_resolve_ignoring_regions(e.obligation.predicate)) + .collect(), } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index aae323ae1671f..83f1fcd756981 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -176,12 +176,14 @@ where TypingMode::Typeck { defining_opaque_types_and_generators } => { defining_opaque_types_and_generators } - TypingMode::Coherence - | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } + TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } | TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => return Default::default(), + TypingMode::Coherence => { + unreachable!("old solver coherence") + } }; if stalled_coroutines.is_empty() { @@ -872,8 +874,9 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { trait_obligation: PolyTraitObligation<'tcx>, stalled_on: &mut Vec, ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { + debug_assert!(!self.selcx.typing_mode().is_coherence(), "old solver coherence"); let infcx = self.selcx.infcx; - if obligation.predicate.is_global() && !self.selcx.typing_mode().is_coherence() { + if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. if infcx.predicate_must_hold_considering_regions(obligation) { @@ -925,9 +928,11 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { project_obligation: PolyProjectionObligation<'tcx>, stalled_on: &mut Vec, ) -> ProcessResult, FulfillmentErrorCode<'tcx>> { + debug_assert!(!self.selcx.typing_mode().is_coherence(), "old solver coherence"); + let tcx = self.selcx.tcx(); let infcx = self.selcx.infcx; - if obligation.predicate.is_global() && !self.selcx.typing_mode().is_coherence() { + if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. if infcx.predicate_must_hold_considering_regions(obligation) { diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 5a66fafd57361..63f7c6dfc94fc 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -139,11 +139,13 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( // so we can ignore those. match infcx.typing_mode_raw().assert_not_erased() { // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => {} + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } value.has_type_flags(flags) @@ -426,8 +428,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.selcx.typing_mode() { // FIXME(#132279): We likely want to reveal opaques during post borrowck analysis - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => ty.super_fold_with(self), TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => { @@ -449,6 +450,9 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx self.depth -= 1; folded_ty } + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6f7c46089632f..6cea4a9300824 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1034,8 +1034,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. match selcx.typing_mode() { - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::Reflection | TypingMode::PostBorrowck { .. } => { @@ -1053,6 +1052,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( selcx.infcx.deeply_resolve_ignoring_regions(trait_ref); !poly_trait_ref.still_further_specializable() } + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 782697782f94c..b4dffab26d1e4 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -231,8 +231,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { ty::Opaque { def_id } => { // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.infcx.typing_mode_raw().assert_not_erased() { - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => ty.try_super_fold_with(self)?, @@ -268,6 +267,9 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { self.anon_depth -= 1; folded_ty? } + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 9ebfb4d5ecda0..7228c55b404b4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -845,6 +845,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) => { + debug_assert!(!self.typing_mode().is_coherence(), "old solver coherence"); + if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate { .. })) { // We do not generate an auto impl candidate for `impl Trait`s which already // reference our auto trait. @@ -855,10 +857,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // Note that this is only sound as projection candidates of opaque types // are always applicable for auto traits. - } else if self.typing_mode().is_coherence() { - // We do not emit auto trait candidates for opaque types in coherence. - // Doing so can result in weird dependency cycles. - candidates.ambiguous = true; } else if self.infcx.can_define_opaque_ty(def_id) { // We do not emit auto trait candidates for opaque types in their defining scope, as // we need to know the hidden type first, which we can't reliably know within the defining diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4846d75339cd6..05b4ba6a7180c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -35,7 +35,6 @@ use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; use self::SelectionCandidate::*; -use super::coherence::{self, Conflict}; use super::project::ProjectionTermObligation; use super::util::closure_trait_ref_and_return_type; use super::{ @@ -106,14 +105,6 @@ pub struct SelectionContext<'cx, 'tcx> { /// require themselves. freshener: TypeFreshener<'cx, 'tcx>, - /// If `intercrate` is set, we remember predicates which were - /// considered ambiguous because of impls potentially added in other crates. - /// This is used in coherence to give improved diagnostics. - /// We don't do his until we detect a coherence error because it can - /// lead to false overflow results (#47139) and because always - /// computing it may negatively impact performance. - intercrate_ambiguity_causes: Option>>, - /// The mode that trait queries run in, which informs our error handling /// policy. In essence, canonicalized queries need their errors propagated /// rather than immediately reported because we do not have accurate spans. @@ -191,7 +182,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, freshener: TypeFreshener::new(infcx), - intercrate_ambiguity_causes: None, query_mode: TraitQueryMode::Standard, } } @@ -208,27 +198,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { SelectionContext { query_mode, ..SelectionContext::new(infcx) } } - /// Enables tracking of intercrate ambiguity causes. See - /// the documentation of [`Self::intercrate_ambiguity_causes`] for more. - pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { - assert!(self.typing_mode().is_coherence()); - assert!(self.intercrate_ambiguity_causes.is_none()); - - self.intercrate_ambiguity_causes = Some(FxIndexSet::default()); - debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); - } - - /// Gets the intercrate ambiguity causes collected since tracking - /// was enabled and disables tracking at the same time. If - /// tracking is not enabled, just returns an empty vector. - pub fn take_intercrate_ambiguity_causes( - &mut self, - ) -> FxIndexSet> { - assert!(self.typing_mode().is_coherence()); - - self.intercrate_ambiguity_causes.take().unwrap_or_default() - } - pub fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -363,42 +332,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - if let Err(conflict) = self.is_knowable(stack) { - debug!("coherence stage: not knowable"); - if self.intercrate_ambiguity_causes.is_some() { - debug!("evaluate_stack: intercrate_ambiguity_causes is some"); - // Heuristics: show the diagnostics when there are no candidates in crate. - if let Ok(candidate_set) = self.assemble_candidates(stack) { - let mut no_candidates_apply = true; - - for c in candidate_set.vec.iter() { - if self.evaluate_candidate(stack, c)?.may_apply() { - no_candidates_apply = false; - break; - } - } - - if !candidate_set.ambiguous && no_candidates_apply { - let trait_ref = self.infcx.deeply_resolve_ignoring_regions( - stack.obligation.predicate.skip_binder().trait_ref, - ); - if !trait_ref.references_error() { - let self_ty = trait_ref.self_ty(); - let self_ty = self_ty.has_concrete_skeleton().then(|| self_ty); - let cause = if let Conflict::Upstream = conflict { - IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_ref, self_ty } - } else { - IntercrateAmbiguityCause::DownstreamCrate { trait_ref, self_ty } - }; - debug!(?cause, "evaluate_stack: pushing cause"); - self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); - } - } - } - } - return Ok(None); - } - let candidate_set = self.assemble_candidates(stack)?; if candidate_set.ambiguous { @@ -1000,8 +933,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: PolyTraitObligation<'tcx>, ) -> Result { - if !self.typing_mode().is_coherence() - && obligation.is_global() + debug_assert!(!self.typing_mode().is_coherence(), "old solver coherence"); + + if obligation.is_global() && obligation.param_env.caller_bounds().all(|bound| bound.has_param()) { // If a param env has no global bounds, global obligations do not @@ -1432,30 +1366,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates } - fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { - let obligation = &stack.obligation; - match self.typing_mode() { - TypingMode::Coherence => {} - TypingMode::Typeck { .. } - | TypingMode::PostTypeckUntilBorrowck { .. } - | TypingMode::Reflection - | TypingMode::PostBorrowck { .. } - | TypingMode::PostAnalysis - | TypingMode::Codegen => return Ok(()), - } - - debug!("is_knowable()"); - - let predicate = self.infcx.deeply_resolve_ignoring_regions(obligation.predicate); - - // Okay to skip binder because of the nature of the - // trait-ref-is-knowable check, which does not care about - // bound regions. - let trait_ref = predicate.skip_binder().trait_ref; - - coherence::trait_ref_is_knowable(self.infcx, trait_ref, |ty| Ok::<_, !>(ty)).into_ok() - } - /// Returns `true` if the global caches can be used. fn can_use_global_caches( &self, @@ -1470,13 +1380,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match self.typing_mode() { - // Avoid using the global cache during coherence and just rely - // on the local cache. It is really just a simplification to - // avoid us having to fear that coherence results "pollute" - // the master cache. Since coherence executes pretty quickly, - // it's not worth going to more trouble to increase the - // hit-rate, I don't think. - TypingMode::Coherence => false, // Avoid using the global cache when we're defining opaque types // as their hidden type may impact the result of candidate selection. // @@ -1502,6 +1405,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // FIXME(#132279): This is still incorrect as we treat opaque types // and default associated items differently between these two modes. TypingMode::PostAnalysis | TypingMode::Codegen => true, + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } @@ -2528,14 +2434,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> { return Err(()); } - TypingMode::Coherence - | TypingMode::Typeck { .. } + TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } | TypingMode::Codegen | TypingMode::ErasedNotCoherence(_) | TypingMode::Reflection | TypingMode::PostAnalysis => {} + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } Ok(Normalized { value: impl_args, obligations: nested_obligations }) @@ -2876,12 +2784,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> { TypingMode::Typeck { defining_opaque_types_and_generators: stalled_generators } => { def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) } - TypingMode::Coherence - | TypingMode::PostAnalysis + TypingMode::PostAnalysis | TypingMode::Reflection | TypingMode::Codegen | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } => false, + TypingMode::Coherence => { + unreachable!("old solver coherence") + } } } } diff --git a/library/core/src/attribute_docs.rs b/library/core/src/attribute_docs.rs index 9a70ea74345be..b04c441e8f1d7 100644 --- a/library/core/src/attribute_docs.rs +++ b/library/core/src/attribute_docs.rs @@ -406,6 +406,104 @@ const _: () = (); /// [the `no_std` attribute]: ../reference/names/preludes.html#the-no_std-attribute const _: () = (); +#[doc(attribute = "no_main")] +/// Prevents emitting the `main` entrypoint symbol. +/// +/// Written as an inner attribute at the top of the crate root, the `no_main` attribute prevents +/// the compiler from generating the program's standard Rust entrypoint, leaving that up to you. +/// This is useful when some other object being linked into the program defines the entrypoint, +/// or when you want to define the platform's `main` symbol yourself. +/// +/// If you define an entry point symbol that is suitable for your target, it must also be exported +/// under an unmangled name using the [`no_mangle` attribute]: +/// +/// ```standalone_crate +/// #![no_main] +/// +/// use std::ffi::{c_char, c_int}; +/// +/// #[unsafe(no_mangle)] +/// pub extern "C" fn main(_argc: c_int, _argv: *const *const c_char) -> c_int { +/// println!("Hello world!"); +/// 0 +/// } +/// ``` +/// +/// Unlike `no_std`, the `no_main` attribute does not prevent the compiler from generating +/// the startup routine or linking the standard library provided by the operating system's executable [ABI]. +/// +/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface +/// [`no_mangle` attribute]: ../reference/abi.html#the-no_mangle-attribute +const _: () = (); + +#[doc(attribute = "repr")] +/// Specifies the [representation] of a type. +/// +/// Written as an outer attribute on a `struct`, `enum` or `union`, `repr` controls how the +/// type is laid out in memory. This is needed when passing types across an [FFI] boundary +/// or whenever you rely on a specific layout. +/// +/// The available representations are: +/// +/// * [`Rust`] (the default): the layout is unspecified and may change between compilations. +/// * [`C`]: the layout follows the rules of the C language for the target platform. +/// * The [primitive representations] (`u8`, `i32`, `usize`, ...): set the discriminant +/// type of an enum. +/// * [`transparent`]: the type has the same layout and ABI as its only non-zero-sized field. +/// +/// The `align(N)` and `packed(N)` modifiers raise or lower the alignment of a type, respectively. +/// `N` must be a power of two no greater than 229. The two modifiers cannot be +/// applied to the same type, and references to fields of a `packed` type cannot be created, +/// since they may be unaligned. +/// +/// # Examples +/// +/// ``` +/// #[repr(C, align(16))] +/// struct Foo { +/// first: u32, +/// second: u32, +/// third: u32, +/// } +/// +/// assert_eq!(align_of::(), 16); +/// // 12 bytes of fields, rounded up to a multiple of the alignment. +/// assert_eq!(size_of::(), 16); +/// ``` +/// +/// ``` +/// #[repr(C, packed(2))] +/// struct Foo { +/// first: u32, +/// second: u32, +/// third: u32, +/// } +/// +/// assert_eq!(align_of::(), 2); +/// assert_eq!(size_of::(), 12); +/// ``` +/// +/// ``` +/// #[repr(C)] +/// struct Foo { +/// item: T, +/// } +/// ``` +/// +/// `Foo` is laid out according to the C rules and is guaranteed to be 16-byte aligned. +/// +/// The representation is a property of the type definition, so it does +/// parameters: below, `Foo` and `Foo` both use the `C` representation. Their actual +/// layouts still differ, because they depend on `T`. +/// +/// [representation]: ../reference/type-layout.html#representations +/// [`Rust`]: ../reference/type-layout.html#the-rust-representation +/// [`C`]: ../reference/type-layout.html#the-c-representation +/// [primitive representations]: ../reference/type-layout.html#primitive-representations +/// [`transparent`]: ../reference/type-layout.html#the-transparent-representation +/// [FFI]: https://en.wikipedia.org/wiki/Foreign_function_interface +const _: () = (); + #[doc(attribute = "inline")] // /// Suggest that the compiler inline a function at its call sites. diff --git a/library/core/src/io/error/os_functions.rs b/library/core/src/io/error/os_functions.rs index b34b7c7dc7926..fcc549f0fb643 100644 --- a/library/core/src/io/error/os_functions.rs +++ b/library/core/src/io/error/os_functions.rs @@ -6,7 +6,7 @@ use crate::fmt; /// The provided reference must point to data that is entirely constant; it must /// not be created during runtime. #[inline] -pub(super) unsafe fn set_functions(f: &'static OsFunctions) { +pub(super) unsafe fn set_functions(_f: &'static OsFunctions) { // FIXME: externally implementable items may allow for weak linkage, allowing // these methods to be overridden even when atomic pointers are not supported. } diff --git a/tests/codegen-llvm/sparc-struct-abi.rs b/tests/codegen-llvm/sparc-struct-abi.rs index 6a31fe0d37f15..f79814e4bb4f1 100644 --- a/tests/codegen-llvm/sparc-struct-abi.rs +++ b/tests/codegen-llvm/sparc-struct-abi.rs @@ -29,7 +29,7 @@ pub struct BoolFloat { f: f32, } -// CHECK: define inreg { i32, float } @structboolfloat() +// CHECK: define inreg{{( noundef)?}} { i32, float } @structboolfloat() // CHECK-NEXT: start: // CHECK-NEXT: ret { i32, float } { i32 16777216, float {{0x40091EB860000000|3.140000e\+00}} } #[no_mangle] @@ -48,7 +48,7 @@ pub struct ShortDouble { d: f64, } -// CHECK: define { i64, double } @structshortdouble() +// CHECK: define{{( noundef)?}} { i64, double } @structshortdouble() // CHECK-NEXT: start: // CHECK-NEXT: ret { i64, double } { i64 34621422135410688, double 3.140000e+00 } #[no_mangle] @@ -88,7 +88,7 @@ pub struct NestedStructs { b: FloatFloat, } -// CHECK: define inreg { float, float, float, float } @structnestestructs() +// CHECK: define inreg{{( noundef)?}} { float, float, float, float } @structnestestructs() // CHECK-NEXT: start: // CHECK-NEXT: ret { float, float, float, float } { float {{0x3FB99999A0000000|1.000000e-01}}, float {{0x3FF19999A0000000|1.100000e\+00}}, float {{0x40019999A0000000|2.200000e\+00}}, float {{0x400A666660000000|3.300000e\+00}} } #[no_mangle] diff --git a/tests/run-make/core-no-io-statics/rmake.rs b/tests/run-make/core-no-io-statics/rmake.rs new file mode 100644 index 0000000000000..0e75dfa8c273c --- /dev/null +++ b/tests/run-make/core-no-io-statics/rmake.rs @@ -0,0 +1,14 @@ +// This test checks that the core library of Rust can be compiled when enabling +// `--cfg no_io_statics`. + +use run_make_support::{rustc, source_root}; + +fn main() { + rustc() + .edition("2024") + .arg("-Dwarnings") + .crate_type("rlib") + .input(source_root().join("library/core/src/lib.rs")) + .cfg("no_io_statics") + .run(); +} diff --git a/tests/ui/assumptions_on_binders/alias_outlives.rs b/tests/ui/assumptions_on_binders/alias_outlives.rs index 0c2ed6585cf45..7dd14da4fd773 100644 --- a/tests/ui/assumptions_on_binders/alias_outlives.rs +++ b/tests/ui/assumptions_on_binders/alias_outlives.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally // test that a `::Assoc: '!a_u1` constraint is considered to be satisfied // if there's a `T::Assoc: 'static` assumption in the root universe and if not that it is diff --git a/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs b/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs index 2f0f2ca8aab85..1d889b8c64362 100644 --- a/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs +++ b/tests/ui/assumptions_on_binders/implied_higher_ranked_alias_outlives_assumption.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally //@ check-pass #![feature(generic_const_items)] diff --git a/tests/ui/assumptions_on_binders/nested-gat-outlives-issue-161067.rs b/tests/ui/assumptions_on_binders/nested-gat-outlives-issue-161067.rs index 937b17e5ec872..4e72f328f73e7 100644 --- a/tests/ui/assumptions_on_binders/nested-gat-outlives-issue-161067.rs +++ b/tests/ui/assumptions_on_binders/nested-gat-outlives-issue-161067.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally //@ needs-rustc-debug-assertions // Regression test for #161067. A nested non-rigid alias must be normalized diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs index 8b0b92b8a7842..b3bc4d6fae25f 100644 --- a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally trait Trait {} diff --git a/tests/ui/assumptions_on_binders/reflexive-outlives-in-root.rs b/tests/ui/assumptions_on_binders/reflexive-outlives-in-root.rs index 641ac3951d76a..fcd436c7df3ed 100644 --- a/tests/ui/assumptions_on_binders/reflexive-outlives-in-root.rs +++ b/tests/ui/assumptions_on_binders/reflexive-outlives-in-root.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![feature(test_binder_constraints, non_lifetime_binders)] #![expect(incomplete_features)] diff --git a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs index ef1a5ca74c546..4c35de2be8759 100644 --- a/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs +++ b/tests/ui/assumptions_on_binders/resolved-region-var-max-universe.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally // Regression test for an ICE in the `MaxUniverse` region visitor. When computing // the max universe of a region constraint, a `ReVar` term could already have been diff --git a/tests/ui/assumptions_on_binders/same-universe-placeholder-outlives.rs b/tests/ui/assumptions_on_binders/same-universe-placeholder-outlives.rs index 6d292416cd4cf..b748dffe34981 100644 --- a/tests/ui/assumptions_on_binders/same-universe-placeholder-outlives.rs +++ b/tests/ui/assumptions_on_binders/same-universe-placeholder-outlives.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![feature(test_binder_constraints, non_lifetime_binders)] #![expect(incomplete_features)] diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs index 97629627ad556..042deefcbb6e5 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![feature(test_binder_constraints)] #![expect(incomplete_features)] diff --git a/tests/ui/assumptions_on_binders/test-infra-works.rs b/tests/ui/assumptions_on_binders/test-infra-works.rs index d8d64d1aac255..b36e16a545bb3 100644 --- a/tests/ui/assumptions_on_binders/test-infra-works.rs +++ b/tests/ui/assumptions_on_binders/test-infra-works.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![feature(test_binder_constraints, non_lifetime_binders)] #![expect(incomplete_features)] diff --git a/tests/ui/assumptions_on_binders/type-outlives-assumptions.rs b/tests/ui/assumptions_on_binders/type-outlives-assumptions.rs index bc3b3a7f2c250..c78231d8ca103 100644 --- a/tests/ui/assumptions_on_binders/type-outlives-assumptions.rs +++ b/tests/ui/assumptions_on_binders/type-outlives-assumptions.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally // Regression test for rust-lang/project-assumptions-on-binders#19, based on the `syn` failure. // The receiver gives us an implied `I: 'b` bound and `'b: 'a` lets that satisfy the object diff --git a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs index fe5753c3c9970..212446a179f00 100644 --- a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs +++ b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-1.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![crate_type = "lib"] diff --git a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs index 78769282a3f4e..0a484d17da542 100644 --- a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs +++ b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-2.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![crate_type = "lib"] diff --git a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs index c1d4d0ed1c79f..6cc175fbce36d 100644 --- a/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs +++ b/tests/ui/assumptions_on_binders/type_relation_binders_inside_solver-3.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: -Zassumptions-on-binders +//@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![crate_type = "lib"] diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs index 29ad935c0149c..9449153060db5 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr index dea81894463b3..21ca0f6e04d97 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr @@ -1,11 +1,11 @@ error[E0425]: cannot find value `x` in this scope - --> $DIR/error_in_ty.rs:6:31 + --> $DIR/error_in_ty.rs:4:31 | LL | pub struct A {} | ^ not found in this scope | note: similarly named const parameter `z` defined here - --> $DIR/error_in_ty.rs:6:20 + --> $DIR/error_in_ty.rs:4:20 | LL | pub struct A {} | ^ @@ -16,7 +16,7 @@ LL + pub struct A {} | error: `[usize; x]` is forbidden as the type of a const generic parameter - --> $DIR/error_in_ty.rs:6:23 + --> $DIR/error_in_ty.rs:4:23 | LL | pub struct A {} | ^^^^^^^^^^ @@ -28,31 +28,31 @@ LL + #![feature(min_adt_const_params)] | error[E0308]: mismatched types - --> $DIR/error_in_ty.rs:10:8 + --> $DIR/error_in_ty.rs:8:8 | LL | impl A<2> { | ^ expected `[usize; x]`, found integer | note: expected because of the type of the const parameter - --> $DIR/error_in_ty.rs:6:14 + --> $DIR/error_in_ty.rs:4:14 | LL | pub struct A {} | ^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/error_in_ty.rs:16:8 + --> $DIR/error_in_ty.rs:14:8 | LL | impl A<2> { | ^ expected `[usize; x]`, found integer | note: expected because of the type of the const parameter - --> $DIR/error_in_ty.rs:6:14 + --> $DIR/error_in_ty.rs:4:14 | LL | pub struct A {} | ^^^^^^^^^^^^^^^^^^^ error[E0592]: duplicate definitions with name `B` - --> $DIR/error_in_ty.rs:12:5 + --> $DIR/error_in_ty.rs:10:5 | LL | pub const fn B() {} | ^^^^^^^^^^^^^^^^ duplicate definitions for `B` diff --git a/tests/ui/error-codes/E0476.old.stderr b/tests/ui/error-codes/E0476.old.stderr deleted file mode 100644 index 454dbecc7d01f..0000000000000 --- a/tests/ui/error-codes/E0476.old.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>` - --> $DIR/E0476.rs:11:1 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl<'a, 'b, T, U> CoerceUnsized<&'a U> for &'b T - where 'b: 'a, T: Unsize, T: ?Sized, U: ?Sized; - -error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type - --> $DIR/E0476.rs:11:1 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: object type is valid for the lifetime `'a` as defined here - --> $DIR/E0476.rs:11:6 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^ -note: source pointer is only valid for the lifetime `'b` as defined here - --> $DIR/E0476.rs:11:10 - | -LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} - | ^^ - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0119, E0476. -For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs index 03656d28b2b99..d5e4b8d237274 100644 --- a/tests/ui/error-codes/E0476.rs +++ b/tests/ui/error-codes/E0476.rs @@ -1,5 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver=coherence #![feature(coerce_unsized)] #![feature(unsize)] diff --git a/tests/ui/error-codes/E0476.next.stderr b/tests/ui/error-codes/E0476.stderr similarity index 92% rename from tests/ui/error-codes/E0476.next.stderr rename to tests/ui/error-codes/E0476.stderr index 454dbecc7d01f..0378ac6e8ec91 100644 --- a/tests/ui/error-codes/E0476.next.stderr +++ b/tests/ui/error-codes/E0476.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>` - --> $DIR/E0476.rs:11:1 + --> $DIR/E0476.rs:9:1 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,18 +9,18 @@ LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S where 'b: 'a, T: Unsize, T: ?Sized, U: ?Sized; error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type - --> $DIR/E0476.rs:11:1 + --> $DIR/E0476.rs:9:1 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: object type is valid for the lifetime `'a` as defined here - --> $DIR/E0476.rs:11:6 + --> $DIR/E0476.rs:9:6 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^ note: source pointer is only valid for the lifetime `'b` as defined here - --> $DIR/E0476.rs:11:10 + --> $DIR/E0476.rs:9:10 | LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper> for &'b Wrapper where S: Unsize {} | ^^ diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs index ba503be2aaff7..39d1840caf41e 100644 --- a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs +++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - #![feature(const_trait_impl)] const trait Foo {} diff --git a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr index 97fdb4b287e8f..76520d1f4d89a 100644 --- a/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr +++ b/tests/ui/traits/const-traits/ice-124857-combine-effect-const-infer-vars.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Foo` for type `i32` - --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:9:1 + --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:7:1 | LL | const impl Foo for i32 {} | ---------------------- first implementation here diff --git a/tests/ui/traits/issue-90662-projection-caching.rs b/tests/ui/traits/issue-90662-projection-caching.rs index 247cc78979a91..ba3b6e4e43b98 100644 --- a/tests/ui/traits/issue-90662-projection-caching.rs +++ b/tests/ui/traits/issue-90662-projection-caching.rs @@ -1,5 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver=coherence //@ check-pass // Regression test for issue #90662 diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs index 151c3b226c114..48b1a442bf41d 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-1.rs @@ -1,4 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence //@ check-pass // A regression test for #124791. Computing ambiguity causes diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs index b472499cb0bf7..28df3a39ddddf 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - // A regression test for #124791. Computing ambiguity causes // for the overlap of the `ToString` impls caused an ICE. #![crate_type = "lib"] diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr index 469f7a909b141..6200046baa65d 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-canonical-state-ice-2.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Overlap` for type `str` - --> $DIR/ambiguity-causes-canonical-state-ice-2.rs:18:1 + --> $DIR/ambiguity-causes-canonical-state-ice-2.rs:16:1 | LL | impl + ?Sized> Overlap for T {} | --------------------------------------------------- first implementation here diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs index 54854b1b8a522..190531bc9201d 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs @@ -4,8 +4,6 @@ // takes multiple minutes when doing so and less than a second // otherwise. -//@ compile-flags: -Znext-solver=coherence - trait RecursiveSuper: Super< A0 = Self::Assoc, diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr index 3731dc5b74ec0..467981efe2c99 100644 --- a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr +++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Overlap` for type `Box<_>` - --> $DIR/ambiguity-causes-visitor-hang.rs:53:1 + --> $DIR/ambiguity-causes-visitor-hang.rs:51:1 | LL | impl Overlap for T {} | ------------------------------------- first implementation here diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs index 3fd22c7dbf0c1..551fe619329ff 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - #![feature(rustc_attrs)] #![rustc_no_implicit_bounds] #![recursion_limit = "10"] diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr index a93fbc2404dad..8e293950f0adb 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `W>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/coherence-fulfill-overflow.rs:14:1 + --> $DIR/coherence-fulfill-overflow.rs:12:1 | LL | impl Trait for W {} | ---------------------------- first implementation here diff --git a/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs b/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs index 13cdcc7d93e58..95916365a73f2 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs +++ b/tests/ui/traits/next-solver/coherence/coherence-unknowable-does-not-eagerly-normalize.rs @@ -1,4 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence //@ check-pass //@ aux-build:coherence-unknowable-does-not-eagerly-normalize-dep.rs // diff --git a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs index cbe489a0430a8..6ad7893e32f1e 100644 --- a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - // Makes sure we don't ICE on associated const projection when the feature gate // is not enabled, since we should avoid encountering ICEs on stable if possible. diff --git a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr index e8c1f597e0cd8..4d75a2ef0af99 100644 --- a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr @@ -1,5 +1,5 @@ error[E0658]: associated const equality is incomplete - --> $DIR/dont-ice-on-assoc-projection.rs:15:32 + --> $DIR/dont-ice-on-assoc-projection.rs:13:32 | LL | impl Foo for T where T: Bar {} | ^^^^^^^^^ @@ -9,7 +9,7 @@ LL | impl Foo for T where T: Bar {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0119]: conflicting implementations of trait `Foo` for type `()` - --> $DIR/dont-ice-on-assoc-projection.rs:15:1 + --> $DIR/dont-ice-on-assoc-projection.rs:13:1 | LL | impl Foo for () {} | --------------- first implementation here diff --git a/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs b/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs index 696d567db86d9..7a555b40bf6dd 100644 --- a/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs +++ b/tests/ui/traits/next-solver/normalize/indirectly-constrained-term.rs @@ -1,6 +1,3 @@ -//@ revisions: current next -//@[next] compile-flags: -Znext-solver=coherence -//@ ignore-compare-mode-next-solver (explicit revisions) //@ check-pass // A regression test for `paperclip-core`. This previously failed to compile diff --git a/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs b/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs index 1df895d732a40..0ccb6f22cf965 100644 --- a/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs +++ b/tests/ui/traits/next-solver/overflow/coherence-alias-hang-with-region.rs @@ -1,6 +1,5 @@ //@ check-pass //@ revisions: ai ia ii -//@ compile-flags: -Znext-solver=coherence // Regression test for nalgebra hang . diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs index e5a57a44d4980..f084027acfe68 100644 --- a/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs +++ b/tests/ui/traits/next-solver/overflow/recursion-limit-normalizes-to-constraints.rs @@ -1,4 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence //@ check-pass #![feature(rustc_attrs)] #![rustc_no_implicit_bounds]