diff --git a/compiler/rustc_ast_passes/src/diagnostics.rs b/compiler/rustc_ast_passes/src/diagnostics.rs index 0814c79d339bd..8c4e2b8986ae6 100644 --- a/compiler/rustc_ast_passes/src/diagnostics.rs +++ b/compiler/rustc_ast_passes/src/diagnostics.rs @@ -38,6 +38,14 @@ pub(crate) struct ImplFnConst { pub parent_constness: Span, } +#[derive(Diagnostic)] +#[diag("`-Znext-solver=globally` is disabled because `generic_const_exprs` is enabled")] +#[note("the old trait solver will be used globally for this crate")] +pub(crate) struct NextSolverDisabledForGenericConstExprs { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("functions in {$in_impl -> [true] trait impls diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index bd92f32e24b68..9e850c4e67587 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -6,7 +6,7 @@ use rustc_errors::msg; use rustc_feature::Features; use rustc_session::Session; use rustc_session::diagnostics::{feature_err, feature_warn}; -use rustc_span::{Span, Spanned, Symbol, sym}; +use rustc_span::{Span, Spanned, sym}; use crate::diagnostics; @@ -436,7 +436,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { maybe_stage_features(sess, features, krate); check_incompatible_features(sess, features); check_dependent_features(sess, features); - check_new_solver_banned_features(sess, features); + warn_next_solver_and_gce(sess, features); check_features_requiring_new_solver(sess, features); let mut visitor = PostExpansionVisitor { sess, features }; @@ -721,26 +721,21 @@ fn check_dependent_features(sess: &Session, features: &Features) { } } -fn check_new_solver_banned_features(sess: &Session, features: &Features) { +fn warn_next_solver_and_gce(sess: &Session, features: &Features) { if !sess.opts.unstable_opts.next_solver.globally { return; } - // Ban GCE with the new solver, because it does not implement GCE correctly. + // Warn people who uses GCE and -Znext-solver=globally + // that their trait solver was downgraded to -Znext-solver=no if let Some(gce_span) = features .enabled_lang_features() .iter() .find(|feat| feat.gate_name == sym::generic_const_exprs) .map(|feat| feat.attr_sp) { - // Abort immediately, otherwise GCE can lower to `ConstKind::Expr`, - // which the new solver intentionally does not support. - #[allow(rustc::symbol_intern_string_literal)] - sess.dcx().emit_fatal(diagnostics::IncompatibleFeatures { - spans: vec![gce_span], - f1: Symbol::intern("-Znext-solver=globally"), - f2: sym::generic_const_exprs, - }); + sess.dcx() + .emit_warn(diagnostics::NextSolverDisabledForGenericConstExprs { span: gce_span }); } } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index f3a6dfea5959e..b841bc28670fe 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -851,7 +851,7 @@ fn test_unstable_options_tracking_hash() { tracked!(mir_opt_level, Some(4)); tracked!(mir_preserve_ub, true); tracked!(move_size_limit, Some(4096)); - tracked!(next_solver, NextSolverConfig { coherence: true, globally: true }); + tracked!(next_solver, NextSolverConfig { coherence: true, globally: false }); tracked!(no_generate_arange_section, true); tracked!(no_link, true); tracked!(no_profiler_runtime, true); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 136a9e6ca464e..e3903bc29bf21 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2686,7 +2686,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn next_trait_solver_globally(self) -> bool { - self.sess.opts.unstable_opts.next_solver.globally + self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs() } pub fn next_trait_solver_in_coherence(self) -> bool { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 0303081e2c627..860ea39bfe741 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1011,7 +1011,7 @@ impl ExternEntry { } } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct NextSolverConfig { /// Whether the new trait solver should be enabled in coherence. pub coherence: bool = true, @@ -1020,6 +1020,18 @@ pub struct NextSolverConfig { pub globally: bool = false, } +// Using -Znext-solver as default on nightly +// See https://github.com/rust-lang/compiler-team/issues/1014 +impl Default for NextSolverConfig { + fn default() -> Self { + if option_env!("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY").is_some() { + Self { coherence: true, globally: true } + } else { + Self { coherence: true, globally: false } + } + } +} + #[derive(Clone)] pub enum Input { /// Load source code from a file. diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index cf0862f7741cd..751793ee671f8 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1371,8 +1371,9 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS let nightly = builder.config.channel == "nightly" || builder.config.channel == "dev"; if nightly { - // We want to enable Polonius Alpha by default on nighty + // We want to enable Polonius Alpha and Next Trait Solver by default on nighty cargo.env("CFG_DEFAULT_POLONIUS_NEXT", "1"); + cargo.env("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY", "1"); } // These conditionals represent a tension between three forces: diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 6658087bae78c..a13840e94ea41 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3228,6 +3228,9 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> builder.do_if_verbose(|| println!("doc tests for: {}", markdown.display())); let mut cmd = builder.rustdoc_cmd(compiler); builder.add_rust_test_threads(&mut cmd); + if builder.config.channel == "nightly" || builder.config.channel == "dev" { + cmd.arg("-Znext-solver=no"); + } // allow for unstable options such as new editions cmd.arg("-Z"); cmd.arg("unstable-options"); @@ -3300,7 +3303,7 @@ impl CommandLineStep for CrateLibrustc { /// /// Returns whether the test succeeded. fn run_cargo_test<'a>( - cargo: builder::Cargo, + mut cargo: builder::Cargo, libtest_args: &[&str], crates: &[String], description: impl Into>, @@ -3314,6 +3317,10 @@ fn run_cargo_test<'a>( _ => compiler.stage + 1, }; + if builder.config.channel == "nightly" || builder.config.channel == "dev" { + cargo.rustdocflag("-Znext-solver=no"); + } + let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder); let _time = helpers::timeit(builder); diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index a8a38e0d2c611..da2d688d72541 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -228,6 +228,7 @@ impl TestContext { "-Ainternal_features", "-Zui-testing", "-Zdeduplicate-diagnostics=no", + "-Znext-solver=no", "-Dwarnings", ] .map(OsString::from), @@ -334,7 +335,7 @@ fn run_ui_cargo(cx: &TestContext) { config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag; config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()]; config.program.envs.extend([ - ("RUSTFLAGS".into(), Some("-Dwarnings".into())), + ("RUSTFLAGS".into(), Some("-Dwarnings -Znext-solver=no".into())), ("CARGO_INCREMENTAL".into(), Some("0".into())), ]); // We need to do this while we still have a rustc in the `program` field. diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 73e3b87b37aa8..e4131f2d620e1 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1038,6 +1038,7 @@ impl<'test> TestCx<'test> { .arg(file_to_doc) .arg("-A") .arg("internal_features") + .arg("-Znext-solver=coherence") .args(&self.props.compile_flags) .args(&self.props.doc_flags); @@ -1850,7 +1851,7 @@ impl<'test> TestCx<'test> { match self.config.compare_mode { Some(CompareMode::Polonius) => { - compiler.args(&["-Zpolonius=next"]); + compiler.args(&["-Zpolonius=next", "-Znext-solver=coherence"]); } Some(CompareMode::NextSolver) => { compiler.args(&["-Znext-solver"]); @@ -1867,7 +1868,9 @@ impl<'test> TestCx<'test> { Some(CompareMode::SplitDwarfSingle) => { compiler.args(&["-Csplit-debuginfo=packed"]); } - None => {} + None => { + compiler.args(["-Znext-solver=coherence"]); + } } // Add `-A unused` before `config` flags and in-test (`props`) flags, so that they can diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index f7d487333e32b..84dfcce7e7ccd 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -473,6 +473,7 @@ impl<'a> LintExtractor<'a> { cmd.arg(format!("--edition={edition}")); // Just in case this is an unstable edition. cmd.arg("-Zunstable-options"); + cmd.arg("-Znext-solver=no"); cmd.arg("--error-format=json"); cmd.arg("--target").arg(self.rustc_target); if let Some(target_linker) = self.rustc_linker { diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs index b2fda8e0c62c9..96f0058543e5a 100644 --- a/src/tools/miri/tests/ui.rs +++ b/src/tools/miri/tests/ui.rs @@ -300,6 +300,9 @@ fn run_tests( ) .into(), ); + + config.program.args.push("-Znext-solver=no".into()); + if let Ok(extra_flags) = env::var("MIRIFLAGS") { for flag in extra_flags.split_whitespace() { config.program.args.push(flag.into()); diff --git a/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.rs b/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.rs index 9d114a1173929..f434186c8418b 100644 --- a/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.rs +++ b/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.rs @@ -3,13 +3,14 @@ #![feature(min_generic_const_args)] #![feature(generic_const_args)] #![feature(generic_const_exprs)] -//~^ ERROR `-Znext-solver=globally` and `generic_const_exprs` are incompatible +//~^ WARN: `-Znext-solver=globally` is disabled because `generic_const_exprs` is enabled //@ normalize-stderr: "(--> ).*/tests/ui/const-generics/generic_const_exprs" -> "$1$$DIR" use std::mem::size_of; union AsBytes { as_bytes: [u8; const { size_of::() }], + //~^ ERROR: overly complex generic constant } fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.stderr b/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.stderr index 9c2b303107185..9ef76844ab417 100644 --- a/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.stderr +++ b/tests/ui/const-generics/generic_const_exprs/next-solver-gce-incompatible-issue-158428.stderr @@ -1,10 +1,19 @@ -error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed +warning: `-Znext-solver=globally` is disabled because `generic_const_exprs` is enabled --> $DIR/next-solver-gce-incompatible-issue-158428.rs:5:12 | LL | #![feature(generic_const_exprs)] | ^^^^^^^^^^^^^^^^^^^ | - = help: remove one of these features + = note: the old trait solver will be used globally for this crate -error: aborting due to 1 previous error +error: overly complex generic constant + --> $DIR/next-solver-gce-incompatible-issue-158428.rs:12:20 + | +LL | as_bytes: [u8; const { size_of::() }], + | ^^^^^^^^^^^^^^^^^^^^^^^^ const blocks are not supported in generic constants + | + = help: consider moving this anonymous constant into a `const` function + = note: this operation may be supported in the future + +error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs index a88009aa91d23..910f2f4bcd30a 100644 --- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs +++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs @@ -1,10 +1,9 @@ -//@ known-bug: unknown // This used to ensure that the next solver prints unsatisfied always-const trait bounds as // `const Trait`, but no longer does because GCE is incompatible with the next solver. //@ compile-flags: -Znext-solver #![feature(const_trait_impl, generic_const_exprs)] -#![allow(incomplete_features)] +//~^ WARN: `-Znext-solver=globally` is disabled because `generic_const_exprs` is enabled fn require() {} @@ -15,11 +14,14 @@ const trait Trait { struct Ty; impl Trait for Ty { - fn make() -> u32 { 0 } + fn make() -> u32 { + 0 + } } fn main() { require::(); + //~^ ERROR: the trait bound `Ty: const Trait` is not satisfied } struct Container; @@ -27,7 +29,9 @@ struct Container; // FIXME(const_trait_impl): Somehow emit `the trait bound `T: const Trait` // is not satisfied` here instead and suggest changing `Trait` to `const Trait`. fn accept0(_: Container<{ T::make() }>) {} +//~^ ERROR: the trait bound `T: const Trait` is not satisfied // FIXME(const_trait_impl): Instead of suggesting `+ const Trait`, suggest // changing `[const] Trait` to `const Trait`. const fn accept1(_: Container<{ T::make() }>) {} +//~^ ERROR: the trait bound `T: const Trait` is not satisfied diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr index 912cdd1d42944..406b994854c46 100644 --- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr @@ -1,10 +1,39 @@ -error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed - --> $DIR/unsatisfied-const-trait-bound.rs:6:30 +warning: `-Znext-solver=globally` is disabled because `generic_const_exprs` is enabled + --> $DIR/unsatisfied-const-trait-bound.rs:5:30 | LL | #![feature(const_trait_impl, generic_const_exprs)] | ^^^^^^^^^^^^^^^^^^^ | - = help: remove one of these features + = note: the old trait solver will be used globally for this crate -error: aborting due to 1 previous error +error[E0277]: the trait bound `T: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:31:37 + | +LL | fn accept0(_: Container<{ T::make() }>) {} + | ^ + +error[E0277]: the trait bound `T: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:36:51 + | +LL | const fn accept1(_: Container<{ T::make() }>) {} + | ^ + +error[E0277]: the trait bound `Ty: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:23:15 + | +LL | require::(); + | ^^ + | +note: required by a bound in `require` + --> $DIR/unsatisfied-const-trait-bound.rs:8:15 + | +LL | fn require() {} + | ^^^^^^^^^^^ required by this bound in `require` +help: make the `impl` of trait `Trait` `const` + | +LL | const impl Trait for Ty { + | +++++ + +error: aborting due to 3 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0277`.