diff --git a/compiler/rustc_attr_data_structures/src/version.rs b/compiler/rustc_attr_data_structures/src/version.rs index 69b0e041d819d..030e952094056 100644 --- a/compiler/rustc_attr_data_structures/src/version.rs +++ b/compiler/rustc_attr_data_structures/src/version.rs @@ -1,4 +1,5 @@ use std::fmt::{self, Display}; +use std::sync::OnceLock; use rustc_macros::{ Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version, @@ -16,8 +17,29 @@ pub struct RustcVersion { impl RustcVersion { pub const CURRENT: Self = current_rustc_version!(); + pub fn current_overridable() -> Self { + *CURRENT_OVERRIDABLE.get_or_init(|| { + if let Ok(override_var) = std::env::var("RUSTC_OVERRIDE_VERSION_STRING") + && let Some(override_) = Self::parse_str(&override_var) + { + override_ + } else { + Self::CURRENT + } + }) + } + fn parse_str(value: &str) -> Option { + // Ignore any suffixes such as "-dev" or "-nightly". + let mut components = value.split('-').next().unwrap().splitn(3, '.'); + let major = components.next()?.parse().ok()?; + let minor = components.next()?.parse().ok()?; + let patch = components.next().unwrap_or("0").parse().ok()?; + Some(RustcVersion { major, minor, patch }) + } } +static CURRENT_OVERRIDABLE: OnceLock = OnceLock::new(); + impl Display for RustcVersion { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 7cb1fede1741a..528f56dfac7da 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -129,9 +129,9 @@ pub fn eval_condition( // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details if sess.psess.assume_incomplete_release { - RustcVersion::CURRENT > min_version + RustcVersion::current_overridable() > min_version } else { - RustcVersion::CURRENT >= min_version + RustcVersion::current_overridable() >= min_version } } MetaItemKind::List(mis) => { diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 23309102c4da5..5e79d10612dbf 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -169,7 +169,7 @@ hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value in hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function .suggestion = cast the value to `{$cast_ty}` - .teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard + .teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> [1] auto trait {$traits} diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 342eed751a589..7b71f5de7569f 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -599,7 +599,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); let mut ty_file = None; - let (mut ty_str, short_ty_str) = + let (ty_str, short_ty_str) = if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() { (predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string())) } else { @@ -738,10 +738,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(within_macro_span, "due to this macro variable"); } - if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { - ty_str = short_ty_str; - } - if rcvr_ty.references_error() { err.downgrade_to_delayed_bug(); } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index ec72e05494bef..e9cfc96ba508a 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -23,7 +23,7 @@ use crate::infer::canonical::{ QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse, }; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; -use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult}; +use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, SubregionOrigin}; use crate::traits::query::NoSolution; use crate::traits::{ Obligation, ObligationCause, PredicateObligation, PredicateObligations, ScrubbedTraitError, @@ -593,10 +593,10 @@ impl<'tcx> InferCtxt<'tcx> { // no action needed } (GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => { - obligations.extend( - self.at(cause, param_env) - .eq(DefineOpaqueTypes::Yes, v1, v2)? - .into_obligations(), + self.inner.borrow_mut().unwrap_region_constraints().make_eqregion( + SubregionOrigin::RelateRegionParamBound(cause.span, None), + v1, + v2, ); } (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => { diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs index 1f3168fafb1da..21812c8017da3 100644 --- a/compiler/rustc_trait_selection/src/solve/select.rs +++ b/compiler/rustc_trait_selection/src/solve/select.rs @@ -15,6 +15,7 @@ use crate::solve::inspect::{self, ProofTreeInferCtxtExt}; #[extension(pub trait InferCtxtSelectExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { + /// Do not use this directly. This is called from [`crate::traits::SelectionContext::select`]. fn select_in_new_trait_solver( &self, obligation: &TraitObligation<'tcx>, diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 27791825aa0f6..acd6fc477055d 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -739,7 +739,7 @@ impl Step for Clippy { const DEFAULT: bool = false; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/clippy") + run.suite_path("src/tools/clippy/tests").path("src/tools/clippy") } fn make_run(run: RunConfig<'_>) { @@ -783,6 +783,23 @@ impl Step for Clippy { let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir()); cargo.env("HOST_LIBS", host_libs); + // Collect paths of tests to run + 'partially_test: { + let paths = &builder.config.paths[..]; + let mut test_names = Vec::new(); + for path in paths { + if let Some(path) = + helpers::is_valid_test_suite_arg(path, "src/tools/clippy/tests", builder) + { + test_names.push(path); + } else if path.ends_with("src/tools/clippy") { + // When src/tools/clippy is called directly, all tests should be run. + break 'partially_test; + } + } + cargo.env("TESTNAME", test_names.join(",")); + } + cargo.add_rustc_lib_path(builder); let cargo = prepare_cargo_test(cargo, &[], &[], host, builder); diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index fcd7943e6e0a8..6093e7fd2632f 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -54,6 +54,7 @@ pub struct Feature { pub tracking_issue: Option, pub file: PathBuf, pub line: usize, + pub description: Option, } impl Feature { fn tracking_issue_display(&self) -> impl fmt::Display { @@ -296,6 +297,7 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba let mut prev_names = vec![]; let lines = contents.lines().zip(1..); + let mut doc_comments: Vec = Vec::new(); for (line, line_number) in lines { let line = line.trim(); @@ -332,6 +334,13 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba continue; } + if in_feature_group { + if let Some(doc_comment) = line.strip_prefix("///") { + doc_comments.push(doc_comment.trim().to_string()); + continue; + } + } + let mut parts = line.split(','); let level = match parts.next().map(|l| l.trim().trim_start_matches('(')) { Some("unstable") => Status::Unstable, @@ -438,9 +447,15 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba tracking_issue, file: path.to_path_buf(), line: line_number, + description: if doc_comments.is_empty() { + None + } else { + Some(doc_comments.join(" ")) + }, }); } } + doc_comments.clear(); } } @@ -564,6 +579,7 @@ fn map_lib_features( tracking_issue: find_attr_val(line, "issue").and_then(handle_issue_none), file: file.to_path_buf(), line: i + 1, + description: None, }; mf(Ok((feature_name, feature)), file, i + 1); continue; @@ -600,6 +616,7 @@ fn map_lib_features( tracking_issue, file: file.to_path_buf(), line: i + 1, + description: None, }; if line.contains(']') { mf(Ok((feature_name, feature)), file, i + 1); diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 6cbdc83d5b5ff..3343577296005 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -12,13 +12,18 @@ use tidy::unstable_book::{ collect_unstable_feature_names, }; -fn generate_stub_issue(path: &Path, name: &str, issue: u32) { - let content = format!(include_str!("stub-issue.md"), name = name, issue = issue); +fn generate_stub_issue(path: &Path, name: &str, issue: u32, description: &str) { + let content = format!( + include_str!("stub-issue.md"), + name = name, + issue = issue, + description = description + ); t!(write(path, content), path); } -fn generate_stub_no_issue(path: &Path, name: &str) { - let content = format!(include_str!("stub-no-issue.md"), name = name); +fn generate_stub_no_issue(path: &Path, name: &str, description: &str) { + let content = format!(include_str!("stub-no-issue.md"), name = name, description = description); t!(write(path, content), path); } @@ -58,11 +63,17 @@ fn generate_unstable_book_files(src: &Path, out: &Path, features: &Features) { let file_name = format!("{feature_name}.md"); let out_file_path = out.join(&file_name); let feature = &features[&feature_name_underscore]; + let description = feature.description.as_deref().unwrap_or_default(); if let Some(issue) = feature.tracking_issue { - generate_stub_issue(&out_file_path, &feature_name_underscore, issue.get()); + generate_stub_issue( + &out_file_path, + &feature_name_underscore, + issue.get(), + &description, + ); } else { - generate_stub_no_issue(&out_file_path, &feature_name_underscore); + generate_stub_no_issue(&out_file_path, &feature_name_underscore, &description); } } } diff --git a/src/tools/unstable-book-gen/src/stub-issue.md b/src/tools/unstable-book-gen/src/stub-issue.md index 8698fb7278f6a..f1e91b4ac172b 100644 --- a/src/tools/unstable-book-gen/src/stub-issue.md +++ b/src/tools/unstable-book-gen/src/stub-issue.md @@ -1,5 +1,7 @@ # `{name}` +{description} + The tracking issue for this feature is: [#{issue}] [#{issue}]: https://github.com/rust-lang/rust/issues/{issue} diff --git a/src/tools/unstable-book-gen/src/stub-no-issue.md b/src/tools/unstable-book-gen/src/stub-no-issue.md index 3da140633d0f7..3674d0048aeb1 100644 --- a/src/tools/unstable-book-gen/src/stub-no-issue.md +++ b/src/tools/unstable-book-gen/src/stub-no-issue.md @@ -1,5 +1,7 @@ # `{name}` +{description} + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ diff --git a/tests/run-make/crate-loading/multiple-dep-versions.stderr b/tests/run-make/crate-loading/multiple-dep-versions.stderr index 6e1d6111b5810..dea08bb96c979 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions.stderr +++ b/tests/run-make/crate-loading/multiple-dep-versions.stderr @@ -39,7 +39,7 @@ error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in t --> replaced | LL | Type.foo(); - | ^^^ method not found in `Type` + | ^^^ method not found in `dep_2_reexport::Type` | note: there are multiple different versions of crate `dependency` in the dependency graph --> replaced @@ -63,7 +63,7 @@ error[E0599]: no function or associated item named `bar` found for struct `dep_2 --> replaced | LL | Type::bar(); - | ^^^ function or associated item not found in `Type` + | ^^^ function or associated item not found in `dep_2_reexport::Type` | note: there are multiple different versions of crate `dependency` in the dependency graph --> replaced diff --git a/tests/ui/associated-types/issue-43924.stderr b/tests/ui/associated-types/issue-43924.stderr index ab1a9511ec6c7..526f425b21e71 100644 --- a/tests/ui/associated-types/issue-43924.stderr +++ b/tests/ui/associated-types/issue-43924.stderr @@ -14,7 +14,7 @@ error[E0599]: no function or associated item named `default` found for trait obj --> $DIR/issue-43924.rs:14:39 | LL | assert_eq!(<() as Foo>::Out::default().to_string(), "false"); - | ^^^^^^^ function or associated item not found in `dyn ToString` + | ^^^^^^^ function or associated item not found in `(dyn ToString + 'static)` error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/rustc_confusables.stderr b/tests/ui/attributes/rustc_confusables.stderr index 55c9219a08a84..aba384ff8ac83 100644 --- a/tests/ui/attributes/rustc_confusables.stderr +++ b/tests/ui/attributes/rustc_confusables.stderr @@ -42,13 +42,13 @@ error[E0599]: no method named `foo` found for struct `rustc_confusables_across_c --> $DIR/rustc_confusables.rs:15:7 | LL | x.foo(); - | ^^^ method not found in `BTreeSet` + | ^^^ method not found in `rustc_confusables_across_crate::BTreeSet` error[E0599]: no method named `push` found for struct `rustc_confusables_across_crate::BTreeSet` in the current scope --> $DIR/rustc_confusables.rs:17:7 | LL | x.push(); - | ^^^^ method not found in `BTreeSet` + | ^^^^ method not found in `rustc_confusables_across_crate::BTreeSet` | help: you might have meant to use `insert` | @@ -60,7 +60,7 @@ error[E0599]: no method named `test` found for struct `rustc_confusables_across_ --> $DIR/rustc_confusables.rs:20:7 | LL | x.test(); - | ^^^^ method not found in `BTreeSet` + | ^^^^ method not found in `rustc_confusables_across_crate::BTreeSet` error[E0599]: no method named `pulled` found for struct `rustc_confusables_across_crate::BTreeSet` in the current scope --> $DIR/rustc_confusables.rs:22:7 diff --git a/tests/ui/cfg/cfg-version/cfg-version-expand.rs b/tests/ui/cfg/cfg-version/cfg-version-expand.rs new file mode 100644 index 0000000000000..8c426b4a41f51 --- /dev/null +++ b/tests/ui/cfg/cfg-version/cfg-version-expand.rs @@ -0,0 +1,30 @@ +//@ run-pass +//@ rustc-env:RUSTC_OVERRIDE_VERSION_STRING=1.50.3 + +#![feature(cfg_version)] + +#[cfg(version("1.49.0"))] +const ON_1_49_0: bool = true; +#[cfg(version("1.50"))] +const ON_1_50_0: bool = true; +#[cfg(not(version("1.51")))] +const ON_1_51_0: bool = false; + +// This one uses the wrong syntax, so doesn't eval to true +#[warn(unexpected_cfgs)] +#[cfg(not(version = "1.48.0"))] //~ WARN unexpected `cfg` condition name: `version` +const ON_1_48_0: bool = false; + +fn main() { + assert!(!ON_1_48_0); + assert!(ON_1_49_0); + assert!(ON_1_50_0); + assert!(!ON_1_51_0); + assert!(cfg!(version("1.1"))); + assert!(cfg!(version("1.49"))); + assert!(cfg!(version("1.50.0"))); + assert!(cfg!(version("1.50.3"))); + assert!(!cfg!(version("1.50.4"))); + assert!(!cfg!(version("1.51"))); + assert!(!cfg!(version("1.100"))); +} diff --git a/tests/ui/cfg/cfg-version/cfg-version-expand.stderr b/tests/ui/cfg/cfg-version/cfg-version-expand.stderr new file mode 100644 index 0000000000000..a9a8d86c0fa94 --- /dev/null +++ b/tests/ui/cfg/cfg-version/cfg-version-expand.stderr @@ -0,0 +1,17 @@ +warning: unexpected `cfg` condition name: `version` + --> $DIR/cfg-version-expand.rs:15:11 + | +LL | #[cfg(not(version = "1.48.0"))] + | ^^^^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(version, values("1.48.0"))` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +help: there is a similar config predicate: `version("..")` + | +LL - #[cfg(not(version = "1.48.0"))] +LL + #[cfg(not(version("1.48.0")))] + | + +warning: 1 warning emitted + diff --git a/tests/ui/empty/empty-struct-braces-expr.stderr b/tests/ui/empty/empty-struct-braces-expr.stderr index 8ec8ecf46bf06..a176107a06e24 100644 --- a/tests/ui/empty/empty-struct-braces-expr.stderr +++ b/tests/ui/empty/empty-struct-braces-expr.stderr @@ -121,7 +121,7 @@ error[E0599]: no variant or associated item named `Empty3` found for enum `empty --> $DIR/empty-struct-braces-expr.rs:25:19 | LL | let xe3 = XE::Empty3; - | ^^^^^^ variant or associated item not found in `XE` + | ^^^^^^ variant or associated item not found in `empty_struct::XE` | help: there is a variant with a similar name | @@ -132,7 +132,7 @@ error[E0599]: no variant or associated item named `Empty3` found for enum `empty --> $DIR/empty-struct-braces-expr.rs:26:19 | LL | let xe3 = XE::Empty3(); - | ^^^^^^ variant or associated item not found in `XE` + | ^^^^^^ variant or associated item not found in `empty_struct::XE` | help: there is a variant with a similar name | diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg index 95c7740f6995d..9c9bd163ecd49 100644 --- a/tests/ui/error-emitter/multiline-removal-suggestion.svg +++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg @@ -1,4 +1,4 @@ - +