diff --git a/Cargo.lock b/Cargo.lock index 8252ac790469d..9ba27d2b57505 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4826,7 +4826,6 @@ version = "0.0.0" dependencies = [ "bitflags", "blake3", - "derive-where", "indexmap", "itoa", "md-5", diff --git a/compiler/rustc_ast_lowering/src/delegation/resolution.rs b/compiler/rustc_ast_lowering/src/delegation/resolution.rs index 0e4992267b250..7678418c47e56 100644 --- a/compiler/rustc_ast_lowering/src/delegation/resolution.rs +++ b/compiler/rustc_ast_lowering/src/delegation/resolution.rs @@ -343,7 +343,9 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { match tcx.resolve_type_relative_delegations(()).get(&def_id) { Some(res) => match *res { TypeRelativeDelegationRes::Ok(sig_id) => Ok(sig_id), - TypeRelativeDelegationRes::Error(err) => Err(err), + TypeRelativeDelegationRes::Error(_) => { + Err(tcx.dcx().emit_err(UnresolvedDelegationCallee { span })) + } TypeRelativeDelegationRes::Ambig(_) => { Err(tcx.dcx().emit_err(AmbiguousDelegationToInherentImpl { span })) } diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index 667c2d0838a25..4a6e57b12233a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -26,7 +26,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser { .zip(iter::repeat(cx.attr_span)) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { check_macro_only(cx, attr_span); } } diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index bff7d7ad81cb9..2553829f8c5ce 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -349,7 +349,7 @@ impl NoArgsAttributeParser for TrackCallerParser { const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = AttributeKind::TrackCaller; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { match cx.target { Target::Fn => { // `#[track_caller]` is not valid on weak lang items because they are called via @@ -571,7 +571,7 @@ impl CombineAttributeParser for TargetFeatureParser { parse_tf_attribute(cx, args) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { // `#[target_feature]` is incompatible with lang item functions, // except on WASM where calling target-feature functions is safe (see #84988). if !cx.sess().target.is_like_wasm && !cx.sess().opts.actually_rustdoc { diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index f3e305ea266a1..78a989fdfdba6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -94,7 +94,7 @@ impl SingleAttributeParser for RustcForceInlineParser { )) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { let Some(inline_span) = find_attr!(cx.parsed_attrs, Inline(attr, span) if !matches!(attr, InlineAttr::Force { .. }) => span) else { return; diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index a00e5af00c2eb..f4d0fa35e3f47 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -1,8 +1,10 @@ +use rustc_abi::ExternAbi; +use rustc_ast::ItemKind; use rustc_attr_ir::AttributeKind::{LinkName, LinkOrdinal, LinkSection}; use rustc_attr_ir::*; use rustc_errors::msg; use rustc_feature::{AttributeStability, Features}; -use rustc_lint_defs::builtin::ILL_FORMED_ATTRIBUTE_INPUT; +use rustc_lint_defs::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNUSED_ATTRIBUTES}; use rustc_session::Session; use rustc_session::diagnostics::feature_err; use rustc_span::edition::Edition::Edition2024; @@ -17,7 +19,7 @@ use crate::attributes::cfg::parse_cfg_entry; use crate::diagnostics::{ AsNeededCompatibility, BothFfiConstAndPure, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic, ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, - InvalidLinkModifier, InvalidMachoSection, InvalidMachoSectionReason, LinkFrameworkApple, + InvalidLinkModifier, InvalidMachoSection, InvalidMachoSectionReason, Link, LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers, NullOnLinkName, NullOnLinkSection, RawDylibOnlyWindows, WholeArchiveNeedsStatic, }; @@ -258,6 +260,29 @@ impl CombineAttributeParser for LinkParser { import_name_type, }) } + + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { + if cx.target != Target::ForeignMod { + return; + } + + let item = cx.target_item.expect("missing AST target item for Target::ForeignMod"); + let ItemKind::ForeignMod(fm) = &item.kind else { + panic!("expected foreign module AST target item for Target::ForeignMod"); + }; + let abi = fm.abi.map_or(ExternAbi::FALLBACK, |abi| { + abi.symbol_unescaped.as_str().parse().unwrap_or_else(|_| { + cx.dcx().span_delayed_bug( + abi.span, + "LinkParser::finalize_check was unable to pre-detect the ABI, so it continues to use the recovery value solely to check for unused_attributes in the lint; a user error E0703 will be reported later in lower_abi", + ); + ExternAbi::Rust + }) + }); + if matches!(abi, ExternAbi::Rust) { + cx.emit_lint(UNUSED_ATTRIBUTES, Link, attr_span); + } + } } impl LinkParser { @@ -584,7 +609,7 @@ impl NoArgsAttributeParser for FfiPureParser { const STABILITY: AttributeStability = unstable!(ffi_pure); const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { // `#[ffi_const]` functions cannot be `#[ffi_pure]`. if cx.all_attrs.iter().any(|a| a.word_is(sym::ffi_const)) { cx.emit_err(BothFfiConstAndPure { attr_span }); diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 4ead90af8d630..10e42ced30705 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -29,7 +29,7 @@ impl NoArgsAttributeParser for RustcPubTransparentParser { const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPubTransparent; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { // `#[rustc_pub_transparent]` may only be applied to `#[repr(transparent)]` types. let is_transparent = find_attr!( cx.parsed_attrs, diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 92b61fe00b1b9..dde10225e652f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -136,7 +136,7 @@ impl NoArgsAttributeParser for AllowInternalUnsafeParser { const STABILITY: AttributeStability = unstable!(allow_internal_unsafe); const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span); - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { check_macro_only(cx, attr_span); } } diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 242b4a73b06a6..8e47414f6c72a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -169,7 +169,7 @@ pub(crate) trait SingleAttributeParser: 'static { /// combinations. `attr_span` is the span of this attribute. /// /// Defaults to a no-op. - fn finalize_check(_cx: &FinalizeCheckContext<'_, '_>, _attr_span: Span) {} + fn finalize_check(_cx: &mut FinalizeCheckContext<'_, '_>, _attr_span: Span) {} } /// Use in combination with [`SingleAttributeParser`]. @@ -287,7 +287,7 @@ pub(crate) trait NoArgsAttributeParser: 'static { /// `attr_span` is the span of this attribute. /// /// Defaults to a no-op. - fn finalize_check(_cx: &FinalizeCheckContext<'_, '_>, _attr_span: Span) {} + fn finalize_check(_cx: &mut FinalizeCheckContext<'_, '_>, _attr_span: Span) {} } pub(crate) struct WithoutArgs(PhantomData); @@ -311,7 +311,7 @@ impl SingleAttributeParser for WithoutArgs { Some(T::CREATE(cx.attr_span)) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { T::finalize_check(cx, attr_span) } } @@ -355,7 +355,7 @@ pub(crate) trait CombineAttributeParser: 'static { /// `attr_span` is the span of the first attribute that was encountered. /// /// Defaults to a no-op. - fn finalize_check(_cx: &FinalizeCheckContext<'_, '_>, _attr_span: Span) {} + fn finalize_check(_cx: &mut FinalizeCheckContext<'_, '_>, _attr_span: Span) {} } /// Use in combination with [`CombineAttributeParser`]. diff --git a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs index 30fdadf95e4ce..2acba84956e67 100644 --- a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs +++ b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs @@ -21,7 +21,7 @@ impl NoArgsAttributeParser for NonExhaustiveParser { const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { if cx.target != Target::Struct { return; } diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 6115ed207d98c..bc4f9d20545fc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -4,6 +4,7 @@ use rustc_attr_ir::IntType::{SignedInt, UnsignedInt}; use rustc_attr_ir::ReprAttr; use rustc_feature::AttributeStability; use rustc_session::diagnostics::feature_err; +use rustc_span::OrdSpan; use super::prelude::*; use crate::diagnostics; @@ -272,7 +273,7 @@ fn parse_alignment(node: &LitKind, cx: &AcceptContext<'_, '_>) -> Result); +pub(crate) struct RustcAlignParser(Option<(Align, OrdSpan)>); impl RustcAlignParser { const PATH: &[Symbol] = &[sym::rustc_align]; @@ -293,7 +294,7 @@ impl RustcAlignParser { }; match parse_alignment(&lit.kind, cx) { - Ok(literal) => self.0 = Ord::max(self.0, Some((literal, cx.attr_span))), + Ok(literal) => self.0 = Ord::max(self.0, Some((literal, OrdSpan(cx.attr_span)))), Err(message) => { cx.emit_err(diagnostics::InvalidAlignmentValue { span: lit.span, @@ -318,7 +319,7 @@ impl AttributeParser for RustcAlignParser { fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { let (align, span) = self.0?; - Some(AttributeKind::RustcAlign { align, span }) + Some(AttributeKind::RustcAlign { align, span: span.0 }) } } @@ -342,6 +343,6 @@ impl AttributeParser for RustcAlignStaticParser { fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { let (align, span) = self.0.0?; - Some(AttributeKind::RustcAlign { align, span }) + Some(AttributeKind::RustcAlign { align, span: span.0 }) } } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 22a4a069b75c7..72839643b4dc3 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -102,7 +102,7 @@ pub(crate) type FinalizeFn = fn(&mut FinalizeContext<'_, '_>) -> FinalizeOutput; /// finalized, so it can inspect the fully parsed attributes via /// [`FinalizeCheckContext::parsed_attrs`]. The [`Span`] is the span of the attribute the /// check is associated with, used for diagnostics. -pub(crate) type FinalizeCheckFn = fn(&FinalizeCheckContext<'_, '_>, Span); +pub(crate) type FinalizeCheckFn = fn(&mut FinalizeCheckContext<'_, '_>, Span); /// The result of finalizing a single attribute parser. pub(crate) struct FinalizeOutput { diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index 44e405fcf5269..bf630c6bf91a0 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -1825,6 +1825,13 @@ pub(crate) struct EmptyLinkName { pub span: Span, } +#[derive(Diagnostic)] +#[diag("attribute should be applied to an `extern` block with non-Rust ABI")] +#[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] +pub(crate) struct Link; + #[derive(Diagnostic)] #[diag("link kind `framework` is only supported on Apple targets", code = E0455)] pub(crate) struct LinkFrameworkApple { diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 48083683b6a7a..df89ffe57b9a0 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -512,7 +512,7 @@ impl<'sess> AttributeParser<'sess> { // inspect the fully parsed attributes via `FinalizeCheckContext::parsed_attrs`. for (check, attr_span) in deferred_checks { check( - &FinalizeCheckContext { + &mut FinalizeCheckContext { shared: SharedContext { cx: self, target_span, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2de98fd971bda..3fe35570a69f8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -894,7 +894,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { .errors .iter() .map(|error| error.span) - .any(|sp| span < sp && !sp.contains(span)) + .any(|sp| span.lo_hi() < sp.lo_hi() && !sp.contains(span)) }) { show_assign_sugg = true; if all_init_spans.iter().any(|init_span| !init_span.contains(span)) @@ -930,7 +930,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { let mut shown = false; let mut shown_condition_value = false; for error in visitor.errors { - if error.span < span && !error.span.overlaps(span) { + if error.span.lo_hi() < span.lo_hi() && !error.span.overlaps(span) { // When we have a case like `match-cfg-fake-edges.rs`, we don't want to mention // match arms coming after the primary span because they aren't relevant: // ``` @@ -951,7 +951,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { } if !shown { for sp in &reachable_spans { - if *sp < span && !sp.overlaps(span) { + if sp.lo_hi() < span.lo_hi() && !sp.overlaps(span) { err.span_label(*sp, "binding initialized here in some conditions"); } } @@ -2545,7 +2545,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { if let hir::ExprKind::MethodCall(body_call, recv, ..) = ex.kind && body_call.ident.name == sym::next - && recv.span.source_equal(self.expr_span) + && recv.span.lo_hi() == self.expr_span.lo_hi() { self.body_expr = Some(ex); } diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index f431374de37ba..7537e2f9f1495 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -419,8 +419,8 @@ impl<'tcx> BorrowExplanation<'tcx> { _ => None, }) .collect::>(); - preds.sort(); - preds.dedup(); + preds.sort_by_key(|span| span.lo_hi()); + preds.dedup_by_key(|span| span.lo_hi()); if !preds.is_empty() { let s = if preds.len() == 1 { "" } else { "s" }; err.span_note( diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 9b36b448903a2..cb60a97eea053 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -123,7 +123,7 @@ impl<'diag, 'tcx> BorrowckDiagnosticsBuffer<'diag, 'tcx> { } if !self.buffered_diags.is_empty() { - self.buffered_diags.sort_by_key(|(sort_span, _)| *sort_span); + self.buffered_diags.sort_by_key(|(sort_span, _)| sort_span.lo_hi()); for (_, diag) in self.buffered_diags.drain(..) { diag.emit(); } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index aa62d6aaa0751..4d65410455118 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -1206,8 +1206,8 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { suggestions.push((binding_span.shrink_to_lo(), msg, "ref ".to_string())); } } - suggestions.sort_unstable_by_key(|&(span, _, _)| span); - suggestions.dedup_by_key(|&mut (span, _, _)| span); + suggestions.sort_unstable_by_key(|&(span, _, _)| span.lo_hi()); + suggestions.dedup_by_key(|&mut (span, _, _)| span.lo_hi()); for (span, msg, suggestion) in suggestions { err.span_suggestion_verbose(span, msg, suggestion, Applicability::MachineApplicable); } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 14a09337bf78e..0a6fb9d5da47a 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -318,7 +318,7 @@ impl<'tcx> MirTypeckRegionConstraints<'tcx> { /// required to hold. Normally, this is at a particular point which /// created the obligation, but for constraints that the user gave, we /// want the constraint to hold at all points. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Locations { /// Indicates that a type constraint should always be true. This /// is particularly important in the new borrowck analysis for diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index d39ae5a1852d5..04be7956e8278 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -993,6 +993,7 @@ fn do_thin_lto( exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], needs_thin_lto: Vec>, + stack_size: usize, ) -> Vec { let _timer = prof.verbose_generic_activity("LLVM_thinlto"); @@ -1083,6 +1084,7 @@ fn do_thin_lto( Arc::clone(&tm_factory), coordinator_send.clone(), item, + stack_size, ); used_token_count += 1; } @@ -1250,6 +1252,8 @@ fn start_executing_work( None }; + let stack_size = sess.opts.recommended_stack_size; + let cgcx = CodegenContext { crate_types: tcx.crate_types().to_vec(), lto: sess.lto(), @@ -1512,6 +1516,7 @@ fn start_executing_work( coordinator_send.clone(), &mut llvm_start_time, item, + stack_size, ); } } @@ -1537,6 +1542,7 @@ fn start_executing_work( coordinator_send.clone(), &mut llvm_start_time, item, + stack_size, ); } else { // There is no unstarted work, so let the main thread @@ -1580,6 +1586,7 @@ fn start_executing_work( coordinator_send.clone(), &mut llvm_start_time, item, + stack_size, ); running_with_own_token += 1; } @@ -1748,6 +1755,7 @@ fn start_executing_work( &exported_symbols_for_lto, &[], needs_thin_lto, + stack_size, )); } else { if let Some(allocator_module) = allocator_module.take() { @@ -1843,6 +1851,7 @@ fn spawn_work<'a, B: WriteBackendMethods>( coordinator_send: Sender>, llvm_start_time: &mut Option>, work: WorkItem, + stack_size: usize, ) { if llvm_start_time.is_none() { *llvm_start_time = Some(prof.verbose_generic_activity("LLVM_passes")); @@ -1876,7 +1885,11 @@ fn spawn_work<'a, B: WriteBackendMethods>( }; drop(coordinator_send.send(msg)); }; - std::thread::Builder::new().name(name).spawn(f).expect("failed to spawn work thread"); + std::thread::Builder::new() + .name(name) + .stack_size(stack_size) + .spawn(f) + .expect("failed to spawn work thread"); } fn spawn_thin_lto_work( @@ -1886,6 +1899,7 @@ fn spawn_thin_lto_work( tm_factory: TargetMachineFactoryFn, coordinator_send: Sender, work: ThinLtoWorkItem, + stack_size: usize, ) { let cgcx = cgcx.clone(); let prof = prof.clone(); @@ -1918,7 +1932,11 @@ fn spawn_thin_lto_work( }; drop(coordinator_send.send(msg)); }; - std::thread::Builder::new().name(name).spawn(f).expect("failed to spawn work thread"); + std::thread::Builder::new() + .name(name) + .stack_size(stack_size) + .spawn(f) + .expect("failed to spawn work thread"); } enum SharedEmitterMessage { @@ -2126,6 +2144,7 @@ impl OngoingCodegen { &crate_info.exported_symbols_for_lto, &crate_info.each_linked_rlib_file_for_lto, needs_thin_lto, + sess.opts.recommended_stack_size, ), allocator_module: None, } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index bedcfe998b638..cb3b43aafa155 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -101,7 +101,7 @@ impl MultiSpan { } pub fn from_spans(mut vec: Vec) -> MultiSpan { - vec.sort(); + vec.sort_by_key(|span| span.lo_hi()); MultiSpan { primary_spans: vec, span_labels: vec![], span_context: vec![] } } diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index efd5ead56b36f..362df06c404db 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -961,7 +961,7 @@ impl<'a> Diag<'a> { .map(|(span, snippet)| SubstitutionPart { snippet, span }) .collect::>(); - parts.sort_unstable_by_key(|part| part.span); + parts.sort_unstable_by_key(|part| part.span.lo_hi()); assert!(!parts.is_empty()); debug_assert_eq!( diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 541ea012bb354..dc4b6a6fd319c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2433,7 +2433,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { body.type_outlives, builder.freeze(), ); - self.infcx.insert_placeholder_assumptions(u, Some(assumptions)); + self.infcx.insert_placeholder_assumptions(u, assumptions); self.check_test_binder_body(body.value); let solver_region_constraint = self.infcx.get_solver_region_constraint(); let constraint = ty::region_constraint::eagerly_handle_placeholders_in_universe( diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c3cc3bcd6cd0c..2c626ab7dc9f3 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -240,7 +240,7 @@ fn bad_placeholder<'cx, 'tcx>( ) -> Diag<'cx> { let kind = if kind.ends_with('s') { format!("{kind}es") } else { format!("{kind}s") }; - spans.sort(); + spans.sort_by_key(|span| span.lo_hi()); cx.dcx().create_err(diagnostics::PlaceholderNotAllowedItemSignatures { spans, kind }) } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index bee062b27e0f5..7dba6b6b5f630 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::{ }; use rustc_session::diagnostics::feature_err; use rustc_span::edit_distance::find_best_match_for_name; -use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, bug, kw, sym}; +use rustc_span::{BytePos, DUMMY_SP, Ident, OrdSpan, Span, Symbol, bug, kw, sym}; use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility; use rustc_trait_selection::traits::{ FulfillmentError, dyn_compatibility_violations_for_assoc_item, @@ -943,22 +943,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return err.emit_err(); } - let mut bound_spans: SortedMap> = Default::default(); + let mut bound_spans: SortedMap> = Default::default(); let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation }); match self_ty.kind() { // Point at the type that couldn't satisfy the bound. - ty::Adt(def, _) => { - bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg) - } + ty::Adt(def, _) => bound_spans + .get_mut_or_insert_default(OrdSpan(tcx.def_span(def.did()))) + .push(msg), // Point at the trait object that couldn't satisfy the bound. ty::Dynamic(preds, _) => { for pred in preds.iter() { match pred.skip_binder() { ty::ExistentialPredicate::Trait(tr) => { bound_spans - .get_mut_or_insert_default(tcx.def_span(tr.def_id)) + .get_mut_or_insert_default(OrdSpan(tcx.def_span(tr.def_id))) .push(msg.clone()); } ty::ExistentialPredicate::Projection(_) @@ -969,7 +969,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Point at the closure that couldn't satisfy the bound. ty::Closure(def_id, _) => { bound_spans - .get_mut_or_insert_default(tcx.def_span(*def_id)) + .get_mut_or_insert_default(OrdSpan(tcx.def_span(*def_id))) .push(format!("`{quiet}`")); } _ => {} @@ -1034,7 +1034,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); for (span, mut bounds) in bound_spans { - if !tcx.sess.source_map().is_span_accessible(span) { + if !tcx.sess.source_map().is_span_accessible(span.0) { continue; } bounds.sort(); @@ -1045,7 +1045,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { [bounds @ .., last] => format!("doesn't satisfy {} or {last}", bounds.join(", ")), [] => unreachable!(), }; - err.span_label(span, msg); + err.span_label(span.0, msg); } add_def_label(&mut err); err.emit_err() @@ -1315,7 +1315,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } } - suggestions.sort_by_key(|&(span, _)| span); + suggestions.sort_by_key(|&(span, _)| span.lo_hi()); // There are cases where one bound points to a span within another bound's span, like when // you have code like the following (#115019), so we skip providing a suggestion in those // cases to avoid having a malformed suggestion. diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 11fe876209ef2..11462f5e40236 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -735,7 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match (parent, error) { (hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), init: Some(init), .. }), _) - if init.hir_id == current_hir_id && !ty.span.source_equal(init.span) => + if init.hir_id == current_hir_id && ty.span.lo_hi() != init.span.lo_hi() => { // Point at `let` assignment type. err.span_label(ty.span, "expected due to this"); diff --git a/compiler/rustc_hir_typeck/src/diverges.rs b/compiler/rustc_hir_typeck/src/diverges.rs index 1a10e19d0a5e9..15ce40d417af2 100644 --- a/compiler/rustc_hir_typeck/src/diverges.rs +++ b/compiler/rustc_hir_typeck/src/diverges.rs @@ -1,13 +1,13 @@ -use std::{cmp, ops}; +use std::ops; -use rustc_span::{DUMMY_SP, Span}; +use rustc_span::Span; /// Tracks whether executing a node may exit normally (versus /// return/break/panic, which "diverge", leaving dead code in their /// wake). Tracked semi-automatically (through type variables marked /// as diverging), with some manual adjustments for control-flow /// primitives (approximating a CFG). -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub(crate) enum Diverges { /// Potentially unknown, some cases converge, /// others require a CFG to determine them. @@ -40,14 +40,28 @@ pub(crate) enum Diverges { impl ops::BitAnd for Diverges { type Output = Self; fn bitand(self, other: Self) -> Self { - cmp::min(self, other) + match (self, other) { + (x @ Self::Maybe, _) => x, + (_, x @ Self::Maybe) => x, + // Using `span`/`custom_note` from `self` seems to give better error messages. + (x @ Self::Always { .. }, Self::Always { .. }) => x, + (Self::WarnedAlways, x) => x, + (x, Self::WarnedAlways) => x, + } } } impl ops::BitOr for Diverges { type Output = Self; fn bitor(self, other: Self) -> Self { - cmp::max(self, other) + match (self, other) { + (x @ Self::WarnedAlways, _) => x, + (_, x @ Self::WarnedAlways) => x, + // Using `span`/`custom_note` from `self` seems to give better error messages. + (x @ Self::Always { .. }, Self::Always { .. }) => x, + (Self::Maybe, x) => x, + (x, Self::Maybe) => x, + } } } @@ -70,9 +84,6 @@ impl Diverges { } pub(super) fn is_always(self) -> bool { - // Enum comparison ignores the - // contents of fields, so we just - // fill them in with garbage here. - self >= Diverges::Always { span: DUMMY_SP, custom_note: None } + matches!(self, Diverges::WarnedAlways | Diverges::Always { .. }) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 16aad0b91cb46..937182c2030da 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -3311,7 +3311,7 @@ impl<'a, 'tcx> ArgsCtxt<'a, 'tcx> { // Sometimes macros mess up the spans, so do not normalize the // arg span to equal the error span, because that's less useful // than pointing out the arg expr in the wrong context. - if normalized_span.source_equal(self.call_metadata.error_span) { + if normalized_span.lo_hi() == self.call_metadata.error_span.lo_hi() { span } else { normalized_span diff --git a/compiler/rustc_hir_typeck/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs index 3fa3e067c6662..18dfbaffc6082 100644 --- a/compiler/rustc_hir_typeck/src/loops.rs +++ b/compiler/rustc_hir_typeck/src/loops.rs @@ -11,7 +11,7 @@ use rustc_hir::{Destination, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::hygiene::DesugaringKind; -use rustc_span::{BytePos, Span, span_bug}; +use rustc_span::{BytePos, OrdSpan, Span, span_bug}; use crate::diagnostics::{ BreakInsideClosure, BreakInsideCoroutine, BreakNonLoop, ConstContinueBadLabel, @@ -80,7 +80,7 @@ struct CheckLoopVisitor<'tcx> { // such as adding a label for an `if`. // e.g. `if 'foo: {}` would be incorrect. cx_stack: Vec, - block_breaks: BTreeMap, + block_breaks: BTreeMap, } pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) { @@ -378,12 +378,13 @@ impl<'hir> CheckLoopVisitor<'hir> { UnlabeledBlock { label_span, wrap_end } if br_cx_kind == BreakContextKind::Break && label_span.eq_ctxt(break_span) => { - let block = self.block_breaks.entry(label_span).or_insert_with(|| BlockInfo { - name: br_cx_kind.to_string(), - spans: vec![], - suggs: vec![], - wrap_end, - }); + let block = + self.block_breaks.entry(OrdSpan(label_span)).or_insert_with(|| BlockInfo { + name: br_cx_kind.to_string(), + spans: vec![], + suggs: vec![], + wrap_end, + }); block.spans.push(span); block.suggs.push(break_span); } @@ -424,7 +425,7 @@ impl<'hir> CheckLoopVisitor<'hir> { name: &block.name, is_break: true, suggestion: Some(OutsideLoopSuggestion { - block_span: *s, + block_span: s.0, break_spans: block.suggs.clone(), block_prefix: if block.wrap_end.is_some() { "{ 'block: " } else { "'block: " }, wrap_end: block.wrap_end, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 86bc6eeebc189..ced9bb387b041 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -32,7 +32,7 @@ use rustc_middle::ty::print::{ use rustc_middle::ty::{self, GenericArgKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; use rustc_span::{ - DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, Ident, MacroKind, Span, Symbol, bug, + DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, Ident, MacroKind, OrdSpan, Span, Symbol, bug, edit_distance, kw, sym, }; use rustc_trait_selection::error_reporting::traits::DefIdOrName; @@ -889,12 +889,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source: SelfSource<'tcx>, unsatisfied_predicates: &UnsatisfiedPredicates<'tcx>, static_candidates: &[CandidateSource], - ) -> Result<(bool, bool, bool, bool, SortedMap>), ()> { + ) -> Result<(bool, bool, bool, bool, SortedMap>), ()> { let mut restrict_type_params = false; let mut suggested_derive = false; let mut unsatisfied_bounds = false; let mut custom_span_label = !static_candidates.is_empty(); - let mut bound_spans: SortedMap> = Default::default(); + let mut bound_spans: SortedMap> = Default::default(); let tcx = self.tcx; if item_ident.name == sym::count && self.is_slice_ty(rcvr_ty, span) { @@ -1136,7 +1136,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty: Ty<'tcx>, item_ident: Ident, item_kind: &str, - bound_spans: SortedMap>, + bound_spans: SortedMap>, unsatisfied_predicates: &UnsatisfiedPredicates<'tcx>, ) { let mut ty_span = match rcvr_ty.kind() { @@ -1178,6 +1178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None }; for (span, mut bounds) in bound_spans { + let span = span.0; if !self.tcx.sess.source_map().is_span_accessible(span) { continue; } @@ -1714,7 +1715,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggested_derive: &mut bool, unsatisfied_bounds: &mut bool, custom_span_label: &mut bool, - bound_spans: &mut SortedMap>, + bound_spans: &mut SortedMap>, ) { let tcx = self.tcx; let rcvr_ty_str = self.tcx.short_string(rcvr_ty, err.long_ty_path()); @@ -1799,16 +1800,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation }); match self_ty.kind() { // Point at the type that couldn't satisfy the bound. - ty::Adt(def, _) => { - bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg) - } + ty::Adt(def, _) => bound_spans + .get_mut_or_insert_default(OrdSpan(tcx.def_span(def.did()))) + .push(msg), // Point at the trait object that couldn't satisfy the bound. ty::Dynamic(preds, _) => { for pred in preds.iter() { match pred.skip_binder() { ty::ExistentialPredicate::Trait(tr) => { bound_spans - .get_mut_or_insert_default(tcx.def_span(tr.def_id)) + .get_mut_or_insert_default(OrdSpan(tcx.def_span(tr.def_id))) .push(msg.clone()); } ty::ExistentialPredicate::Projection(_) @@ -1819,7 +1820,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Point at the closure that couldn't satisfy the bound. ty::Closure(def_id, _) => { bound_spans - .get_mut_or_insert_default(tcx.def_span(*def_id)) + .get_mut_or_insert_default(OrdSpan(tcx.def_span(*def_id))) .push(format!("`{quiet}`")); } _ => {} @@ -2029,7 +2030,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect(); - spanned_predicates.sort_by_key(|(span, _)| *span); + spanned_predicates.sort_by_key(|(span, _)| span.lo_hi()); for (_, (primary_spans, span_labels, predicates)) in spanned_predicates { let mut tracker = TraitBoundDuplicateTracker::new(); let mut all_trait_bounds_for_rcvr = true; @@ -3571,7 +3572,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, trait_pred: ty::TraitClause<'tcx>, adt: ty::AdtDef<'tcx>, - ) -> Option> { + ) -> Option> { let diagnostic_name = self.tcx.get_diagnostic_name(trait_pred.def_id())?; let can_derive = match diagnostic_name { @@ -3609,7 +3610,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut derives = Vec::new(); let self_name = self_ty.to_string(); - let self_span = self.tcx.def_span(adt.did()); + let self_span = OrdSpan(self.tcx.def_span(adt.did())); for super_trait in supertraits(self.tcx, ty::Binder::dummy(trait_pred.trait_ref)) { if let Some(parent_diagnostic_name) = self.tcx.get_diagnostic_name(super_trait.def_id()) @@ -3627,7 +3628,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, err: &mut Diag<'_>, unsatisfied_predicates: &UnsatisfiedPredicates<'tcx>, - ) -> Vec<(String, Span, Symbol)> { + ) -> Vec<(String, OrdSpan, Symbol)> { let mut derives = Vec::new(); let mut traits = Vec::new(); for (pred, _, _) in unsatisfied_predicates { @@ -3691,7 +3692,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } } - derives_grouped.push((self_name, self_span, trait_name.to_string())); + derives_grouped.push((self_name, self_span.0, trait_name.to_string())); } for (self_name, self_span, traits) in &derives_grouped { diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 19414d7466061..923c0d49936c8 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -500,7 +500,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } if !errors_buffer.is_empty() { - errors_buffer.sort_by_key(|diag| diag.span.primary_span()); + errors_buffer.sort_by_key(|diag| diag.span.primary_span().map(Span::lo_hi)); for err in errors_buffer { err.emit(); } diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 4d90e60736995..38dab6ec4875d 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -1,4 +1,6 @@ //! Definition of `InferCtxtLike` from the librarified type layer. +use std::range::RangeInclusive; + use rustc_data_structures::sso::SsoHashMap; use rustc_hir::def_id::DefId; use rustc_middle::traits::ObligationCause; @@ -49,7 +51,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { fn insert_placeholder_assumptions( &self, u: ty::UniverseIndex, - assumptions: Option>>, + assumptions: rustc_type_ir::region_constraint::Assumptions>, ) { self.insert_placeholder_assumptions(u, assumptions); } @@ -57,7 +59,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { fn get_placeholder_assumptions( &self, u: ty::UniverseIndex, - ) -> Option>> { + ) -> rustc_type_ir::region_constraint::Assumptions> { self.get_placeholder_assumptions(u) } @@ -67,6 +69,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.get_solver_region_constraint().without_spans() } + fn has_placeholder_assumptions(&self, range: RangeInclusive) -> bool { + self.has_placeholder_assumptions(range) + } + fn overwrite_solver_region_constraint( &self, constraint: rustc_type_ir::region_constraint::RegionConstraint>, @@ -189,7 +195,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { let u = self.universe(); self.placeholder_assumptions_for_next_solver .borrow_mut() - .insert(u, Some(rustc_type_ir::region_constraint::Assumptions::empty())); + .insert(u, rustc_type_ir::region_constraint::Assumptions::empty()); f(value) }) } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 267c36652656d..e02cc9a7acd1f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1,5 +1,6 @@ use std::cell::{Cell, RefCell}; use std::fmt; +use std::range::RangeInclusive; pub use at::DefineOpaqueTypes; use free_regions::RegionRelations; @@ -335,10 +336,7 @@ pub struct InferCtxt<'tcx> { // FIXME(-Zassumptions-on-binders): This and `universe` should probably be // in `InferCtxtInner` so they can participate in rollbacks and whatnot placeholder_assumptions_for_next_solver: RefCell< - FxIndexMap< - ty::UniverseIndex, - Option>>, - >, + FxIndexMap>>, >, next_trait_solver: bool, @@ -1579,28 +1577,34 @@ impl<'tcx> InferCtxt<'tcx> { pub fn insert_placeholder_assumptions( &self, u: ty::UniverseIndex, - assumptions: Option>>, + assumptions: rustc_type_ir::region_constraint::Assumptions>, ) { - if let Some(assumptions) = &assumptions { - assert!( - !assumptions.type_outlives.has_escaping_bound_vars(), - "assumptions has escaping bound vars, which is indicative of a bug in how assumptions are handled: {:?}", - assumptions.type_outlives - ); - assert!( - assumptions.region_outlives.base_edges().all(|r| !r.has_escaping_bound_vars()), - "assumptions has escaping bound vars, which is indicative of a bug in how assumptions are handled: {:?}", - assumptions.region_outlives - ); - } + assert!( + !assumptions.type_outlives.has_escaping_bound_vars(), + "assumptions has escaping bound vars, which is indicative of a bug in how assumptions are handled: {:?}", + assumptions.type_outlives + ); + assert!( + assumptions.region_outlives.base_edges().all(|r| !r.has_escaping_bound_vars()), + "assumptions has escaping bound vars, which is indicative of a bug in how assumptions are handled: {:?}", + assumptions.region_outlives + ); self.placeholder_assumptions_for_next_solver.borrow_mut().insert(u, assumptions); } pub fn get_placeholder_assumptions( &self, u: ty::UniverseIndex, - ) -> Option>> { - self.placeholder_assumptions_for_next_solver.borrow().get(&u).unwrap().as_ref().cloned() + ) -> rustc_type_ir::region_constraint::Assumptions> { + self.placeholder_assumptions_for_next_solver.borrow().get(&u).unwrap().clone() + } + + pub fn has_placeholder_assumptions(&self, range: RangeInclusive) -> bool { + let assumptions = self.placeholder_assumptions_for_next_solver.borrow(); + // Walk around that `Step` trait is nightly only. + (range.start.index()..=range.last.index()) + .map(ty::UniverseIndex::from_usize) + .all(|u| assumptions.get(&u).is_some()) } pub fn get_solver_region_constraint(&self) -> SolverRegionConstraint<'tcx> { diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 14f534a3e7eb0..4b833da8eeb59 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -287,8 +287,6 @@ impl<'tcx> InferCtxt<'tcx> { &assumptions, ); debug!(?constraint); - let constraint = region_constraint::propagate_ambiguity(constraint); - debug!(?constraint); // FIXME(-Zassumptions-on-binders): actually implement OR as an OR for c in constraint.and_constraint.0.into_iter().chain( diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 3e73bdbf5985f..7a6a49f37278a 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -450,6 +450,9 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.using_internal_features, ); + // STACK_SIZE is setup in run_in_thread_pool_with_globals, before arriving here. + sess.opts.recommended_stack_size = *util::STACK_SIZE.get().unwrap(); + let target_config = codegen_backend.target_config(&sess); // Store all of the target features in the session. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c22ca05012b7b..9d7ac4cf9511d 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -433,7 +433,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { // Gate identifiers containing invalid Unicode codepoints that were recovered during lexing. sess.psess.bad_unicode_identifiers.with_lock(|identifiers| { for (ident, mut spans) in identifiers.drain(..) { - spans.sort(); + spans.sort_by_key(|span| span.lo_hi()); if ident == sym::ferris { enum FerrisFix { SnakeCase, diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 912f13929a349..d58b7bfddfc6d 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -21,6 +21,7 @@ use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib}; use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::{CurrentGcx, TyCtxt}; use rustc_query_impl::{CollectActiveJobsKind, collect_active_query_jobs}; +pub use rustc_session::config::DEFAULT_STACK_SIZE; use rustc_session::config::{ Cfg, Jobs, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple, }; @@ -142,7 +143,6 @@ pub(crate) fn check_abi_required_features(sess: &Session) { } pub static STACK_SIZE: OnceLock = OnceLock::new(); -pub const DEFAULT_STACK_SIZE: usize = 17 * 1024 * 1024; fn init_stack_size(early_dcx: &EarlyDiagCtxt) -> usize { // Obey the environment setting or default diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 69ac09e650c16..3410c71e684ab 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2160,8 +2160,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { // Due to macros, there might be several predicates with the same span // and we only want to suggest removing them once. - lint_spans.sort_unstable(); - lint_spans.dedup(); + lint_spans.sort_unstable_by_key(|span| span.lo_hi()); + lint_spans.dedup_by_key(|span| span.lo_hi()); cx.emit_span_lint( EXPLICIT_OUTLIVES_REQUIREMENTS, diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 416b8717a7dc3..588a9e1130f76 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -2,7 +2,7 @@ use rustc_ast as ast; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordMap; use rustc_lint_defs::{declare_lint, declare_lint_pass}; -use rustc_span::Symbol; +use rustc_span::{OrdSpan, Symbol}; use unicode_security::general_security_profile::IdentifierType; use crate::diagnostics::{ @@ -180,7 +180,7 @@ impl EarlyLintPass for NonAsciiIdents { // We will soon sort, so the initial order does not matter. #[allow(rustc::potential_query_instability)] let mut symbols: Vec<_> = symbols.iter().collect(); - symbols.sort_by_key(|k| k.1); + symbols.sort_by_key(|k| k.1.lo_hi()); for &(ref symbol, &sp) in symbols.iter() { let symbol_str = symbol.as_str(); if symbol_str.is_ascii() { @@ -342,7 +342,7 @@ impl EarlyLintPass for NonAsciiIdents { .collect::>(); // we're sorting the output here. - let mut lint_reports: BTreeMap<(Span, Vec), AugmentedScriptSet> = + let mut lint_reports: BTreeMap<(OrdSpan, Vec), AugmentedScriptSet> = BTreeMap::new(); // The end result is put in `lint_reports` which is sorted. @@ -368,7 +368,7 @@ impl EarlyLintPass for NonAsciiIdents { // We sort primitive chars here and can use unstable sort ch_list.sort_unstable(); ch_list.dedup(); - lint_reports.insert((sp, ch_list), augment_script_set); + lint_reports.insert((OrdSpan(sp), ch_list), augment_script_set); } for ((sp, ch_list), script_set) in lint_reports { @@ -382,7 +382,7 @@ impl EarlyLintPass for NonAsciiIdents { } cx.emit_span_lint( MIXED_SCRIPT_CONFUSABLES, - sp, + sp.0, MixedScriptConfusables { set: script_set.to_string(), includes }, ); } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 6598110cbfa8f..6fd65af794ac6 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -367,5 +367,5 @@ fn is_arg_inside_call(arg: Span, call: Span) -> bool { // panic call in the source file, to avoid invalid suggestions when macros are involved. // We specifically check for the spans to not be identical, as that happens sometimes when // proc_macros lie about spans and apply the same span to all the tokens they produce. - call.contains(arg) && !call.source_equal(arg) + call.contains(arg) && call.lo_hi() != arg.lo_hi() } diff --git a/compiler/rustc_middle/src/middle/resolve.rs b/compiler/rustc_middle/src/middle/resolve.rs index c34758e6454e4..bafb45469a56e 100644 --- a/compiler/rustc_middle/src/middle/resolve.rs +++ b/compiler/rustc_middle/src/middle/resolve.rs @@ -294,6 +294,7 @@ pub struct DelegationInfo { } #[derive(Debug, StableHash)] +// FIXME(fn_delegation): replace with `Result`. pub enum TypeRelativeDelegationRes { Ok(DefId), Ambig(ErrorGuaranteed), diff --git a/compiler/rustc_middle/src/mono.rs b/compiler/rustc_middle/src/mono.rs index a54ca4faf81ee..cf567fa1c8999 100644 --- a/compiler/rustc_middle/src/mono.rs +++ b/compiler/rustc_middle/src/mono.rs @@ -15,7 +15,7 @@ use rustc_hir::ItemId; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE}; use rustc_macros::{StableHash, TyDecodable, TyEncodable}; use rustc_session::config::OptLevel; -use rustc_span::{Span, Symbol}; +use rustc_span::{OrdSpan, Span, Symbol}; use rustc_target::spec::SymbolVisibility; use tracing::debug; @@ -528,7 +528,7 @@ impl<'tcx> CodegenUnit<'tcx> { // The codegen tests rely on items being process in the same order as // they appear in the file, so for local items, we sort by span first #[derive(PartialEq, Eq, PartialOrd, Ord)] - struct ItemSortKey<'tcx>(Option, SymbolName<'tcx>); + struct ItemSortKey<'tcx>(Option, SymbolName<'tcx>); // We only want to take HirIds of user-defines instances into account. // The others don't matter for the codegen tests and can even make item @@ -560,9 +560,9 @@ impl<'tcx> CodegenUnit<'tcx> { } fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> ItemSortKey<'tcx> { ItemSortKey( - local_item_id(item) - .map(|def_id| tcx.def_span(def_id).find_ancestor_not_from_macro()) - .flatten(), + local_item_id(item).and_then(|def_id| { + tcx.def_span(def_id).find_ancestor_not_from_macro().map(OrdSpan) + }), item.symbol_name(tcx), ) } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index d97fede2b6eb8..a50c5226c052d 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -21,7 +21,7 @@ use rustc_macros::{ Decodable, Encodable, StableHash, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, }; use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId}; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, OrdSpan, Span, Symbol, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; @@ -863,15 +863,15 @@ impl DynCompatibilityViolation { | Self::SupertraitConst(_) => DynCompatibilityViolationSolution::None, Self::Method( name, - MethodViolation::StaticMethod(Some((add_self_sugg, make_sized_sugg))), + MethodViolation::StaticMethod(Some(((add_s, add_sp), (make_s, make_sp)))), _, ) => DynCompatibilityViolationSolution::AddSelfOrMakeSized { name: *name, - add_self_sugg: add_self_sugg.clone(), - make_sized_sugg: make_sized_sugg.clone(), + add_self_sugg: (add_s.clone(), OrdSpan(*add_sp)), + make_sized_sugg: (make_s.clone(), OrdSpan(*make_sp)), }, Self::Method(name, MethodViolation::UndispatchableReceiver(Some((span, lt))), _) => { - DynCompatibilityViolationSolution::ChangeToRefSelf(*name, *span, *lt) + DynCompatibilityViolationSolution::ChangeToRefSelf(*name, OrdSpan(*span), *lt) } Self::Method(name, ..) | Self::AssocConst(name, ..) | Self::GenericAssocTy(name, _) => { DynCompatibilityViolationSolution::MoveToAnotherTrait(*name) @@ -901,15 +901,15 @@ impl DynCompatibilityViolation { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum DynCompatibilityViolationSolution { None, AddSelfOrMakeSized { name: Symbol, - add_self_sugg: (String, Span), - make_sized_sugg: (String, Span), + add_self_sugg: (String, OrdSpan), + make_sized_sugg: (String, OrdSpan), }, - ChangeToRefSelf(Symbol, Span, Symbol), + ChangeToRefSelf(Symbol, OrdSpan, Symbol), MoveToAnotherTrait(Symbol), } @@ -923,7 +923,7 @@ impl DynCompatibilityViolationSolution { make_sized_sugg, } => { err.span_suggestion_verbose( - add_self_sugg.1, + add_self_sugg.1.0, format!( "consider turning `{name}` into a method by giving it a `&self` argument, \ so that it is accessible through the trait object's vtable", @@ -932,7 +932,7 @@ impl DynCompatibilityViolationSolution { Applicability::MaybeIncorrect, ); err.span_suggestion_verbose( - make_sized_sugg.1, + make_sized_sugg.1.0, format!( "alternatively, consider constraining `{name}` so it is explicitly marked \ as not applying to trait objects", @@ -943,7 +943,7 @@ impl DynCompatibilityViolationSolution { } DynCompatibilityViolationSolution::ChangeToRefSelf(name, span, lt) => { err.span_suggestion_verbose( - span, + span.0, format!("consider changing method `{name}`'s `self` parameter to be `&self`"), format!("&{lt}{}self", if lt != sym::empty { " " } else { "" }), Applicability::MachineApplicable, diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 7b253390b53b6..e83c3560a1ee9 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -1105,7 +1105,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { // Visit the body. visitor.visit_expr(&thir[expr]); - warnings.sort_by_key(|w| w.block_span); + warnings.sort_by_key(|w| w.block_span.lo_hi()); for UnusedUnsafeWarning { hir_id, block_span, enclosing_unsafe } in warnings { let block_span = tcx.sess.source_map().guess_head_span(block_span); tcx.emit_node_span_lint( diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 52de3f094e15b..b434bd17e2d8e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -412,7 +412,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { { let mut redundant_subpats = redundant_subpats.clone(); // Emit lints in the order in which they occur in the file. - redundant_subpats.sort_unstable_by_key(|(pat, _)| pat.data().span); + redundant_subpats.sort_unstable_by_key(|(pat, _)| pat.data().span.lo_hi()); for (pat, explanation) in redundant_subpats { report_unreachable_pattern(cx, arm.arm_data, pat, &explanation, None) } diff --git a/compiler/rustc_mir_transform/src/check_call_recursion.rs b/compiler/rustc_mir_transform/src/check_call_recursion.rs index 101658808d949..aa5649ed9eb2d 100644 --- a/compiler/rustc_mir_transform/src/check_call_recursion.rs +++ b/compiler/rustc_mir_transform/src/check_call_recursion.rs @@ -79,7 +79,7 @@ fn check_recursion<'tcx>( return; } - vis.reachable_recursive_calls.sort(); + vis.reachable_recursive_calls.sort_by_key(|span| span.lo_hi()); let sp = tcx.def_span(def_id); let hir_id = tcx.local_def_id_to_hir_id(def_id); diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index ade8bb7865dda..9aa5f3b9f5ab2 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -50,7 +50,7 @@ pub(super) fn extract_refined_covspans<'tcx>( // Discard any spans not contained within the function body span. // Also discard any spans that fill the entire body, because they tend // to represent compiler-inserted code, e.g. implicitly returning `()`. - if !body_span.contains(covspan_span) || body_span.source_equal(covspan_span) { + if !body_span.contains(covspan_span) || body_span.lo_hi() == covspan_span.lo_hi() { return false; } @@ -91,7 +91,7 @@ pub(super) fn extract_refined_covspans<'tcx>( // preferring the one with the most-dominated BCB. // (Ideally we should try to preserve _all_ non-dominating BCBs, but that // requires a lot more complexity in the span refiner, for little benefit.) - covspans.dedup_by(|b, a| a.span.source_equal(b.span)); + covspans.dedup_by_key(|a| a.span.lo_hi()); // Sort the holes, and merge overlapping/adjacent holes. let mut holes = node.hole_spans.iter().copied().map(|span| Hole { span }).collect::>(); diff --git a/compiler/rustc_monomorphize/src/graph_checks/statics.rs b/compiler/rustc_monomorphize/src/graph_checks/statics.rs index 4a6416843fded..e954077f27972 100644 --- a/compiler/rustc_monomorphize/src/graph_checks/statics.rs +++ b/compiler/rustc_monomorphize/src/graph_checks/statics.rs @@ -100,7 +100,7 @@ pub(super) fn check_static_initializers_are_acyclic<'tcx, 'a, 'b>( // Emit errors for all cycles for nodes in nodes_of_sccs.iter_mut().filter(|nodes| is_cyclic(nodes)) { // We sort the nodes by their Span to have consistent error line numbers - nodes.sort_by_key(|node| tcx.def_span(statics[node.index()])); + nodes.sort_by_key(|node| tcx.def_span(statics[node.index()]).lo_hi()); let head_def = statics[nodes[0].index()]; let head_span = tcx.def_span(head_def); diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 45ae4cadf519c..655ab64145db5 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -173,7 +173,7 @@ where // recreated universes here. delegate.insert_placeholder_assumptions( new_universe, - Some(rustc_type_ir::region_constraint::Assumptions::empty()), + rustc_type_ir::region_constraint::Assumptions::empty(), ); } } diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index c96aa90a10792..fdf702248196a 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -75,7 +75,7 @@ where // context to compute placeholder assumptions for the binders it enters. infcx.insert_placeholder_assumptions( *new, - Some(rustc_type_ir::region_constraint::Assumptions::empty()), + rustc_type_ir::region_constraint::Assumptions::empty(), ); } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index cbdf6879bbe71..c841845392429 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -5,7 +5,7 @@ use std::ops::ControlFlow; use rustc_macros::StableHash; use rustc_type_ir::data_structures::HashSet; use rustc_type_ir::inherent::*; -use rustc_type_ir::region_constraint::{self, RegionConstraint}; +use rustc_type_ir::region_constraint::RegionConstraint; use rustc_type_ir::relate::Relate; use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::search_graph::{ @@ -1388,13 +1388,19 @@ where f: impl FnOnce(&mut Self, T) -> U, ) -> U { self.delegate.enter_forall_without_assumptions(value, |value| { + // Invariant: we shouldn't insert empty assumptions if assumptions computation fails. + // When handling placeholder constraints, we rely on vacancies to force ambiguity. let u = self.delegate.universe(); - let assumptions = if self.cx().assumptions_on_binders() { - self.region_assumptions_for_placeholders_in_universe(value.clone(), u, param_env) - } else { - None - }; - self.delegate.insert_placeholder_assumptions(u, assumptions); + if self.cx().assumptions_on_binders() + && let Some(assumptions) = self.region_assumptions_for_placeholders_in_universe( + value.clone(), + u, + param_env, + ) + { + self.delegate.insert_placeholder_assumptions(u, assumptions); + } + f(self, value) }) } @@ -1768,10 +1774,6 @@ where let region_constraints = if self.cx().assumptions_on_binders() { ExternalRegionConstraints::NextGen(if let Certainty::Yes = certainty { let constraint = self.delegate.get_solver_region_constraint(); - debug_assert_eq!( - constraint, - region_constraint::propagate_ambiguity(constraint.clone()) - ); constraint } else { RegionConstraint::new_true() diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs index 10dd8585b09c4..8a4d3fba99a39 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/solver_region_constraints.rs @@ -8,7 +8,6 @@ use rustc_type_ir::outlives::{Component, push_outlives_components}; use rustc_type_ir::region_constraint::TransitiveRelationBuilder; use rustc_type_ir::region_constraint::{ And, Assumptions, LeafRegionConstraint, Or, eagerly_handle_placeholders_in_universe, - propagate_ambiguity, }; use rustc_type_ir::{ AliasTy, Binder, ClauseKind, Const, InferCtxtLike, Interner, Region, TypeVisitable, @@ -115,17 +114,27 @@ where pub(super) fn eagerly_handle_placeholders(&mut self) -> Result { let constraint = self.delegate.get_solver_region_constraint(); - let smallest_universe = self.max_input_universe.index(); - let largest_universe = self.delegate.universe().index(); - debug!(?smallest_universe, largest_universe); + let smallest_universe = self.max_input_universe; + let largest_universe = self.delegate.universe(); + debug!("smallest_universe={smallest_universe:#?}, largest_universe={largest_universe:#?}"); - let constraint = ((smallest_universe + 1)..=largest_universe) - .map(|u| UniverseIndex::from_usize(u)) + // We rely on placeholder assumptions to evaluate region constraints with placeholders. + // But we can fail to compute assumptions due to unresolved type variables. In that case, + // we conservatively bail with ambiguity. + if !self + .delegate + .has_placeholder_assumptions(((smallest_universe + 1)..=largest_universe).into()) + { + return Ok(Certainty::AMBIGUOUS); + } + + // Walk around that `Step` trait is nightly only. + let constraint = ((smallest_universe.index() + 1)..=largest_universe.index()) + .map(UniverseIndex::from_usize) .rev() .fold(constraint, |constraint, u| { eagerly_handle_placeholders_in_universe(&**self.delegate, constraint, u) }); - let constraint = propagate_ambiguity(constraint); debug!("final constraint={:?}", constraint); self.delegate.overwrite_solver_region_constraint(constraint.clone(), self.origin_span); @@ -164,7 +173,9 @@ where Or::new_leaf(PlaceholderTyOutlives(Ty::new_placeholder(self.cx(), *p), r, ())) } Alias(_, alias) => self.destructure_alias_outlives(*alias, r), - UnresolvedInferenceVariable(_) => Or::new_ambig(()), + UnresolvedInferenceVariable(_) => { + panic!("Shouldn't destructure type outlives when ty vars exist") + } Param(_) => panic!("Params should have been canonicalized to placeholders"), EscapingAlias(components) => self.destructure_components(components, r), } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 1d7d2dd75c316..dddc78373b1b5 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -92,15 +92,6 @@ where let ty::OutlivesClause(ty, lt) = goal.predicate; let ty = self.normalize(GoalSource::Misc, goal.param_env, ty::Unnormalized::new_wip(ty))?; - if self.cx().assumptions_on_binders() { - use rustc_type_ir::region_constraint::RegionConstraint; - - let constraint = self.destructure_type_outlives(ty, lt); - self.register_solver_region_constraint(RegionConstraint::new_from_or(constraint)); - } else { - self.register_ty_outlives(ty, lt); - } - // The normalized type can still contain non-rigid higher ranked aliases if their // normalization ends up with ambiguity. Or we have non-rigid aliases inside rigid ones. // Infer vars may be resolved to types/consts containing non-rigid aliases later. @@ -109,6 +100,18 @@ where if ty.has_non_region_infer() || ty.has_non_rigid_aliases() { self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } else { + // We drop region constraints in ambiguous response so there's no need to add them in + // the ambiguous branch. Also this guarantees we don't have ty vars when destructuring + // type outlives. + if self.cx().assumptions_on_binders() { + use rustc_type_ir::region_constraint::RegionConstraint; + + let constraint = self.destructure_type_outlives(ty, lt); + self.register_solver_region_constraint(RegionConstraint::new_from_or(constraint)); + } else { + self.register_ty_outlives(ty, lt); + } + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3e06b787a78be..3c920d14006bb 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -8,7 +8,6 @@ use std::cell::Cell; use std::slice; -use rustc_abi::ExternAbi; use rustc_ast::MetaItemKind; use rustc_attr_ir::diagnostic::Directive; use rustc_attr_ir::lang_items::LangItem; @@ -208,7 +207,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } AttributeKind::Naked(..) => self.check_naked(hir_id, target), AttributeKind::MayDangle(attr_span) => self.check_may_dangle(hir_id, *attr_span), - AttributeKind::Link(_, attr_span) => self.check_link(hir_id, *attr_span, target), AttributeKind::MacroExport { span, .. } => { self.check_macro_export(hir_id, *span, target) } @@ -271,6 +269,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::InstructionSet(..) => (), AttributeKind::InstrumentFn(..) => (), AttributeKind::Lang(..) => (), + AttributeKind::Link(..) => (), AttributeKind::LinkName { .. } => (), AttributeKind::LinkOrdinal { .. } => (), AttributeKind::LinkSection { .. } => (), @@ -1100,22 +1099,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.dcx().emit_err(diagnostics::InvalidMayDangle { attr_span }); } - /// Checks if `#[link]` is applied to an item other than a foreign module. - fn check_link(&self, hir_id: HirId, attr_span: Span, target: Target) { - if target != Target::ForeignMod { - return; // Checked by attribute parser - } - - if let hir::Node::Item(item) = self.tcx.hir_node(hir_id) - && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item - && !matches!(abi, ExternAbi::Rust) - { - return; - } - - self.tcx.emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr_span, diagnostics::Link); - } - /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self, @@ -1210,7 +1193,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if !reprs.is_empty() { let sorted_reprs = { let mut to_sort = reprs.to_owned(); - to_sort.sort_unstable(); + to_sort.sort_unstable_by_key(|(attr, span)| (*attr, span.lo_hi())); to_sort }; diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 59c1005885903..7c82811f99276 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -126,13 +126,6 @@ pub(crate) struct BothOptimizeNoneAndInline { pub inline_span: Span, } -#[derive(Diagnostic)] -#[diag("attribute should be applied to an `extern` block with non-Rust ABI")] -#[warning( - "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" -)] -pub(crate) struct Link; - #[derive(Diagnostic)] #[diag("#[rustc_legacy_const_generics] functions must only have const generics")] pub(crate) struct RustcLegacyConstGenericsOnly { diff --git a/compiler/rustc_query_impl/src/handle_cycle_error.rs b/compiler/rustc_query_impl/src/handle_cycle_error.rs index 83e95b9195580..3f70fc2a6b833 100644 --- a/compiler/rustc_query_impl/src/handle_cycle_error.rs +++ b/compiler/rustc_query_impl/src/handle_cycle_error.rs @@ -223,7 +223,7 @@ fn recursive_type_error( let start_index = item_and_field_ids .iter() .enumerate() - .min_by_key(|&(_, &(id, _))| tcx.def_span(id)) + .min_by_key(|&(_, &(id, _))| tcx.def_span(id).lo_hi()) .unwrap() .0; item_and_field_ids.rotate_left(start_index); diff --git a/compiler/rustc_resolve/src/diagnostics/impls.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs index 9defefee9637b..543ad177c370e 100644 --- a/compiler/rustc_resolve/src/diagnostics/impls.rs +++ b/compiler/rustc_resolve/src/diagnostics/impls.rs @@ -346,9 +346,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.lint_buffer.buffer_lint( MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, CRATE_NODE_ID, - span_use, + span_use.0, diagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths { - definition: span_def, + definition: span_def.0, }, ); } @@ -943,11 +943,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let BindingError { name, target, origin, could_be_path } = binding_error; let mut target_sp = target.iter().map(|pat| pat.span).collect::>(); - target_sp.sort(); - target_sp.dedup(); + target_sp.sort_by_key(|sp| sp.lo_hi()); + target_sp.dedup_by_key(|sp| sp.lo_hi()); let mut origin_sp = origin.iter().map(|(span, _)| *span).collect::>(); - origin_sp.sort(); - origin_sp.dedup(); + origin_sp.sort_by_key(|sp| sp.lo_hi()); + origin_sp.dedup_by_key(|sp| sp.lo_hi()); let msp = MultiSpan::from_spans(target_sp.clone()); let mut err = self.dcx().create_err(diagnostics::VariableIsNotBoundInAllPatterns { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index d743093aae92f..1fcc4dafeed91 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -10,7 +10,7 @@ use rustc_middle::middle::resolve::PartialRes; use rustc_session::diagnostics::feature_err; use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext}; -use rustc_span::{Ident, Span, bug, kw, span_bug, sym}; +use rustc_span::{Ident, OrdSpan, Span, bug, kw, span_bug, sym}; use smallvec::SmallVec; use tracing::{debug, instrument}; @@ -1393,7 +1393,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && let DeclKind::Import { import, .. } = binding.kind && matches!(import.kind, ImportKind::MacroExport) { - self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); + self.macro_expanded_macro_export_errors + .insert((OrdSpan(path_span), OrdSpan(binding.span))); } self.record_use(ident, binding, used); diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 5cd45c5de5230..9afbb425eeb9d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::Visibility; use rustc_session::diagnostics::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::LocalExpnId; -use rustc_span::{Ident, Span, Symbol, kw, span_bug, sym}; +use rustc_span::{Ident, OrdSpan, Span, Symbol, kw, span_bug, sym}; use tracing::debug; use crate::Namespace::{self, *}; @@ -1765,7 +1765,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && !other_binding.is_ambiguity_recursive(); if is_redundant { redundant_span[ns] = - Some((other_binding.span, other_binding.is_import())); + Some((OrdSpan(other_binding.span), other_binding.is_import())); } } Err(_) => is_redundant = false, @@ -1785,7 +1785,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let ident = source; let subs = redundant_spans .into_iter() - .map(|(span, is_imported)| match (span.is_dummy(), is_imported) { + .map(|(OrdSpan(span), is_imported)| match (span.is_dummy(), is_imported) { (false, true) => { diagnostics::RedundantImportSub::ImportedHere { span, ident } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index cdef92b389265..9a40af31c1e5f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -113,7 +113,7 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str } /// Description of an elided lifetime. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub(super) struct MissingLifetime { /// Used to overwrite the resolution with the suggestion, to avoid cascading errors. pub id: NodeId, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 0a96becf993e9..f0005d4a98e13 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -69,7 +69,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{self, RegisteredTools, TyCtxt, TyCtxtFeed, Visibility}; use rustc_span::def_id::{LocalModId, ModId}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; -use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, span_bug, sym}; +use rustc_span::{DUMMY_SP, Ident, OrdSpan, Span, Symbol, bug, kw, span_bug, sym}; use rustc_structures::CrateType; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; @@ -1431,7 +1431,7 @@ pub struct Resolver<'ra, 'tcx> { /// Visibility path resolution failures are delayed until all modules are collected. delayed_vis_resolution_errors: Vec> = Vec::new(), /// Crate-local macro expanded `macro_export` referred to by a module-relative path. - macro_expanded_macro_export_errors: BTreeSet<(Span, Span)> = BTreeSet::new(), + macro_expanded_macro_export_errors: BTreeSet<(OrdSpan, OrdSpan)> = BTreeSet::new(), arenas: &'ra WorkerLocal>, dummy_decl: Decl<'ra>, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 753a4ed0d779a..798dcaf969965 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -51,6 +51,9 @@ mod native_libs; mod print_request; pub mod sigpipe; +/// A recommended stack size for worker threads spawned within a session. +pub const DEFAULT_STACK_SIZE: usize = 17 * 1024 * 1024; + /// Special CPU name requesting the CPU of the current host. pub const NATIVE_CPU: &str = "native"; @@ -1516,6 +1519,7 @@ impl Default for Options { target_modifiers: BTreeMap::default(), mitigation_coverage_map: Default::default(), jobs: Jobs { frontend: None, backend: None, linker: LinkerJobs::Default }, + recommended_stack_size: DEFAULT_STACK_SIZE, } } } @@ -3074,6 +3078,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M target_modifiers: collected_options.target_modifiers, mitigation_coverage_map: collected_options.mitigations, jobs, + recommended_stack_size: DEFAULT_STACK_SIZE, } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 0e06713019f9c..e53ba99647849 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -438,6 +438,7 @@ top_level_options!( color: ColorConfig [UNTRACKED], verbose: bool [TRACKED_NO_CRATE_HASH], jobs: Jobs [UNTRACKED], + recommended_stack_size: usize [UNTRACKED], } ); diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 7889e53315361..f8e5e2b48b5f0 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -7,7 +7,6 @@ edition = "2024" # tidy-alphabetical-start bitflags = "2.4.1" blake3 = "1.5.2" -derive-where = "1.2.7" indexmap = { version = "2.0.0" } itoa = "1.0" md5 = { package = "md-5", version = "0.10.0" } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 20950c1a5ff87..ddec29eca6517 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -32,7 +32,6 @@ // this crate without this line making `rustc_span` available. extern crate self as rustc_span; -use derive_where::derive_where; use rustc_data_structures::stable_hash::StableHashCtxt; use rustc_data_structures::{AtomicRef, outline}; use rustc_macros::{Decodable, Encodable, StableHash}; @@ -60,7 +59,7 @@ pub mod def_id; use def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, LocalDefId, StableCrateId}; pub mod edit_distance; mod span_encoding; -pub use span_encoding::{DUMMY_SP, Span}; +pub use span_encoding::{DUMMY_SP, OrdSpan, Span}; pub mod symbol; pub use symbol::{ @@ -74,7 +73,6 @@ pub mod profiling; pub mod macros; use std::borrow::Cow; -use std::cmp::{self, Ordering}; use std::fmt::Display; use std::hash::Hash; use std::io::{self, Read}; @@ -82,7 +80,7 @@ use std::ops::{Add, Range, Sub}; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; -use std::{fmt, iter}; +use std::{cmp, fmt, iter}; pub use macros::{bug, span_bug}; use md5::{Digest, Md5}; @@ -684,22 +682,20 @@ impl FileName { /// sent to other threads, but some pieces of performance infra run in a separate thread. /// Using `Span` is generally preferred. #[derive(Clone, Copy, Hash, PartialEq, Eq)] -#[derive_where(PartialOrd, Ord)] pub struct SpanData { pub lo: BytePos, pub hi: BytePos, /// Information about where the macro came from, if this piece of /// code was created by a macro expansion. - #[derive_where(skip)] - // `SyntaxContext` does not implement `Ord`. - // The other fields are enough to determine in-file order. pub ctxt: SyntaxContext, - #[derive_where(skip)] - // `LocalDefId` does not implement `Ord`. - // The other fields are enough to determine in-file order. pub parent: Option, } +// `SyntaxContext` and `LocalDefId` aren't orderable. See the equivalent negative impls for `Span` +// for more details. +impl !PartialOrd for SpanData {} +impl !Ord for SpanData {} + impl SpanData { #[inline] pub fn span(&self) -> Span { @@ -740,17 +736,6 @@ impl Default for SpanData { } } -impl PartialOrd for Span { - fn partial_cmp(&self, rhs: &Self) -> Option { - Some(self.cmp(rhs)) - } -} -impl Ord for Span { - fn cmp(&self, rhs: &Self) -> Ordering { - Ord::cmp(&self.data(), &rhs.data()) - } -} - impl Span { #[inline] pub fn lo(self) -> BytePos { @@ -773,6 +758,16 @@ impl Span { self.map_ctxt(|_| ctxt) } + /// When to use this: + /// - Use it instead of `==` for span equality comparisons when either span could be generated + /// code and you only care that they point to the same bytes of source text. + /// - Use it (possibly via `OrdSpan`) for span ordering comparisons of any kind. + #[inline] + pub fn lo_hi(self) -> (BytePos, BytePos) { + let data = self.data(); + (data.lo, data.hi) + } + #[inline] pub fn is_visible(self, sm: &SourceMap) -> bool { !self.is_dummy() && sm.is_span_accessible(self) @@ -861,16 +856,6 @@ impl Span { span.lo <= other.hi && other.lo <= span.hi } - /// Returns `true` if the spans are equal with regards to the source text. - /// - /// Use this instead of `==` when either span could be generated code, - /// and you only care that they point to the same bytes of source text. - pub fn source_equal(self, other: Span) -> bool { - let span = self.data(); - let other = other.data(); - span.lo == other.lo && span.hi == other.hi - } - /// Returns `Some(span)`, where the start is trimmed by the end of `other`. pub fn trim_start(self, other: Span) -> Option { let span = self.data(); @@ -1084,7 +1069,7 @@ impl Span { } let expn_data = ctxt.outer_expn_data(); - let is_recursive = expn_data.call_site.source_equal(prev_span); + let is_recursive = expn_data.call_site.lo_hi() == prev_span.lo_hi(); prev_span = self; self = expn_data.call_site; diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 64280d5ce4b5e..af6f219b4e58e 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -1,3 +1,6 @@ +use std::cmp::Ordering; +use std::hash::Hash; + use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::stable_hash::RawSpan; // This code is very hot and uses lots of arithmetic, avoid overflow checks for performance. @@ -85,6 +88,12 @@ pub struct Span { ctxt_or_parent_or_marker: u16, } +// `SyntaxContext` (`SpanData::ctxt`) and `LocalDefId` (within `SpanData::parent`) aren't orderable. +// If you want to order spans just on `lo`/`hi`, use explicit comparisons involving `Span::lo_hi`. +// Or you can wrap your span within `OrdSpan` which impls `PartialOrd`/`Ord` via `Span::lo_hi`. +impl !PartialOrd for Span {} +impl !Ord for Span {} + // Convenience structures for all span formats. #[derive(Clone, Copy)] struct InlineCtxt { @@ -456,6 +465,38 @@ impl Span { } } +/// Span wrapper that provides equality and ordering based only on the `lo`/`hi` fields. Exists +/// because `Span` doesn't impl `PartialOrd`/`Ord` due to the `ctxt` and `parent` fields being +/// unorderable. Useful when storing things in source code order, e.g. in a `BTreeMap`. +#[derive(Clone, Copy, Debug)] +pub struct OrdSpan(pub Span); + +impl PartialEq for OrdSpan { + fn eq(&self, rhs: &Self) -> bool { + // Ignores `ctxt` and `parent` because they are unorderable. + self.0.lo_hi() == rhs.0.lo_hi() + } +} + +impl Eq for OrdSpan {} + +impl PartialOrd for OrdSpan { + fn partial_cmp(&self, rhs: &Self) -> Option { + Some(self.cmp(rhs)) + } +} + +impl Ord for OrdSpan { + fn cmp(&self, rhs: &Self) -> Ordering { + // Ignores `ctxt` and `parent` because they are unorderable. + self.0.lo_hi().cmp(&rhs.0.lo_hi()) + } +} + +// `OrdSpan` is typically stored in types that rely on ordering, such as `BTreeMap` or `SortedMap`. +// Hashing shouldn't be necessary. +impl !Hash for OrdSpan {} + #[derive(Default)] pub(crate) struct SpanInterner { spans: FxIndexSet, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 166c320cda28a..e79a05328f132 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -73,16 +73,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if mention_influencer { spans.push(sup_origin.span()); } - // We dedup the spans *ignoring* expansion context. - spans.sort(); - spans.dedup_by_key(|span| (span.lo(), span.hi())); + // We sort and dedup the spans *ignoring* expansion context. + spans.sort_by_key(|span| span.lo_hi()); + spans.dedup_by_key(|span| span.lo_hi()); // We try to make the output have fewer overlapping spans if possible. let require_span = if sup_origin.span().overlaps(return_sp) { sup_origin.span() } else { return_sp }; let spans_empty = spans.is_empty(); - let require_as_note = spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp); + let require_as_note = + spans.iter().any(|sp| sp.overlaps(return_sp) || sp.lo_hi() > return_sp.lo_hi()); let bound = if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin { Some(*bound) } else { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index b9f70cea5f5ab..59ce72eef48fc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -210,12 +210,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; // sort the errors by span, for better error message stability. - errors.sort_by_key(|u| match *u { - RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), - RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), - RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(), - RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => rvo.span(), - RegionResolutionError::CannotNormalize(_, ref sro) => sro.span(), + errors.sort_by_key(|u| { + match *u { + RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), + RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), + RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(), + RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => { + rvo.span() + } + RegionResolutionError::CannotNormalize(_, ref sro) => sro.span(), + } + .lo_hi() }); errors } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 63b0733b0a095..c03ace331208b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1178,7 +1178,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { type Result = ControlFlow<&'v hir::Expr<'v>>; fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result { if let hir::ExprKind::Match(expr, _arms, hir::MatchSource::TryDesugar(_)) = ex.kind - && ex.span.with_lo(ex.span.hi() - BytePos(1)).source_equal(self.search_span) + && ex.span.with_lo(ex.span.hi() - BytePos(1)).lo_hi() + == self.search_span.lo_hi() && let hir::ExprKind::Call(_, [expr, ..]) = expr.kind { ControlFlow::Break(expr) diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 22ebedd9f7e3c..d50f6521441d5 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -1,5 +1,6 @@ use core::fmt; use std::hash::{Hash, Hasher}; +use std::range::RangeInclusive; use derive_where::derive_where; #[cfg(feature = "nightly")] @@ -407,12 +408,13 @@ pub trait InferCtxtLike: Sized { fn insert_placeholder_assumptions( &self, u: ty::UniverseIndex, - assumptions: Option>, + assumptions: crate::region_constraint::Assumptions, ); fn get_placeholder_assumptions( &self, u: ty::UniverseIndex, - ) -> Option>; + ) -> crate::region_constraint::Assumptions; + fn has_placeholder_assumptions(&self, range: RangeInclusive) -> bool; fn get_solver_region_constraint( &self, ) -> crate::region_constraint::RegionConstraint; diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index e13ecb5e9575e..e1b1d157ff85f 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -558,8 +558,7 @@ pub fn eagerly_handle_placeholders_in_universe, I: Interne ) } -/// Force the whole constraint to be ambiguous if it contains ambiguities which could -/// have caused the constraint to be `false` if they had been `false` themselves. -/// -/// For example if we have `'a: 'b AND ambig` it's possible that if we had more inference -/// information we could have produced a better region constraint than `ambig`, and that -/// constraint may then have gone on to be false, at which point we would have `'a: 'b AND false` -/// causing the whole constraint to be `false`. -/// -/// If we're not careful we can wind up returning `'a: 'b AND ambig` from passing trait solver -/// goals and then upon rerunning wind up returning `NoSolution` which would be dubious :3 -/// -/// This is inherently conservative and this method should be called as little as possible as it -/// can cause us to get ambiguities instead of `NoSolution` (for example if `'a: 'b` is `false`), -/// which can affect coherence, candidate selection, etc. -/// -/// FIXME(-Zassumptions-on-binders): this method should probably be trait-solver internal as it only -/// matters at trait solver query boundaries. We currently call it in more than just that location -#[instrument(level = "debug", ret)] -pub fn propagate_ambiguity( - constraint: RegionConstraint, -) -> RegionConstraint { - if let Some(ambig) = constraint.and_constraint.0.iter().find(|c| c.is_ambig()) { - return RegionConstraint::new_leaf(ambig.clone()); - } - - for and in constraint.or_constraint.0.iter() { - // FIXME(-Zassumptions-on-binders): This is overly conservative. If we have: - // `'a: 'b OR ambig` we don't necessarily want to propagate ambiguity here - // as we might end up with `'a: 'b` being satisfied in which case we unnecessarily - // errored here. - // - // It's fine if the `ambig` wound up being `false` as that wouldn't cause a goal to - // become `NoSolution`, it would instead result in us returning the `'a: 'b` constraint - // by itself. - // - // `rust-lang/project-assumptions-on-binders#21` - if let Some(ambig) = and.0.iter().find(|c| c.is_ambig()) { - return RegionConstraint::new_leaf(ambig.clone()); - } - } - - constraint -} - /// Handles converting region outlives constraints involving placeholders from `u` into OR constraints /// involving regions from smaller universes with known relationships to the placeholder. For example: /// ```ignore (not rust) @@ -715,7 +670,7 @@ fn pull_region_outlives_constraints_out_of_universe< infcx: &Infcx, constraint: RegionConstraint, u: UniverseIndex, - assumptions: &Option>, + assumptions: &Assumptions, ) -> RegionConstraint { assert!(max_universe(infcx, constraint.clone()) <= u); @@ -745,14 +700,6 @@ fn pull_region_outlives_constraints_out_of_universe< continue; } - let assumptions = match assumptions { - Some(assumptions) => assumptions, - None => { - pulled_constraints.push(Or::new_ambig(())); - continue; - } - }; - // The constraint may already be entailed by the assumptions of the binder we are // leaving, e.g. `for<'a, 'b> where 'b: 'a { 'b: 'a }`. There is nothing to lift into // a smaller universe in that case, and looking for lower universe candidates would @@ -875,7 +822,7 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling< infcx: &Infcx, constraint: RegionConstraint, u: UniverseIndex, - assumptions: &Option>, + assumptions: &Assumptions, ) -> RegionConstraint { use LeafRegionConstraint::*; @@ -920,7 +867,7 @@ fn rewrite_placeholder_ty_outlives_constraints_in_universe_for_eager_placeholder ty: I::Ty, region: Region, u: UniverseIndex, - assumptions: &Option>, + assumptions: &Assumptions, ) -> Or { use LeafRegionConstraint::*; @@ -931,11 +878,6 @@ fn rewrite_placeholder_ty_outlives_constraints_in_universe_for_eager_placeholder return Or::new_leaf(PlaceholderTyOutlives(ty, region, ())); } - let assumptions = match assumptions { - Some(assumptions) => assumptions, - None => return Or::new_ambig(()), - }; - let mut candidates = vec![]; // There could be `!T: 'region` assumptions in the env even if `!T` is in a @@ -966,7 +908,7 @@ fn rewrite_alias_ty_outlives_constraints_in_universe_for_eager_placeholder_handl infcx: &Infcx, bound_outlives: Binder, Region)>, u: UniverseIndex, - assumptions: &Option>, + assumptions: &Assumptions, ) -> Or { use LeafRegionConstraint::*; @@ -1016,14 +958,6 @@ fn rewrite_alias_ty_outlives_constraints_in_universe_for_eager_placeholder_handl } } - let assumptions = match assumptions { - Some(assumptions) => assumptions, - None => { - candidates.push(Or::new_ambig(())); - return candidates.into_iter().fold(Or::new_false(), |acc, c| Or::build_or(acc, c)); - } - }; - // Actually look at the assumptions and matching our higher ranked alias outlives goal // against potentially higher ranked type outlives assumptions. candidates.push(alias_outlives_candidates_from_assumptions(infcx, bound_outlives, assumptions)); @@ -1274,14 +1208,14 @@ impl<'a, Infcx: InferCtxtLike, I: Interner> TypeRelation { self.infcx.enter_forall_with_empty_assumptions(a, |a| { let u = self.infcx.universe(); - self.infcx.insert_placeholder_assumptions(u, Some(Assumptions::empty())); + self.infcx.insert_placeholder_assumptions(u, Assumptions::empty()); let b = self.infcx.instantiate_binder_with_infer(b); self.relate(a, b) })?; self.infcx.enter_forall_with_empty_assumptions(b, |b| { let u = self.infcx.universe(); - self.infcx.insert_placeholder_assumptions(u, Some(Assumptions::empty())); + self.infcx.insert_placeholder_assumptions(u, Assumptions::empty()); let a = self.infcx.instantiate_binder_with_infer(a); self.relate(a, b) })?; diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index aa84f6bc28023..6ebbc6afc1661 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -72,12 +72,16 @@ pub struct FileDesc(OwnedFd); // // On Apple targets however, apparently the 64-bit libc is either buggy or // intentionally showing odd behavior by rejecting any read with a size -// larger than INT_MAX. To handle both of these the read size is capped on -// both platforms. -const READ_LIMIT: usize = if cfg!(target_vendor = "apple") { - libc::c_int::MAX as usize -} else { - libc::ssize_t::MAX as usize +// larger than INT_MAX. +// +// Meanwhile on QNX, reads/writes/sends larger than INT_MAX return the wrong +// number of bytes written (eg, writing 2^31 bytes returns (2^64 - 2^31) instead +// of the correct byte count). +const READ_LIMIT: usize = cfg_select! { + any(target_vendor = "apple", target_os = "nto", target_os = "qnx") => { + libc::c_int::MAX as usize + } + _ => libc::ssize_t::MAX as usize, }; #[cfg(any( diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index 4e5de0209ad24..55db60fde694d 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -36,8 +36,26 @@ cfg_select! { use netc as c; +// Similarly to reads (see READ_LIMIT), the `send` syscall on most platforms +// takes a `size_t` length, but returns an `ssize_t` of bytes written. So the +// actual maximum number of bytes we can send in one call is SSIZE_MAX. +// +// On Apple targets however, apparently the 64-bit libc is either buggy or +// intentionally showing odd behavior by rejecting send calls with a size +// larger than INT_MAX. So cap the send size to INT_MAX. +// +// Meanwhile on QNX, reads/writes/sends larger than INT_MAX return the wrong +// number of bytes written (eg, writing 2^31 bytes returns (2^64 - 2^31) instead +// of the correct byte count). +// +// On Windows, the relevant syscall takes an `i32` (unlike for read/write!), +// so we need to clamp to i32::MAX. const MAX_SEND_LEN: usize = - if cfg!(target_vendor = "apple") { c_int::MAX as usize } else { ::MAX as usize }; + cfg_select! { + any(target_vendor = "apple", target_os = "nto", target_os = "qnx") => c_int::MAX as usize, + target_os = "windows" => i32::MAX as usize, + _ => libc::ssize_t::MAX as usize, + }; cfg_select! { any( @@ -717,8 +735,6 @@ impl UdpSocket { self.inner.peek_from(buf) } - // `MAX_SEND_LEN` is `usize::MAX` off Apple/Windows, where the guard is a no-op. - #[allow(clippy::absurd_extreme_comparisons)] pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result { if buf.len() > MAX_SEND_LEN { return Err(io::Error::from_raw_os_error(c::EMSGSIZE)); @@ -872,8 +888,6 @@ impl UdpSocket { self.inner.peek(buf) } - // `MAX_SEND_LEN` is `usize::MAX` off Apple/Windows, where the guard is a no-op. - #[allow(clippy::absurd_extreme_comparisons)] pub fn send(&self, buf: &[u8]) -> io::Result { if buf.len() > MAX_SEND_LEN { return Err(io::Error::from_raw_os_error(c::EMSGSIZE)); diff --git a/library/std/src/sys/net/connection/socket/tests.rs b/library/std/src/sys/net/connection/socket/tests.rs index e6f02d7a93859..cc072420b754b 100644 --- a/library/std/src/sys/net/connection/socket/tests.rs +++ b/library/std/src/sys/net/connection/socket/tests.rs @@ -18,13 +18,32 @@ fn no_lookup_host_duplicates() { ); } -// #115325: on Apple, `send` rejects a length > `c_int::MAX` with `EINVAL`, so -// the clamp must not regress to the unbounded `wrlen_t::MAX`. +// On non-Windows platforms, the maximum valid length to pass into `send` is +// not the same as the maximum of the *type* used for the length. Ensure that +// the proper maximum is used, and that we do not regress to simply clamping to +// `wrlen_t::MAX` +// +// On Apple (per 115325), `send` takes a `size_t` length, but rejects any +// length > `c_int::MAX` with `EINVAL`. +// +// On QNX, `send` with length > `c_int::MAX` returns an incorrect count of bytes +// written. +// +// On Windows, `send` takes an `i32` length and returns an `i32`. +// +// On other platforms, `send` takes a `size_t` and returns an `ssize_t`, so +// sends larger then `ssize_t::MAX` will (maybe silently) return bad lengths. #[test] fn max_send_len_within_platform_limit() { - if cfg!(target_vendor = "apple") { - assert_eq!(MAX_SEND_LEN, c_int::MAX as usize); - } else { - assert_eq!(MAX_SEND_LEN, ::MAX as usize); + cfg_select! { + any(target_vendor = "apple", target_os = "nto", target_os = "qnx") => { + assert_eq!(MAX_SEND_LEN, c_int::MAX as usize); + } + target_os = "windows" => { + assert_eq!(MAX_SEND_LEN, i32::MAX as usize); + } + _ => { + assert_eq!(MAX_SEND_LEN, libc::ssize_t::MAX as usize); + } } } diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 8b98d0d31e507..e9d5336001fd8 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -309,7 +309,7 @@ impl Socket { ) -> io::Result<(usize, SocketAddr)> { let mut storage = unsafe { mem::zeroed::() }; let mut addrlen = size_of_val(&storage) as netc::socklen_t; - let length = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; + let length = cmp::min(buf.len(), super::MAX_SEND_LEN) as wrlen_t; // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index 930f114f1a70e..e01ff61eb6f86 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -1,5 +1,6 @@ use std::env::consts::EXE_EXTENSION; use std::fmt::{Display, Formatter}; +use std::path::PathBuf; use crate::core::build_steps::compile::Sysroot; use crate::core::build_steps::tool::{RustcPerf, Rustdoc}; @@ -50,6 +51,9 @@ enum PerfCommand { /// The name of the modified artifact to be compared. modified: String, + + #[clap(long, global = true)] + database_path: Option, }, } @@ -87,6 +91,9 @@ struct SharedOpts { /// Select the profiles that should be benchmarked. #[clap(long, global = true, value_delimiter = ',', default_value = "Check,Debug,Opt")] profiles: Vec, + + #[clap(long, global = true)] + database_path: Option, } #[derive(Clone, Copy, Debug, PartialEq, clap::ValueEnum)] @@ -152,7 +159,17 @@ pub fn perf(builder: &Builder<'_>, args: &PerfArgs, trailing_args: &[String]) { // with compile-time benchmarks. cmd.current_dir(builder.src.join("src/tools/rustc-perf")); - let db_path = results_dir.join("results.db"); + let db_path = args + .cmd + .shared_opts() + .and_then(|i| i.database_path.as_ref()) + .or(if let PerfCommand::Compare { database_path: Some(path), .. } = &args.cmd { + Some(path) + } else { + None + }) + .map(|i| PathBuf::from(i.as_str())) + .unwrap_or_else(|| results_dir.join("results.db")); let is_profiling = match &args.cmd { PerfCommand::Eprintln { .. } @@ -214,7 +231,7 @@ Consider setting `rust.debuginfo-level = 1` in `bootstrap.toml`."#); cmd.args(trailing_args); cmd.run(builder); } - PerfCommand::Compare { base, modified } => { + PerfCommand::Compare { base, modified, database_path: _ } => { cmd.arg("bench_cmp"); cmd.arg("--db").arg(&db_path); cmd.arg(base).arg(modified); diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index 58c5e4255caf6..4ce38dd42033a 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -920,6 +920,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l database-path -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l config -d 'TOML configuration file for build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build -d 'host target of the stage0 compiler' -r -f @@ -959,6 +960,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l database-path -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l config -d 'TOML configuration file for build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build -d 'host target of the stage0 compiler' -r -f @@ -998,6 +1000,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l database-path -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l config -d 'TOML configuration file for build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build -d 'host target of the stage0 compiler' -r -f @@ -1037,6 +1040,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l database-path -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l config -d 'TOML configuration file for build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build -d 'host target of the stage0 compiler' -r -f @@ -1072,6 +1076,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l database-path -r complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build -d 'host target of the stage0 compiler' -r -f diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index bf7ed50a85b90..61a4d0d65de91 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -1093,6 +1093,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1140,6 +1141,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1187,6 +1189,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1234,6 +1237,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1277,6 +1281,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { break } 'x;perf;compare' { + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 292408fbe49f6..28b1767fc0e96 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -920,6 +920,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l database-path -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build -d 'host target of the stage0 compiler' -r -f @@ -959,6 +960,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l database-path -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build -d 'host target of the stage0 compiler' -r -f @@ -998,6 +1000,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l database-path -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build -d 'host target of the stage0 compiler' -r -f @@ -1037,6 +1040,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l exclude -d 'Select the benchmarks matching a prefix in this comma-separated list that you don\'t want to run' -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',DocJson\t'',Opt\t'',Clippy\t''}" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l database-path -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build -d 'host target of the stage0 compiler' -r -f @@ -1072,6 +1076,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l database-path -r complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build -d 'host target of the stage0 compiler' -r -f diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index 5ab4cab3a32a3..7178833189ac6 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -1093,6 +1093,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1140,6 +1141,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1187,6 +1189,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1234,6 +1237,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'Select the benchmarks matching a prefix in this comma-separated list that you don''t want to run') [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') @@ -1277,6 +1281,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { break } 'x.py;perf;compare' { + [CompletionResult]::new('--database-path', '--database-path', [CompletionResultType]::ParameterName, 'database-path') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index 0c449988b0461..f1b35e4cbc894 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -3094,7 +3094,7 @@ _x.py() { return 0 ;; x.py__perf__benchmark) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3116,6 +3116,10 @@ _x.py() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3292,7 +3296,7 @@ _x.py() { return 0 ;; x.py__perf__cachegrind) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3314,6 +3318,10 @@ _x.py() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3490,12 +3498,16 @@ _x.py() { return 0 ;; x.py__perf__compare) - opts="-v -q -i -j -h --verbose --quiet --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3676,7 +3688,7 @@ _x.py() { return 0 ;; x.py__perf__eprintln) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3698,6 +3710,10 @@ _x.py() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3874,7 +3890,7 @@ _x.py() { return 0 ;; x.py__perf__samply) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3896,6 +3912,10 @@ _x.py() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 9ee5843a5abd7..8376e44746052 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -1123,6 +1123,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1172,6 +1173,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1221,6 +1223,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1270,6 +1273,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1316,6 +1320,7 @@ _arguments "${_arguments_options[@]}" : \ ;; (compare) _arguments "${_arguments_options[@]}" : \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh index f8897cc5f5ec8..be81e2e743e7c 100644 --- a/src/etc/completions/x.sh +++ b/src/etc/completions/x.sh @@ -3094,7 +3094,7 @@ _x() { return 0 ;; x__perf__benchmark) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3116,6 +3116,10 @@ _x() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3292,7 +3296,7 @@ _x() { return 0 ;; x__perf__cachegrind) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3314,6 +3318,10 @@ _x() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3490,12 +3498,16 @@ _x() { return 0 ;; x__perf__compare) - opts="-v -q -i -j -h --verbose --quiet --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3676,7 +3688,7 @@ _x() { return 0 ;; x__perf__eprintln) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3698,6 +3710,10 @@ _x() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then @@ -3874,7 +3890,7 @@ _x() { return 0 ;; x__perf__samply) - opts="-v -q -i -j -h --include --exclude --scenarios --profiles --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -q -i -j -h --include --exclude --scenarios --profiles --database-path --verbose --quiet --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3896,6 +3912,10 @@ _x() { COMPREPLY=($(compgen -W "Check Debug Doc DocJson Opt Clippy" -- "${cur}")) return 0 ;; + --database-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) local oldifs if [ -n "${IFS+x}" ]; then diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index f61942a11da4a..3159859c1ea8e 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -1123,6 +1123,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1172,6 +1173,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1221,6 +1223,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1270,6 +1273,7 @@ _arguments "${_arguments_options[@]}" : \ '*--exclude=[Select the benchmarks matching a prefix in this comma-separated list that you don'\''t want to run]:EXCLUDE:_default' \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc DocJson Opt Clippy)' \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ @@ -1316,6 +1320,7 @@ _arguments "${_arguments_options[@]}" : \ ;; (compare) _arguments "${_arguments_options[@]}" : \ +'--database-path=[]:DATABASE_PATH:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ '--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[host target of the stage0 compiler]:BUILD:' \ diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ea29a66c958a3..0a6c4ce6414a1 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -348,7 +348,7 @@ pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box ExpandedCodeVisitor<'ast> { } fn compute_expanded(mut self) -> FxHashMap> { - self.expanded_codes.sort_unstable_by(|item1, item2| item1.span.cmp(&item2.span)); + self.expanded_codes.sort_unstable_by_key(|item| item.span.lo_hi()); let mut expanded: FxHashMap> = FxHashMap::default(); for ExpandedCodeInfo { span, code, original_span, .. } in self.expanded_codes { if let Ok(lines) = self.source_map.span_to_lines(span) diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs index 93f079f7351db..fe0e8c98b46e0 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs @@ -77,7 +77,7 @@ impl EarlyLintPass for DisallowedScriptIdents { // Sort by `Span` so that error messages make sense with respect to the // order of identifier locations in the code. let mut symbols: Vec<_> = symbols.iter().collect(); - symbols.sort_unstable_by_key(|k| k.1); + symbols.sort_unstable_by_key(|k| k.1.lo_hi()); for &(symbol, &span) in &symbols { // Note: `symbol.as_str()` is an expensive operation, thus should not be called diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs index 22be9d8367daa..a072e3dfff503 100644 --- a/src/tools/clippy/clippy_lints/src/format_args.rs +++ b/src/tools/clippy/clippy_lints/src/format_args.rs @@ -610,8 +610,8 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> { .any(|(span, _)| self.cx.sess().source_map().is_multiline(*span)); // Suggest removing each argument only once, for example in `format!("{0} {0}", arg)`. - fixes.sort_unstable_by_key(|(span, _)| *span); - fixes.dedup_by_key(|(span, _)| *span); + fixes.sort_unstable_by_key(|(span, _)| span.lo_hi()); + fixes.dedup_by_key(|(span, _)| span.lo_hi()); span_lint_and_then( self.cx, diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs index 02f8170fedc27..b511caf6b5299 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs @@ -9,7 +9,7 @@ use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{Ty, TypeckResults}; -use rustc_span::Span; +use rustc_span::{OrdSpan, Span}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{IntoSpan as _, SpanExt as _, snippet, snippet_with_context}; @@ -94,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { format!("{}<{}, S>", target.type_name(), target.type_arguments()), ), ]; - suggestions.extend(vis.suggestions); + suggestions.extend(vis.suggestions.into_iter().map(|(span, s)| (span.0, s))); diag.multipart_suggestion( "add a type parameter for `BuildHasher`", @@ -295,7 +295,7 @@ struct ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { cx: &'a LateContext<'tcx>, maybe_typeck_results: Option<&'tcx TypeckResults<'tcx>>, target: &'b ImplicitHasherType<'tcx>, - suggestions: BTreeMap, + suggestions: BTreeMap, } impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { @@ -337,7 +337,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { match method.ident.name { sym::new => { - self.suggestions.insert(e.span, format!("{container_name}::default()")); + self.suggestions.insert(OrdSpan(e.span), format!("{container_name}::default()")); }, sym::with_capacity => { let (arg_snippet, _) = snippet_with_context( @@ -350,7 +350,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> { &mut Applicability::MaybeIncorrect, ); self.suggestions.insert( - e.span, + OrdSpan(e.span), format!("{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())"), ); }, diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index 73e430fa08d6b..8b6c99cc122c9 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -1,3 +1,5 @@ +use std::cmp::max_by_key; + use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; use rustc_errors::{Applicability, SuggestionStyle}; @@ -96,7 +98,9 @@ fn emit_lint( // `<>` needs to be added if there aren't yet any generic arguments or constraints let needs_angle_brackets = bound.args.is_empty() && bound.constraints.is_empty(); let insert_span = match (bound.args, bound.constraints) { - ([.., arg], [.., constraint]) => arg.span().max(constraint.span).shrink_to_hi(), + ([.., arg], [.., constraint]) => { + max_by_key(arg.span(), constraint.span, |span| span.lo_hi()).shrink_to_hi() + } ([.., arg], []) => arg.span().shrink_to_hi(), ([], [.., constraint]) => constraint.span.shrink_to_hi(), ([], []) => bound.span.shrink_to_hi(), diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs index 8242c383140a6..82af5d67e6f23 100644 --- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs +++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt}; use rustc_hir::{BlockCheckMode, Expr, ExprKind, HirId, Stmt, UnsafeSource}; use rustc_lint::{LateContext, LateLintPass, LintContext as _, impl_lint_pass}; -use rustc_span::{Span, SyntaxContext}; +use rustc_span::{OrdSpan, Span, SyntaxContext}; use std::collections::BTreeMap; use std::collections::btree_map::Entry; @@ -106,7 +106,7 @@ pub struct ExprMetavarsInUnsafe { /// } /// } /// ``` - metavar_expns: BTreeMap, + metavar_expns: BTreeMap, } impl ExprMetavarsInUnsafe { @@ -180,7 +180,7 @@ impl<'tcx> Visitor<'tcx> for BodyVisitor<'_, 'tcx> { } else if ctxt.is_root() && self.expn_depth > 0 { let unsafe_block = self.macro_unsafe_blocks.last().copied(); - match (self.lint.metavar_expns.entry(e.span), unsafe_block) { + match (self.lint.metavar_expns.entry(OrdSpan(e.span)), unsafe_block) { (Entry::Vacant(e), None) => { e.insert(MetavarState::ReferencedInSafe); }, diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 2d5605371ac1a..21f110f4155f6 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{self as hir, AmbigArg, UseTree}; use rustc_lint::{LateContext, LateLintPass, LintContext as _, impl_lint_pass}; -use rustc_span::Span; +use rustc_span::{OrdSpan, Span}; use rustc_span::edition::Edition; use std::collections::BTreeMap; @@ -151,7 +151,7 @@ impl LateLintPass<'_> for MacroUseImports { if !check_dup.contains(&(*item).to_string()) { used.entry(( (*root).to_string(), - span, + OrdSpan(*span), hir_id.local_id, cx.tcx.def_path_hash(hir_id.owner.def_id.into()), )) @@ -175,7 +175,7 @@ impl LateLintPass<'_> for MacroUseImports { .collect::>(); used.entry(( (*root).to_string(), - span, + OrdSpan(*span), hir_id.local_id, cx.tcx.def_path_hash(hir_id.owner.def_id.into()), )) @@ -187,7 +187,7 @@ impl LateLintPass<'_> for MacroUseImports { let rest = rest.to_vec(); used.entry(( (*root).to_string(), - span, + OrdSpan(*span), hir_id.local_id, cx.tcx.def_path_hash(hir_id.owner.def_id.into()), )) @@ -215,11 +215,11 @@ impl LateLintPass<'_> for MacroUseImports { cx, MACRO_USE_IMPORTS, *hir_id, - *span, + span.0, "`macro_use` attributes are no longer needed in the Rust 2018 edition", |diag| { diag.span_suggestion( - *span, + span.0, "remove the attribute and import the macro directly, try", format!("use {import};"), Applicability::MaybeIncorrect, diff --git a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs index b58ceb263be22..7dfe8202a12d4 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs @@ -187,7 +187,7 @@ impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> { // If we haven't found a reference yet, check if this references // one of the locals that was moved in the `unwrap_or` argument. // We are only interested in exprs that appear before the `unwrap_or` call. - if expr.span < self.unwrap_or_span + if expr.span.lo_hi() < self.unwrap_or_span.lo_hi() && let ExprKind::Path(ref path) = expr.kind && let QPath::Resolved(_, path) = path && let Res::Local(local_id) = path.res diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs index edb1c9c53ded7..c7207bb4dd4bc 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs @@ -373,7 +373,7 @@ fn check_option_fold<'tcx>( // `.iter().fold(` -> `.as_ref().map_or(`, drop the accumulator // parameter, and substitute `init` for each use of the accumulator. - acc_uses.sort(); + acc_uses.sort_by_key(|span| span.lo_hi()); let mut parts = vec![ ( recv.span.with_lo(option_expr.span.hi()).with_hi(init.span.lo()), diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs index bf649ff5e249c..19c3abd2576f6 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -122,7 +122,7 @@ impl<'tcx> UnsafeExprCollector<'tcx> { .into_iter() .map(|(span, msg)| (msg, span)) .collect::>(); - unsafe_ops.sort_unstable(); + unsafe_ops.sort_unstable_by_key(|(s, span)| (*s, span.lo_hi())); unsafe_ops } diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs index 968f6ad679b59..47708e8f02d19 100644 --- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs +++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs @@ -111,7 +111,7 @@ fn check_op(cx: &LateContext<'_>, outer: &Expr<'_>, expr: &Expr<'_>, other: &Exp } else { let span = expr.span.to(other.span); - let cmp_span = if other.span < expr.span { + let cmp_span = if other.span.lo_hi() < expr.span.lo_hi() { other.span.between(expr.span) } else { expr.span.between(other.span) diff --git a/src/tools/clippy/clippy_lints/src/useless_vec.rs b/src/tools/clippy/clippy_lints/src/useless_vec.rs index 3d2f47cee4670..0b526010d2cce 100644 --- a/src/tools/clippy/clippy_lints/src/useless_vec.rs +++ b/src/tools/clippy/clippy_lints/src/useless_vec.rs @@ -16,7 +16,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pa use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::ty; use rustc_middle::ty::layout::LayoutOf as _; -use rustc_span::{DesugaringKind, Span}; +use rustc_span::{DesugaringKind, OrdSpan, Span}; pub struct UselessVec { too_large_for_stack: u64, @@ -41,7 +41,7 @@ pub struct UselessVec { /// the first `vec![1, 2]` (which is shared with the other expn) to an array which indeed would /// work, we get a false positive warning on the `$v.push(3)` which really requires `$v` to /// be a vector. - span_to_state: BTreeMap, + span_to_state: BTreeMap, allow_in_test: bool, } @@ -223,7 +223,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { }, }; - if let Entry::Vacant(entry) = self.span_to_state.entry(vec_span) { + if let Entry::Vacant(entry) = self.span_to_state.entry(OrdSpan(vec_span)) { entry.insert(VecState::Change { suggest_ty, vec_snippet, @@ -232,7 +232,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { } }, VecToArray::Impossible => { - self.span_to_state.insert(vec_span, VecState::NoChange); + self.span_to_state.insert(OrdSpan(vec_span), VecState::NoChange); }, } } @@ -246,6 +246,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { expr_hir_id, } = state { + let span = span.0; span_lint_hir_and_then(cx, USELESS_VEC, expr_hir_id, span, "useless use of `vec!`", |diag| { let help_msg = format!("you can use {} directly", suggest_ty.desc()); // If the `vec!` macro contains comment, better not make the suggestion machine applicable as it diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index f9ca42dfa0e1f..cef93e9653430 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -171,15 +171,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Make sure we are consistent wrt what is 'first' and 'second'. let original_span = - tcx.def_span(original.instance.def_id()).data(); - let span = tcx.def_span(def_id).data(); - if original_span < span { + tcx.def_span(original.instance.def_id()); + let span = tcx.def_span(def_id); + if original_span.lo_hi() < span.lo_hi() { throw_machine_stop!( TerminationInfo::MultipleSymbolDefinitions { link_name, - first: original_span, + first: original_span.data(), first_crate: tcx.crate_name(original.cnum), - second: span, + second: span.data(), second_crate: tcx.crate_name(cnum), } ); @@ -187,9 +187,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_machine_stop!( TerminationInfo::MultipleSymbolDefinitions { link_name, - first: span, + first: span.data(), first_crate: tcx.crate_name(cnum), - second: original_span, + second: original_span.data(), second_crate: tcx.crate_name(original.cnum), } ); diff --git a/tests/ui/associated-inherent-types/ice-normalize-inherent-assoc-const.rs b/tests/ui/associated-inherent-types/ice-normalize-inherent-assoc-const.rs new file mode 100644 index 0000000000000..a7b430f85a9a2 --- /dev/null +++ b/tests/ui/associated-inherent-types/ice-normalize-inherent-assoc-const.rs @@ -0,0 +1,19 @@ +//! Regression test for: https://github.com/rust-lang/rust/issues/142722. + +#![feature(trivial_bounds)] +#![feature(generic_const_exprs)] +#![feature(gca_min_const_items)] +#![feature(inherent_associated_types)] + +struct Foo; +impl Foo { + const ASSOC_C: usize = todo!(); + //~^ ERROR evaluation panicked: not yet implemented + fn foo() + where + [u8; Self::ASSOC_C]:, + { + } +} + +pub fn main() {} diff --git a/tests/ui/associated-inherent-types/ice-normalize-inherent-assoc-const.stderr b/tests/ui/associated-inherent-types/ice-normalize-inherent-assoc-const.stderr new file mode 100644 index 0000000000000..5ce8a67bc7810 --- /dev/null +++ b/tests/ui/associated-inherent-types/ice-normalize-inherent-assoc-const.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation panicked: not yet implemented + --> $DIR/ice-normalize-inherent-assoc-const.rs:10:28 + | +LL | const ASSOC_C: usize = todo!(); + | ^^^^^^^ evaluation of `Foo::ASSOC_C` failed here + +note: erroneous constant encountered + --> $DIR/ice-normalize-inherent-assoc-const.rs:14:14 + | +LL | [u8; Self::ASSOC_C]:, + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/attributes/link-foreign-mod-abi.rs b/tests/ui/attributes/link-foreign-mod-abi.rs new file mode 100644 index 0000000000000..83d0a2dd47f0b --- /dev/null +++ b/tests/ui/attributes/link-foreign-mod-abi.rs @@ -0,0 +1,45 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib + +#![no_core] +#![feature(no_core, rust_cold_cc, rust_preserve_none_cc, rust_tail_cc, unboxed_closures)] +#![allow(missing_abi)] +#![deny(unfulfilled_lint_expectations, unused_attributes)] + +#[link(name = "omitted")] +extern {} + +#[link(name = "c")] +extern "C" {} + +#[link(name = "rust-call")] +extern "rust-call" {} + +#[link(name = "rust-cold")] +extern "rust-cold" {} + +#[link(name = "rust-preserve-none")] +extern "rust-preserve-none" {} + +#[link(name = "tail")] +extern "tail" {} + +#[cfg_attr(any(), link(name = "disabled"))] +extern "Rust" {} + +#[expect(unused_attributes)] +#[cfg_attr(all(), link(name = "enabled"))] +extern "Rust" {} + +#[allow(unused_attributes)] +#[link(name = "allowed")] +extern "Rust" {} + +#[expect(unused_attributes)] +#[link(name = "expected")] +extern "Rust" {} + +#[expect(unused_attributes)] +#[link(name = "first")] +#[link(name = "second")] +extern "Rust" {} diff --git a/tests/ui/attributes/link-invalid-abi.rs b/tests/ui/attributes/link-invalid-abi.rs new file mode 100644 index 0000000000000..49f91236c1a2b --- /dev/null +++ b/tests/ui/attributes/link-invalid-abi.rs @@ -0,0 +1,13 @@ +//@ check-fail +//@ compile-flags: --crate-type=lib + +#![no_core] +#![feature(no_core)] +#![warn(unused_attributes)] + +#[link(name = "first")] +//~^ WARN +//~| WARN +#[link(name = "second")] +extern "invalid" {} +//~^ ERROR diff --git a/tests/ui/attributes/link-invalid-abi.stderr b/tests/ui/attributes/link-invalid-abi.stderr new file mode 100644 index 0000000000000..add2ebcb7c186 --- /dev/null +++ b/tests/ui/attributes/link-invalid-abi.stderr @@ -0,0 +1,24 @@ +error[E0703]: invalid ABI: found `invalid` + --> $DIR/link-invalid-abi.rs:12:8 + | +LL | extern "invalid" {} + | ^^^^^^^^^ invalid ABI + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions + +warning: attribute should be applied to an `extern` block with non-Rust ABI + --> $DIR/link-invalid-abi.rs:8:1 + | +LL | #[link(name = "first")] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/link-invalid-abi.rs:6:9 + | +LL | #![warn(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs index 0864776ab49fd..52da0f38017a0 100644 --- a/tests/ui/delegation/bad-resolve.rs +++ b/tests/ui/delegation/bad-resolve.rs @@ -43,7 +43,13 @@ impl Trait for S { mod prefix {} reuse unresolved_prefix::{a, b, c}; //~ ERROR cannot find module or crate `unresolved_prefix` +//~| ERROR failed to resolve delegation callee +//~| ERROR failed to resolve delegation callee +//~| ERROR failed to resolve delegation callee reuse prefix::{self, super, crate}; //~ ERROR `crate` in paths can only be used in start position -//~^ ERROR cannot find function `self` in module `prefix` +//~| ERROR failed to resolve delegation callee +//~| ERROR failed to resolve delegation callee +//~| ERROR cannot find function `self` in module `prefix` +//~| ERROR failed to resolve delegation callee fn main() {} diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index 9740442e4b9f3..9756a009ec9b9 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -72,13 +72,49 @@ LL | reuse foo { &self.0 } | ^^^ not found in this scope error[E0423]: cannot find function `self` in module `prefix` - --> $DIR/bad-resolve.rs:46:16 + --> $DIR/bad-resolve.rs:49:16 | LL | reuse prefix::{self, super, crate}; | ^^^^ not found in `prefix` | = note: a module named `prefix::self` exists in another namespace +error: failed to resolve delegation callee + --> $DIR/bad-resolve.rs:45:27 + | +LL | reuse unresolved_prefix::{a, b, c}; + | ^ + +error: failed to resolve delegation callee + --> $DIR/bad-resolve.rs:45:30 + | +LL | reuse unresolved_prefix::{a, b, c}; + | ^ + +error: failed to resolve delegation callee + --> $DIR/bad-resolve.rs:45:33 + | +LL | reuse unresolved_prefix::{a, b, c}; + | ^ + +error: failed to resolve delegation callee + --> $DIR/bad-resolve.rs:49:16 + | +LL | reuse prefix::{self, super, crate}; + | ^^^^ + +error: failed to resolve delegation callee + --> $DIR/bad-resolve.rs:49:22 + | +LL | reuse prefix::{self, super, crate}; + | ^^^^^ + +error: failed to resolve delegation callee + --> $DIR/bad-resolve.rs:49:29 + | +LL | reuse prefix::{self, super, crate}; + | ^^^^^ + error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl --> $DIR/bad-resolve.rs:34:11 | @@ -152,12 +188,12 @@ LL | reuse unresolved_prefix::{a, b, c}; = help: you might be missing a crate named `unresolved_prefix` error[E0433]: `crate` in paths can only be used in start position - --> $DIR/bad-resolve.rs:46:29 + --> $DIR/bad-resolve.rs:49:29 | LL | reuse prefix::{self, super, crate}; | ^^^^^ can only be used in path start position -error: aborting due to 14 previous errors; 1 warning emitted +error: aborting due to 20 previous errors; 1 warning emitted Some errors have detailed explanations: E0038, E0046, E0186, E0324, E0407, E0423, E0425, E0433, E0575... For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/delegation/delegation-inherent-impl-issue-162774.rs b/tests/ui/delegation/delegation-inherent-impl-issue-162774.rs new file mode 100644 index 0000000000000..32432babd7b63 --- /dev/null +++ b/tests/ui/delegation/delegation-inherent-impl-issue-162774.rs @@ -0,0 +1,18 @@ +#![feature(fn_delegation)] + +trait Trait { + fn foo(&self) {} +} + +struct F; +impl Trait for F {} + +struct S(F); + +impl S { + reuse Trait::foo { self.0 } + reuse Self::foo::<> as bar { self } + //~^ ERROR failed to resolve delegation callee +} + +fn main() {} diff --git a/tests/ui/delegation/delegation-inherent-impl-issue-162774.stderr b/tests/ui/delegation/delegation-inherent-impl-issue-162774.stderr new file mode 100644 index 0000000000000..b2c0f53163470 --- /dev/null +++ b/tests/ui/delegation/delegation-inherent-impl-issue-162774.stderr @@ -0,0 +1,8 @@ +error: failed to resolve delegation callee + --> $DIR/delegation-inherent-impl-issue-162774.rs:14:17 + | +LL | reuse Self::foo::<> as bar { self } + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.rs b/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.rs index a35386fa3720e..73c18e5690fd1 100644 --- a/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.rs +++ b/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.rs @@ -18,7 +18,7 @@ impl Iterator { //~^ ERROR: expected a type, found a trait [E0782] - reuse< < fn()>::Output>::Item as Iterator>::*; + reuse< < fn()>::Output>::Item as Iterator>::*; //~ ERROR failed to resolve delegation callee //~^ ERROR: cannot find method or associated constant `Item` in trait `Iterator` //~| ERROR: ambiguous associated type } diff --git a/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.stderr b/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.stderr index 99bb6ac7e66be..50eaca19144be 100644 --- a/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.stderr +++ b/tests/ui/delegation/generics/def-path-hash-collision-ice-153410.stderr @@ -6,6 +6,12 @@ LL | reuse< < fn()>::Output>::Item as Iterator>::*; | = note: an associated type named `Iterator::Item` exists in another namespace +error: failed to resolve delegation callee + --> $DIR/def-path-hash-collision-ice-153410.rs:21:58 + | +LL | reuse< < fn()>::Output>::Item as Iterator>::*; + | ^ + error[E0782]: expected a type, found a trait --> $DIR/def-path-hash-collision-ice-153410.rs:19:6 | @@ -36,7 +42,7 @@ LL - reuse< < fn()>::Output>::Item as Iterator>::*; LL + reuse< < ::Output>::Item as Iterator>::*; | -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0223, E0575, E0782. For more information about an error, try `rustc --explain E0223`. diff --git a/tests/ui/delegation/generics/synth-params-ice-143498.rs b/tests/ui/delegation/generics/synth-params-ice-143498.rs index 366451ccdc012..2216f05f6c31f 100644 --- a/tests/ui/delegation/generics/synth-params-ice-143498.rs +++ b/tests/ui/delegation/generics/synth-params-ice-143498.rs @@ -18,7 +18,7 @@ impl X { //~^ ERROR: cannot find type `X` in this scope - reuse< std::fmt::Debug as Iterator >::*; + reuse< std::fmt::Debug as Iterator >::*; //~ ERROR failed to resolve delegation callee //~^ ERROR: cannot find method or associated constant `Item` in trait `Iterator` //~| ERROR: expected a type, found a trait } diff --git a/tests/ui/delegation/generics/synth-params-ice-143498.stderr b/tests/ui/delegation/generics/synth-params-ice-143498.stderr index 8db4a84d76c53..21c5e29ad8707 100644 --- a/tests/ui/delegation/generics/synth-params-ice-143498.stderr +++ b/tests/ui/delegation/generics/synth-params-ice-143498.stderr @@ -12,6 +12,12 @@ LL | reuse< std::fmt::Debug as Iterator >::*; | = note: an associated type named `Iterator::Item` exists in another namespace +error: failed to resolve delegation callee + --> $DIR/synth-params-ice-143498.rs:21:43 + | +LL | reuse< std::fmt::Debug as Iterator >::*; + | ^ + error[E0782]: expected a type, found a trait --> $DIR/synth-params-ice-143498.rs:21:12 | @@ -23,7 +29,7 @@ help: you can add the `dyn` keyword if you want a trait object LL | reuse< dyn std::fmt::Debug as Iterator >::*; | +++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0425, E0575, E0782. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/delegation/ice-issue-124342.rs b/tests/ui/delegation/ice-issue-124342.rs index b5e7d9386d33d..a882b1bd90e6b 100644 --- a/tests/ui/delegation/ice-issue-124342.rs +++ b/tests/ui/delegation/ice-issue-124342.rs @@ -3,7 +3,7 @@ mod to_reuse {} trait Trait { - reuse to_reuse::foo { foo } + reuse to_reuse::foo { foo } //~ ERROR failed to resolve delegation callee //~^ ERROR cannot find function `foo` in module `to_reuse` //~| ERROR cannot find value `foo` in this scope } diff --git a/tests/ui/delegation/ice-issue-124342.stderr b/tests/ui/delegation/ice-issue-124342.stderr index 19d75e494cafe..df2b2ea91f0bd 100644 --- a/tests/ui/delegation/ice-issue-124342.stderr +++ b/tests/ui/delegation/ice-issue-124342.stderr @@ -15,6 +15,12 @@ help: you might have meant to refer to the associated function LL | reuse to_reuse::foo { Self::foo } | ++++++ -error: aborting due to 2 previous errors +error: failed to resolve delegation callee + --> $DIR/ice-issue-124342.rs:6:21 + | +LL | reuse to_reuse::foo { foo } + | ^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.rs b/tests/ui/delegation/ice-line-bounds-issue-148732.rs index 0123f0c8705b0..b8887f6ecbbf5 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.rs +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.rs @@ -1,4 +1,4 @@ -reuse a as b { +reuse a as b { //~ ERROR failed to resolve delegation callee //~^ ERROR cannot find function `a` in this scope //~| ERROR functions delegation is not yet fully implemented dbg!(b); diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr index eb93655beb60d..196f984626ce5 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr @@ -19,6 +19,12 @@ LL | | } = help: add `#![feature(fn_delegation)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error: failed to resolve delegation callee + --> $DIR/ice-line-bounds-issue-148732.rs:1:7 + | +LL | reuse a as b { + | ^ + error[E0277]: `fn() {b}` doesn't implement `Debug` --> $DIR/ice-line-bounds-issue-148732.rs:4:5 | @@ -30,7 +36,7 @@ LL | dbg!(b); | = help: use parentheses to call this function: `b()` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0425, E0658. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/delegation/ice-non-fn-target-in-trait-impl.rs b/tests/ui/delegation/ice-non-fn-target-in-trait-impl.rs index 7a61da79f3c8f..2dac22779c3da 100644 --- a/tests/ui/delegation/ice-non-fn-target-in-trait-impl.rs +++ b/tests/ui/delegation/ice-non-fn-target-in-trait-impl.rs @@ -10,7 +10,7 @@ trait Trait { } impl Trait for () { - reuse std::path::<> as bar; + reuse std::path::<> as bar; //~ ERROR failed to resolve delegation callee //~^ ERROR cannot find function `path` in crate `std` reuse core::<> as bar2; //~^ ERROR cannot find function `core` in this scope diff --git a/tests/ui/delegation/ice-non-fn-target-in-trait-impl.stderr b/tests/ui/delegation/ice-non-fn-target-in-trait-impl.stderr index e9eca6b35bb51..f543f823da157 100644 --- a/tests/ui/delegation/ice-non-fn-target-in-trait-impl.stderr +++ b/tests/ui/delegation/ice-non-fn-target-in-trait-impl.stderr @@ -14,6 +14,12 @@ LL | reuse core::<> as bar2; | = note: a crate named `core` exists in another namespace -error: aborting due to 2 previous errors +error: failed to resolve delegation callee + --> $DIR/ice-non-fn-target-in-trait-impl.rs:13:16 + | +LL | reuse std::path::<> as bar; + | ^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/delegation/inherent-impls-non-local-crate.rs b/tests/ui/delegation/inherent-impls-non-local-crate.rs index 27b8d387a7e63..865bdb877a8a1 100644 --- a/tests/ui/delegation/inherent-impls-non-local-crate.rs +++ b/tests/ui/delegation/inherent-impls-non-local-crate.rs @@ -6,13 +6,17 @@ reuse inherent_impl::S::foo; reuse inherent_impl::S::not_existing; //~^ ERROR: no associated function or constant named `not_existing` found for struct `S` in the current scope +//~| ERROR failed to resolve delegation callee reuse inherent_impl::S::TYPE; //~^ ERROR: no associated function or constant named `TYPE` found for struct `S` in the current scope +//~| ERROR failed to resolve delegation callee reuse inherent_impl::S::CONST; //~^ ERROR: expected function, found `usize` [E0618] +//~| ERROR failed to resolve delegation callee reuse inherent_impl::S::bar; //~^ ERROR: no associated function or constant named `bar` found for struct `S` in the current scope +//~| ERROR failed to resolve delegation callee reuse ::bar as trait_bar; diff --git a/tests/ui/delegation/inherent-impls-non-local-crate.stderr b/tests/ui/delegation/inherent-impls-non-local-crate.stderr index 31358b1d7144e..288f72427c376 100644 --- a/tests/ui/delegation/inherent-impls-non-local-crate.stderr +++ b/tests/ui/delegation/inherent-impls-non-local-crate.stderr @@ -1,5 +1,29 @@ +error: failed to resolve delegation callee + --> $DIR/inherent-impls-non-local-crate.rs:7:25 + | +LL | reuse inherent_impl::S::not_existing; + | ^^^^^^^^^^^^ + +error: failed to resolve delegation callee + --> $DIR/inherent-impls-non-local-crate.rs:10:25 + | +LL | reuse inherent_impl::S::TYPE; + | ^^^^ + +error: failed to resolve delegation callee + --> $DIR/inherent-impls-non-local-crate.rs:13:25 + | +LL | reuse inherent_impl::S::CONST; + | ^^^^^ + +error: failed to resolve delegation callee + --> $DIR/inherent-impls-non-local-crate.rs:17:25 + | +LL | reuse inherent_impl::S::bar; + | ^^^ + error: ambiguous delegation to inherent impl function - --> $DIR/inherent-impls-non-local-crate.rs:19:25 + --> $DIR/inherent-impls-non-local-crate.rs:23:25 | LL | reuse inherent_impl::X::foo as x_foo; | ^^^ @@ -11,19 +35,19 @@ LL | reuse inherent_impl::S::not_existing; | ^^^^^^^^^^^^ associated function or constant not found in `S` error[E0599]: no associated function or constant named `TYPE` found for struct `S` in the current scope - --> $DIR/inherent-impls-non-local-crate.rs:9:25 + --> $DIR/inherent-impls-non-local-crate.rs:10:25 | LL | reuse inherent_impl::S::TYPE; | ^^^^ associated function or constant not found in `S` error[E0618]: expected function, found `usize` - --> $DIR/inherent-impls-non-local-crate.rs:11:25 + --> $DIR/inherent-impls-non-local-crate.rs:13:25 | LL | reuse inherent_impl::S::CONST; | ^^^^^ call expression requires function error[E0599]: no associated function or constant named `bar` found for struct `S` in the current scope - --> $DIR/inherent-impls-non-local-crate.rs:14:25 + --> $DIR/inherent-impls-non-local-crate.rs:17:25 | LL | reuse inherent_impl::S::bar; | ^^^ associated function or constant not found in `S` @@ -35,7 +59,7 @@ LL + use inherent_impl::Trait; | error[E0034]: multiple applicable items in scope - --> $DIR/inherent-impls-non-local-crate.rs:19:25 + --> $DIR/inherent-impls-non-local-crate.rs:23:25 | LL | reuse inherent_impl::X::foo as x_foo; | ^^^ multiple `foo` found @@ -43,7 +67,7 @@ LL | reuse inherent_impl::X::foo as x_foo; = note: candidate #1 is defined in an impl for the type `X` = note: candidate #2 is defined in an impl for the type `X` -error: aborting due to 6 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0034, E0599, E0618. For more information about an error, try `rustc --explain E0034`. diff --git a/tests/ui/delegation/unused-import-ice-144594.rs b/tests/ui/delegation/unused-import-ice-144594.rs index fca67c6ee0b81..f245b409c4999 100644 --- a/tests/ui/delegation/unused-import-ice-144594.rs +++ b/tests/ui/delegation/unused-import-ice-144594.rs @@ -1,6 +1,6 @@ #![feature(fn_delegation)] -reuse a as b { +reuse a as b { //~ ERROR failed to resolve delegation callee //~^ ERROR cannot find function `a` in this scope [E0425] || { use std::ops::Add; diff --git a/tests/ui/delegation/unused-import-ice-144594.stderr b/tests/ui/delegation/unused-import-ice-144594.stderr index f09313aac21f4..27440c0ff83ec 100644 --- a/tests/ui/delegation/unused-import-ice-144594.stderr +++ b/tests/ui/delegation/unused-import-ice-144594.stderr @@ -10,6 +10,12 @@ error[E0425]: cannot find value `x` in this scope LL | x.add | ^ not found in this scope -error: aborting due to 2 previous errors +error: failed to resolve delegation callee + --> $DIR/unused-import-ice-144594.rs:3:7 + | +LL | reuse a as b { + | ^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/delegation/wrong-lifetime-rib.rs b/tests/ui/delegation/wrong-lifetime-rib.rs index e9214b7c42260..ca14583eaa525 100644 --- a/tests/ui/delegation/wrong-lifetime-rib.rs +++ b/tests/ui/delegation/wrong-lifetime-rib.rs @@ -8,7 +8,7 @@ mod ice_156342 { impl Trait { //~^ ERROR: cannot define inherent `impl` for a type outside of the crate where the type is defined - reuse None::<&()>; + reuse None::<&()>; //~ ERROR failed to resolve delegation callee //~^ ERROR: expected function, found unit variant `None` } diff --git a/tests/ui/delegation/wrong-lifetime-rib.stderr b/tests/ui/delegation/wrong-lifetime-rib.stderr index ca759995fec42..447328f579df2 100644 --- a/tests/ui/delegation/wrong-lifetime-rib.stderr +++ b/tests/ui/delegation/wrong-lifetime-rib.stderr @@ -4,6 +4,12 @@ error[E0423]: expected function, found unit variant `None` LL | reuse None::<&()>; | ^^^^^^^^^^^ not a function +error: failed to resolve delegation callee + --> $DIR/wrong-lifetime-rib.rs:11:15 + | +LL | reuse None::<&()>; + | ^^^^ + error: inferred lifetimes are not allowed in delegations as we need to inherit signature --> $DIR/wrong-lifetime-rib.rs:17:18 | @@ -144,7 +150,7 @@ help: you can add the `dyn` keyword if you want a trait object LL | let _: &dyn X; | +++ -error: aborting due to 19 previous errors +error: aborting due to 20 previous errors Some errors have detailed explanations: E0116, E0223, E0423, E0782. For more information about an error, try `rustc --explain E0116`. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index a677339551153..2d3b7658f9aae 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -207,14 +207,6 @@ note: the lint level is defined here LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^^^^^ -warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 - | -LL | #[link(name = "x")] extern "Rust" {} - | ^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - warning: the `macro_use` attribute cannot be used on crates --> $DIR/issue-43106-gating-of-builtin-attrs.rs:45:4 | @@ -978,6 +970,14 @@ LL | #[link(name = "x")] impl S { } = help: the `link` attribute can only be applied to foreign modules = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +warning: attribute should be applied to an `extern` block with non-Rust ABI + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5 + | +LL | #[link(name = "x")] extern "Rust" {} + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + warning: the `must_use` attribute cannot be used on modules --> $DIR/issue-43106-gating-of-builtin-attrs.rs:749:3 | diff --git a/triagebot.toml b/triagebot.toml index 60098a038ea73..bad75dc51d740 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1185,6 +1185,10 @@ cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"] message = "Some changes occurred in float parsing" cc = ["@tgross35"] +[mentions."src/tools/test-float-parse"] +message = "Some changes occurred in float parsing" +cc = ["@tgross35"] + [mentions."library/core/src/fmt/num.rs"] message = "Some changes occurred in integer formatting" cc = ["@tgross35"]