diff options
371 files changed, 2474 insertions, 1831 deletions
diff --git a/Cargo.lock b/Cargo.lock index 1296468b4e2..75c5f78e2b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.3.1" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6b5c519bab3ea61843a7923d074b04245624bb84a64a8c150f5deb014e388b" +checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" dependencies = [ "clap", ] @@ -580,7 +580,7 @@ dependencies = [ "clap", "indoc", "itertools", - "opener", + "opener 0.5.2", "shell-escape", "walkdir", ] @@ -2340,9 +2340,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.31" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b67ee4a744f36e6280792016c17e69921b51df357181d1eb17d620fcc3609f3" +checksum = "80992cb0e05f22cc052c99f8e883f1593b891014b96a8b4637fd274d7030c85e" dependencies = [ "ammonia", "anyhow", @@ -2355,7 +2355,8 @@ dependencies = [ "log", "memchr", "once_cell", - "opener", + "opener 0.6.1", + "pathdiff", "pulldown-cmark", "regex", "serde", @@ -2545,6 +2546,15 @@ dependencies = [ ] [[package]] +name = "normpath" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] name = "ntapi" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2632,6 +2642,17 @@ dependencies = [ ] [[package]] +name = "opener" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" +dependencies = [ + "bstr", + "normpath", + "winapi", +] + +[[package]] name = "openssl" version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 815edcc0dc4..050366b081f 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -14,7 +14,7 @@ use crate::{ pub trait LayoutCalculator { type TargetDataLayoutRef: Borrow<TargetDataLayout>; - fn delay_bug(&self, txt: String); + fn delayed_bug(&self, txt: String); fn current_data_layout(&self) -> Self::TargetDataLayoutRef; fn scalar_pair<FieldIdx: Idx, VariantIdx: Idx>( @@ -792,7 +792,7 @@ pub trait LayoutCalculator { let only_variant = &variants[VariantIdx::new(0)]; for field in only_variant { if field.is_unsized() { - self.delay_bug("unsized field in union".to_string()); + self.delayed_bug("unsized field in union".to_string()); } align = align.max(field.align); @@ -1038,7 +1038,7 @@ fn univariant< for &i in &inverse_memory_index { let field = &fields[i]; if !sized { - this.delay_bug(format!( + this.delayed_bug(format!( "univariant: field #{} comes after unsized field", offsets.len(), )); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index be5671f1bf7..5b07299d411 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -327,7 +327,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ), ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()), ExprKind::Err => hir::ExprKind::Err( - self.tcx.sess.delay_span_bug(e.span, "lowered ExprKind::Err"), + self.tcx.sess.span_delayed_bug(e.span, "lowered ExprKind::Err"), ), ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), @@ -799,7 +799,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr_ident_mut(span, task_context_ident, task_context_hid) } else { // Use of `await` outside of an async context, we cannot use `task_context` here. - self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no task_context hir id")) + self.expr_err(span, self.tcx.sess.span_delayed_bug(span, "no task_context hir id")) }; let new_unchecked = self.expr_call_lang_item_fn_mut( span, diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index b6202be4f52..8fa2cae43bf 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -267,7 +267,7 @@ fn make_count<'hir>( ctx.expr( sp, hir::ExprKind::Err( - ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count"), + ctx.tcx.sess.span_delayed_bug(sp, "lowered bad format_args count"), ), ) } @@ -306,7 +306,7 @@ fn make_format_spec<'hir>( } Err(_) => ctx.expr( sp, - hir::ExprKind::Err(ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count")), + hir::ExprKind::Err(ctx.tcx.sess.span_delayed_bug(sp, "lowered bad format_args count")), ), }; let &FormatOptions { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index c47c5fc8fcc..fbbb9d7a52a 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -256,7 +256,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { None => { - let guar = this.tcx.sess.delay_span_bug( + let guar = this.tcx.sess.span_delayed_bug( span, "expected to lower type alias type, but it was missing", ); @@ -863,7 +863,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { None => { - let guar = this.tcx.sess.delay_span_bug( + let guar = this.tcx.sess.span_delayed_bug( i.span, "expected to lower associated type, but it was missing", ); @@ -996,7 +996,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> { match block { Some(block) => self.lower_block_expr(block), - None => self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no block")), + None => self.expr_err(span, self.tcx.sess.span_delayed_bug(span, "no block")), } } @@ -1006,7 +1006,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &[], match expr { Some(expr) => this.lower_expr_mut(expr), - None => this.expr_err(span, this.tcx.sess.delay_span_bug(span, "no block")), + None => this.expr_err(span, this.tcx.sess.span_delayed_bug(span, "no block")), }, ) }) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4abd0f135c6..eb6d11a72e6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -54,7 +54,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey}; +use rustc_errors::{DiagnosticArgFromDisplay, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; @@ -763,10 +763,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.resolver.get_import_res(id).present_items() } - fn diagnostic(&self) -> &Handler { - self.tcx.sess.diagnostic() - } - /// Reuses the span but adds information like the kind of the desugaring and features that are /// allowed inside this span. fn mark_span_with_reason( @@ -1326,7 +1322,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => { - hir::TyKind::Err(self.tcx.sess.delay_span_bug(t.span, "TyKind::Err lowered")) + hir::TyKind::Err(self.tcx.sess.span_delayed_bug(t.span, "TyKind::Err lowered")) } // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS #[allow(rustc::untranslatable_diagnostic)] @@ -1510,7 +1506,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"), TyKind::CVarArgs => { - let guar = self.tcx.sess.delay_span_bug( + let guar = self.tcx.sess.span_delayed_bug( t.span, "`TyKind::CVarArgs` should have been handled elsewhere", ); @@ -1653,7 +1649,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { self.tcx .sess - .delay_span_bug(lifetime.ident.span, "no def-id for fresh lifetime"); + .span_delayed_bug(lifetime.ident.span, "no def-id for fresh lifetime"); continue; } } @@ -2515,9 +2511,10 @@ impl<'hir> GenericArgsCtor<'hir> { let hir_id = lcx.next_id(); let Some(host_param_id) = lcx.host_param_id else { - lcx.tcx - .sess - .delay_span_bug(span, "no host param id for call in const yet no errors reported"); + lcx.tcx.sess.span_delayed_bug( + span, + "no host param id for call in const yet no errors reported", + ); return; }; diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 8050f5826aa..db8ca7c3643 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -139,7 +139,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // We should've returned in the for loop above. - self.diagnostic().span_bug( + self.tcx.sess.diagnostic().span_bug( p.span, format!( "lower_qpath: no final extension segment in {}..{}", diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 8851fbd28f0..897f35a5c4a 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -102,7 +102,7 @@ impl<'a> PostExpansionVisitor<'a> { } Err(abi::AbiDisabled::Unrecognized) => { if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) { - self.sess.parse_sess.span_diagnostic.delay_span_bug( + self.sess.diagnostic().span_delayed_bug( span, format!( "unrecognized ABI not caught in lowering: {}", @@ -515,7 +515,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { } }; } - gate_all!(c_str_literals, "`c\"..\"` literals are experimental"); gate_all!( if_let_guard, "`if let` guards are experimental", @@ -628,7 +627,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate) if all_stable { err.sugg = Some(attr.span); } - sess.parse_sess.span_diagnostic.emit_err(err); + sess.diagnostic().emit_err(err); } } } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 609d75733b2..a6930fe0a17 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -945,7 +945,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> { assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}"); use ReprAttr::*; let mut acc = Vec::new(); - let diagnostic = &sess.parse_sess.span_diagnostic; + let diagnostic = sess.diagnostic(); if let Some(items) = attr.meta_item_list() { for item in items { @@ -1060,9 +1060,9 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> { // Not a word we recognize. This will be caught and reported by // the `check_mod_attrs` pass, but this pass doesn't always run // (e.g. if we only pretty-print the source), so we have to gate - // the `delay_span_bug` call as follows: + // the `span_delayed_bug` call as follows: if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) { - diagnostic.delay_span_bug(item.span(), "unrecognized representation hint"); + diagnostic.span_delayed_bug(item.span(), "unrecognized representation hint"); } } } diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs deleted file mode 100644 index 21d367c40cb..00000000000 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ /dev/null @@ -1,248 +0,0 @@ -#![deny(rustc::untranslatable_diagnostic)] -#![deny(rustc::diagnostic_outside_of_impl)] -use rustc_infer::infer::InferCtxt; -use rustc_middle::mir::visit::TyContext; -use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{ - Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, SourceInfo, Statement, - StatementKind, Terminator, TerminatorKind, UserTypeProjection, -}; -use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::GenericArgsRef; -use rustc_middle::ty::{self, Ty, TyCtxt}; - -use crate::{ - borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict, - region_infer::values::LivenessValues, -}; - -pub(super) fn generate_constraints<'tcx>( - infcx: &InferCtxt<'tcx>, - liveness_constraints: &mut LivenessValues, - all_facts: &mut Option<AllFacts>, - location_table: &LocationTable, - body: &Body<'tcx>, - borrow_set: &BorrowSet<'tcx>, -) { - let mut cg = ConstraintGeneration { - borrow_set, - infcx, - liveness_constraints, - location_table, - all_facts, - body, - }; - - for (bb, data) in body.basic_blocks.iter_enumerated() { - cg.visit_basic_block_data(bb, data); - } -} - -/// 'cg = the duration of the constraint generation process itself. -struct ConstraintGeneration<'cg, 'tcx> { - infcx: &'cg InferCtxt<'tcx>, - all_facts: &'cg mut Option<AllFacts>, - location_table: &'cg LocationTable, - liveness_constraints: &'cg mut LivenessValues, - borrow_set: &'cg BorrowSet<'tcx>, - body: &'cg Body<'tcx>, -} - -impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> { - /// We sometimes have `args` within an rvalue, or within a - /// call. Make them live at the location where they appear. - fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) { - self.add_regular_live_constraint(*args, location); - self.super_args(args); - } - - /// We sometimes have `region` within an rvalue, or within a - /// call. Make them live at the location where they appear. - fn visit_region(&mut self, region: ty::Region<'tcx>, location: Location) { - self.add_regular_live_constraint(region, location); - self.super_region(region); - } - - /// We sometimes have `ty` within an rvalue, or within a - /// call. Make them live at the location where they appear. - fn visit_ty(&mut self, ty: Ty<'tcx>, ty_context: TyContext) { - match ty_context { - TyContext::ReturnTy(SourceInfo { span, .. }) - | TyContext::YieldTy(SourceInfo { span, .. }) - | TyContext::UserTy(span) - | TyContext::LocalDecl { source_info: SourceInfo { span, .. }, .. } => { - span_bug!(span, "should not be visiting outside of the CFG: {:?}", ty_context); - } - TyContext::Location(location) => { - self.add_regular_live_constraint(ty, location); - } - } - - self.super_ty(ty); - } - - fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { - if let Some(all_facts) = self.all_facts { - let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); - all_facts.cfg_edge.push(( - self.location_table.start_index(location), - self.location_table.mid_index(location), - )); - - all_facts.cfg_edge.push(( - self.location_table.mid_index(location), - self.location_table.start_index(location.successor_within_block()), - )); - - // If there are borrows on this now dead local, we need to record them as `killed`. - if let StatementKind::StorageDead(local) = statement.kind { - record_killed_borrows_for_local( - all_facts, - self.borrow_set, - self.location_table, - local, - location, - ); - } - } - - self.super_statement(statement, location); - } - - fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { - // When we see `X = ...`, then kill borrows of - // `(*X).foo` and so forth. - self.record_killed_borrows_for_place(*place, location); - - self.super_assign(place, rvalue, location); - } - - fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { - if let Some(all_facts) = self.all_facts { - let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); - all_facts.cfg_edge.push(( - self.location_table.start_index(location), - self.location_table.mid_index(location), - )); - - let successor_blocks = terminator.successors(); - all_facts.cfg_edge.reserve(successor_blocks.size_hint().0); - for successor_block in successor_blocks { - all_facts.cfg_edge.push(( - self.location_table.mid_index(location), - self.location_table.start_index(successor_block.start_location()), - )); - } - } - - // A `Call` terminator's return value can be a local which has borrows, - // so we need to record those as `killed` as well. - if let TerminatorKind::Call { destination, .. } = terminator.kind { - self.record_killed_borrows_for_place(destination, location); - } - - self.super_terminator(terminator, location); - } - - fn visit_ascribe_user_ty( - &mut self, - _place: &Place<'tcx>, - _variance: ty::Variance, - _user_ty: &UserTypeProjection, - _location: Location, - ) { - } -} - -impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> { - /// Some variable with type `live_ty` is "regular live" at - /// `location` -- i.e., it may be used later. This means that all - /// regions appearing in the type `live_ty` must be live at - /// `location`. - fn add_regular_live_constraint<T>(&mut self, live_ty: T, location: Location) - where - T: TypeVisitable<TyCtxt<'tcx>>, - { - debug!("add_regular_live_constraint(live_ty={:?}, location={:?})", live_ty, location); - - self.infcx.tcx.for_each_free_region(&live_ty, |live_region| { - let vid = live_region.as_var(); - self.liveness_constraints.add_location(vid, location); - }); - } - - /// When recording facts for Polonius, records the borrows on the specified place - /// as `killed`. For example, when assigning to a local, or on a call's return destination. - fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) { - if let Some(all_facts) = self.all_facts { - let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); - - // Depending on the `Place` we're killing: - // - if it's a local, or a single deref of a local, - // we kill all the borrows on the local. - // - if it's a deeper projection, we have to filter which - // of the borrows are killed: the ones whose `borrowed_place` - // conflicts with the `place`. - match place.as_ref() { - PlaceRef { local, projection: &[] } - | PlaceRef { local, projection: &[ProjectionElem::Deref] } => { - debug!( - "Recording `killed` facts for borrows of local={:?} at location={:?}", - local, location - ); - - record_killed_borrows_for_local( - all_facts, - self.borrow_set, - self.location_table, - local, - location, - ); - } - - PlaceRef { local, projection: &[.., _] } => { - // Kill conflicting borrows of the innermost local. - debug!( - "Recording `killed` facts for borrows of \ - innermost projected local={:?} at location={:?}", - local, location - ); - - if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) { - for &borrow_index in borrow_indices { - let places_conflict = places_conflict::places_conflict( - self.infcx.tcx, - self.body, - self.borrow_set[borrow_index].borrowed_place, - place, - places_conflict::PlaceConflictBias::NoOverlap, - ); - - if places_conflict { - let location_index = self.location_table.mid_index(location); - all_facts.loan_killed_at.push((borrow_index, location_index)); - } - } - } - } - } - } - } -} - -/// When recording facts for Polonius, records the borrows on the specified local as `killed`. -fn record_killed_borrows_for_local( - all_facts: &mut AllFacts, - borrow_set: &BorrowSet<'_>, - location_table: &LocationTable, - local: Local, - location: Location, -) { - if let Some(borrow_indices) = borrow_set.local_map.get(&local) { - all_facts.loan_killed_at.reserve(borrow_indices.len()); - for &borrow_index in borrow_indices { - let location_index = location_table.mid_index(location); - all_facts.loan_killed_at.push((borrow_index, location_index)); - } - } -} diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index b3d14c1beb5..54f161ea9b4 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -432,7 +432,8 @@ impl<'mir, 'tcx> Borrows<'mir, 'tcx> { assert_eq!( borrows_out_of_scope_at_location, polonius_prec.loans_out_of_scope_at_location, - "the loans out of scope must be the same as the borrows out of scope" + "polonius loan scopes differ from NLL borrow scopes, for body {:?}", + body.span, ); borrows_out_of_scope_at_location = polonius_prec.loans_out_of_scope_at_location; diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 03172ef34b9..924e68fa91d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -385,7 +385,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( error_region: Option<ty::Region<'tcx>>, ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { // We generally shouldn't have errors here because the query was - // already run, but there's no point using `delay_span_bug` + // already run, but there's no point using `span_delayed_bug` // when we're going to emit an error here anyway. let _errors = ocx.select_all_or_error(); let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone()); diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index ef4bf543454..7bcad92ff33 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1135,7 +1135,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }); } else { issued_spans.var_subdiag( - Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic), + Some(self.infcx.tcx.sess.diagnostic()), &mut err, Some(issued_borrow.kind), |kind, var_span| { @@ -1152,7 +1152,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); borrow_spans.var_subdiag( - Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic), + Some(self.infcx.tcx.sess.diagnostic()), &mut err, Some(gen_borrow_kind), |kind, var_span| { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index e37457f48df..4deed98d002 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -124,7 +124,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let did = did.expect_local(); if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) { diag.eager_subdiagnostic( - &self.infcx.tcx.sess.parse_sess.span_diagnostic, + self.infcx.tcx.sess.diagnostic(), OnClosureNote::InvokedTwice { place_name: &ty::place_to_string_for_capture( self.infcx.tcx, @@ -146,7 +146,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let did = did.expect_local(); if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) { diag.eager_subdiagnostic( - &self.infcx.tcx.sess.parse_sess.span_diagnostic, + self.infcx.tcx.sess.diagnostic(), OnClosureNote::MovedTwice { place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place), span: *span, @@ -1119,7 +1119,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { && self.infcx.can_eq(self.param_env, ty, self_ty) { err.eager_subdiagnostic( - &self.infcx.tcx.sess.parse_sess.span_diagnostic, + self.infcx.tcx.sess.diagnostic(), CaptureReasonSuggest::FreshReborrow { span: move_span.shrink_to_hi(), }, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 40bbc5e7c41..759f5e910f7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -84,7 +84,7 @@ impl<'tcx> RegionErrors<'tcx> { #[track_caller] pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) { let val = val.into(); - self.1.sess.delay_span_bug(DUMMY_SP, format!("{val:?}")); + self.1.sess.span_delayed_bug(DUMMY_SP, format!("{val:?}")); self.0.push(val); } pub fn is_empty(&self) -> bool { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 730b65898bc..977a5d5d50d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -619,8 +619,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { _, ) => { // HIR lowering sometimes doesn't catch this in erroneous - // programs, so we need to use delay_span_bug here. See #82126. - self.infcx.tcx.sess.delay_span_bug( + // programs, so we need to use span_delayed_bug here. See #82126. + self.infcx.tcx.sess.span_delayed_bug( hir_arg.span(), format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"), ); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 6e44f44dc18..3d3fd412ae0 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -65,19 +65,18 @@ use self::path_utils::*; pub mod borrow_set; mod borrowck_errors; -mod constraint_generation; mod constraints; mod dataflow; mod def_use; mod diagnostics; mod facts; -mod invalidation; mod location; mod member_constraints; mod nll; mod path_utils; mod place_ext; mod places_conflict; +mod polonius; mod prefixes; mod region_infer; mod renumber; @@ -195,8 +194,7 @@ fn do_mir_borrowck<'tcx>( nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes - let location_table_owned = LocationTable::new(body); - let location_table = &location_table_owned; + let location_table = LocationTable::new(body); let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true); let promoted_move_data = promoted @@ -228,7 +226,7 @@ fn do_mir_borrowck<'tcx>( free_regions, body, &promoted, - location_table, + &location_table, param_env, &mut flow_inits, &mdpe.move_data, @@ -292,7 +290,7 @@ fn do_mir_borrowck<'tcx>( param_env, body: promoted_body, move_data: &move_data, - location_table, // no need to create a real one for the promoted, it is not used + location_table: &location_table, // no need to create a real one for the promoted, it is not used movable_coroutine, fn_self_span_reported: Default::default(), locals_are_invalidated_at_exit, @@ -333,7 +331,7 @@ fn do_mir_borrowck<'tcx>( param_env, body, move_data: &mdpe.move_data, - location_table, + location_table: &location_table, movable_coroutine, locals_are_invalidated_at_exit, fn_self_span_reported: Default::default(), @@ -435,7 +433,7 @@ fn do_mir_borrowck<'tcx>( promoted, borrow_set, region_inference_context: regioncx, - location_table: polonius_input.as_ref().map(|_| location_table_owned), + location_table: polonius_input.as_ref().map(|_| location_table), input_facts: polonius_input, output_facts, })) @@ -1020,9 +1018,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { flow_state: &Flows<'cx, 'tcx>, ) -> bool { let mut error_reported = false; - let tcx = self.infcx.tcx; - let body = self.body; - let borrow_set = self.borrow_set.clone(); + let borrow_set = Rc::clone(&self.borrow_set); // Use polonius output if it has been enabled. let mut polonius_output; @@ -1039,8 +1035,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { each_borrow_involving_path( self, - tcx, - body, + self.infcx.tcx, + self.body, location, (sd, place_span.0), &borrow_set, @@ -2134,11 +2130,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { && !self.has_buffered_errors() { // rust-lang/rust#46908: In pure NLL mode this code path should be - // unreachable, but we use `delay_span_bug` because we can hit this when + // unreachable, but we use `span_delayed_bug` because we can hit this when // dereferencing a non-Copy raw pointer *and* have `-Ztreat-err-as-bug` // enabled. We don't want to ICE for that case, as other errors will have // been emitted (#52262). - self.infcx.tcx.sess.delay_span_bug( + self.infcx.tcx.sess.span_delayed_bug( span, format!( "Accessing `{place:?}` with the kind `{kind:?}` shouldn't be possible", @@ -2432,7 +2428,7 @@ mod error { pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) { if let None = self.tainted_by_errors { - self.tainted_by_errors = Some(self.tcx.sess.delay_span_bug( + self.tainted_by_errors = Some(self.tcx.sess.span_delayed_bug( t.span.clone_ignoring_labels(), "diagnostic buffered but not emitted", )) diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 480358ef997..c88d9d81fe1 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -2,16 +2,17 @@ #![deny(rustc::diagnostic_outside_of_impl)] //! The entry point of the NLL borrow checker. +use polonius_engine::{Algorithm, Output}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::LocalDefId; use rustc_index::IndexSlice; use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere}; -use rustc_middle::mir::{ - Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, Promoted, - START_BLOCK, -}; +use rustc_middle::mir::{Body, ClosureOutlivesSubject, ClosureRegionRequirements, Promoted}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt}; +use rustc_mir_dataflow::impls::MaybeInitializedPlaces; +use rustc_mir_dataflow::move_paths::MoveData; +use rustc_mir_dataflow::ResultsCursor; use rustc_span::symbol::sym; use std::env; use std::io; @@ -19,20 +20,13 @@ use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; -use polonius_engine::{Algorithm, Output}; - -use rustc_mir_dataflow::impls::MaybeInitializedPlaces; -use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData}; -use rustc_mir_dataflow::ResultsCursor; - use crate::{ borrow_set::BorrowSet, - constraint_generation, consumers::ConsumerOptions, diagnostics::RegionErrors, facts::{AllFacts, AllFactsExt, RustcFacts}, - invalidation, location::LocationTable, + polonius, region_infer::{values::RegionValueElements, RegionInferenceContext}, renumber, type_check::{self, MirTypeckRegionConstraints, MirTypeckResults}, @@ -78,81 +72,6 @@ pub(crate) fn replace_regions_in_mir<'tcx>( universal_regions } -// This function populates an AllFacts instance with base facts related to -// MovePaths and needed for the move analysis. -fn populate_polonius_move_facts( - all_facts: &mut AllFacts, - move_data: &MoveData<'_>, - location_table: &LocationTable, - body: &Body<'_>, -) { - all_facts - .path_is_var - .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l))); - - for (child, move_path) in move_data.move_paths.iter_enumerated() { - if let Some(parent) = move_path.parent { - all_facts.child_path.push((child, parent)); - } - } - - let fn_entry_start = - location_table.start_index(Location { block: START_BLOCK, statement_index: 0 }); - - // initialized_at - for init in move_data.inits.iter() { - match init.location { - InitLocation::Statement(location) => { - let block_data = &body[location.block]; - let is_terminator = location.statement_index == block_data.statements.len(); - - if is_terminator && init.kind == InitKind::NonPanicPathOnly { - // We are at the terminator of an init that has a panic path, - // and where the init should not happen on panic - - for successor in block_data.terminator().successors() { - if body[successor].is_cleanup { - continue; - } - - // The initialization happened in (or rather, when arriving at) - // the successors, but not in the unwind block. - let first_statement = Location { block: successor, statement_index: 0 }; - all_facts - .path_assigned_at_base - .push((init.path, location_table.start_index(first_statement))); - } - } else { - // In all other cases, the initialization just happens at the - // midpoint, like any other effect. - all_facts - .path_assigned_at_base - .push((init.path, location_table.mid_index(location))); - } - } - // Arguments are initialized on function entry - InitLocation::Argument(local) => { - assert!(body.local_kind(local) == LocalKind::Arg); - all_facts.path_assigned_at_base.push((init.path, fn_entry_start)); - } - } - } - - for (local, path) in move_data.rev_lookup.iter_locals_enumerated() { - if body.local_kind(local) != LocalKind::Arg { - // Non-arguments start out deinitialised; we simulate this with an - // initial move: - all_facts.path_moved_at_base.push((path, fn_entry_start)); - } - } - - // moved_out_at - // deinitialisation is assumed to always happen! - all_facts - .path_moved_at_base - .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source)))); -} - /// Computes the (non-lexical) regions from the input MIR. /// /// This may result in errors being reported. @@ -182,67 +101,23 @@ pub(crate) fn compute_regions<'cx, 'tcx>( let elements = &Rc::new(RegionValueElements::new(body)); // Run the MIR type-checker. - let MirTypeckResults { - constraints, - universal_region_relations, - opaque_type_values, - live_loans, - } = type_check::type_check( - infcx, - param_env, - body, - promoted, - &universal_regions, - location_table, - borrow_set, - &mut all_facts, - flow_inits, - move_data, - elements, - upvars, - polonius_input, - ); - - if let Some(all_facts) = &mut all_facts { - let _prof_timer = infcx.tcx.prof.generic_activity("polonius_fact_generation"); - all_facts.universal_region.extend(universal_regions.universal_regions()); - populate_polonius_move_facts(all_facts, move_data, location_table, body); - - // Emit universal regions facts, and their relations, for Polonius. - // - // 1: universal regions are modeled in Polonius as a pair: - // - the universal region vid itself. - // - a "placeholder loan" associated to this universal region. Since they don't exist in - // the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index - // added to the existing number of loans, as if they succeeded them in the set. - // - let borrow_count = borrow_set.len(); - debug!( - "compute_regions: polonius placeholders, num_universals={}, borrow_count={}", - universal_regions.len(), - borrow_count + let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } = + type_check::type_check( + infcx, + param_env, + body, + promoted, + &universal_regions, + location_table, + borrow_set, + &mut all_facts, + flow_inits, + move_data, + elements, + upvars, + polonius_input, ); - for universal_region in universal_regions.universal_regions() { - let universal_region_idx = universal_region.index(); - let placeholder_loan_idx = borrow_count + universal_region_idx; - all_facts.placeholder.push((universal_region, placeholder_loan_idx.into())); - } - - // 2: the universal region relations `outlives` constraints are emitted as - // `known_placeholder_subset` facts. - for (fr1, fr2) in universal_region_relations.known_outlives() { - if fr1 != fr2 { - debug!( - "compute_regions: emitting polonius `known_placeholder_subset` \ - fr1={:?}, fr2={:?}", - fr1, fr2 - ); - all_facts.known_placeholder_subset.push((fr1, fr2)); - } - } - } - // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the // base constraints generated by the type-check. @@ -250,7 +125,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( let MirTypeckRegionConstraints { placeholder_indices, placeholder_index_to_region: _, - mut liveness_constraints, + liveness_constraints, outlives_constraints, member_constraints, universe_causes, @@ -258,13 +133,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>( } = constraints; let placeholder_indices = Rc::new(placeholder_indices); - constraint_generation::generate_constraints( - infcx, - &mut liveness_constraints, + // If requested, emit legacy polonius facts. + polonius::emit_facts( &mut all_facts, + infcx.tcx, location_table, body, borrow_set, + move_data, + &universal_regions, + &universal_region_relations, ); let mut regioncx = RegionInferenceContext::new( @@ -279,17 +157,12 @@ pub(crate) fn compute_regions<'cx, 'tcx>( type_tests, liveness_constraints, elements, - live_loans, ); - // Generate various additional constraints. - invalidation::generate_invalidates(infcx.tcx, &mut all_facts, location_table, body, borrow_set); - - let def_id = body.source.def_id(); - - // Dump facts if requested. + // If requested: dump NLL facts, and run legacy polonius analysis. let polonius_output = all_facts.as_ref().and_then(|all_facts| { if infcx.tcx.sess.opts.unstable_opts.nll_facts { + let def_id = body.source.def_id(); let def_path = infcx.tcx.def_path(def_id); let dir_path = PathBuf::from(&infcx.tcx.sess.opts.unstable_opts.nll_facts_dir) .join(def_path.to_filename_friendly_no_crate()); @@ -314,7 +187,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( if !nll_errors.is_empty() { // Suppress unhelpful extra errors in `infer_opaque_types`. - infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug( + infcx.set_tainted_by_errors(infcx.tcx.sess.span_delayed_bug( body.span, "`compute_regions` tainted `infcx` with errors but did not emit any errors", )); @@ -407,7 +280,7 @@ pub(super) fn dump_annotation<'tcx>( let def_span = tcx.def_span(body.source.def_id()); let mut err = if let Some(closure_region_requirements) = closure_region_requirements { - let mut err = tcx.sess.diagnostic().span_note_diag(def_span, "external requirements"); + let mut err = tcx.sess.diagnostic().struct_span_note(def_span, "external requirements"); regioncx.annotate(tcx, &mut err); @@ -426,7 +299,7 @@ pub(super) fn dump_annotation<'tcx>( err } else { - let mut err = tcx.sess.diagnostic().span_note_diag(def_span, "no external requirements"); + let mut err = tcx.sess.diagnostic().struct_span_note(def_span, "no external requirements"); regioncx.annotate(tcx, &mut err); err diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs index a3db101311f..232bd741825 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs @@ -14,34 +14,21 @@ use crate::{ ReadOrWrite, Reservation, Shallow, Write, WriteKind, }; -pub(super) fn generate_invalidates<'tcx>( +/// Emit `loan_invalidated_at` facts. +pub(super) fn emit_loan_invalidations<'tcx>( tcx: TyCtxt<'tcx>, - all_facts: &mut Option<AllFacts>, + all_facts: &mut AllFacts, location_table: &LocationTable, body: &Body<'tcx>, borrow_set: &BorrowSet<'tcx>, ) { - if all_facts.is_none() { - // Nothing to do if we don't have any facts - return; - } - - if let Some(all_facts) = all_facts { - let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation"); - let dominators = body.basic_blocks.dominators(); - let mut ig = InvalidationGenerator { - all_facts, - borrow_set, - tcx, - location_table, - body: body, - dominators, - }; - ig.visit_body(body); - } + let dominators = body.basic_blocks.dominators(); + let mut visitor = + LoanInvalidationsGenerator { all_facts, borrow_set, tcx, location_table, body, dominators }; + visitor.visit_body(body); } -struct InvalidationGenerator<'cx, 'tcx> { +struct LoanInvalidationsGenerator<'cx, 'tcx> { tcx: TyCtxt<'tcx>, all_facts: &'cx mut AllFacts, location_table: &'cx LocationTable, @@ -52,7 +39,7 @@ struct InvalidationGenerator<'cx, 'tcx> { /// Visits the whole MIR and generates `invalidates()` facts. /// Most of the code implementing this was stolen from `borrow_check/mod.rs`. -impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { +impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { self.check_activations(location); @@ -214,7 +201,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { } } -impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { +impl<'cx, 'tcx> LoanInvalidationsGenerator<'cx, 'tcx> { /// Simulates mutation of a place. fn mutate_place(&mut self, location: Location, place: Place<'tcx>, kind: AccessDepth) { self.access_place( @@ -348,20 +335,16 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { rw: ReadOrWrite, ) { debug!( - "invalidation::check_access_for_conflict(location={:?}, place={:?}, sd={:?}, \ - rw={:?})", + "check_access_for_conflict(location={:?}, place={:?}, sd={:?}, rw={:?})", location, place, sd, rw, ); - let tcx = self.tcx; - let body = self.body; - let borrow_set = self.borrow_set; each_borrow_involving_path( self, - tcx, - body, + self.tcx, + self.body, location, (sd, place), - borrow_set, + self.borrow_set, |_| true, |this, borrow_index, borrow| { match (rw, borrow.kind) { diff --git a/compiler/rustc_borrowck/src/polonius/loan_kills.rs b/compiler/rustc_borrowck/src/polonius/loan_kills.rs new file mode 100644 index 00000000000..5df94383702 --- /dev/null +++ b/compiler/rustc_borrowck/src/polonius/loan_kills.rs @@ -0,0 +1,147 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] +use rustc_middle::mir::visit::Visitor; +use rustc_middle::mir::{ + Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, + Terminator, TerminatorKind, +}; +use rustc_middle::ty::TyCtxt; + +use crate::{borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict}; + +/// Emit `loan_killed_at` and `cfg_edge` facts at the same time. +pub(super) fn emit_loan_kills<'tcx>( + tcx: TyCtxt<'tcx>, + all_facts: &mut AllFacts, + location_table: &LocationTable, + body: &Body<'tcx>, + borrow_set: &BorrowSet<'tcx>, +) { + let mut visitor = LoanKillsGenerator { borrow_set, tcx, location_table, all_facts, body }; + for (bb, data) in body.basic_blocks.iter_enumerated() { + visitor.visit_basic_block_data(bb, data); + } +} + +struct LoanKillsGenerator<'cx, 'tcx> { + tcx: TyCtxt<'tcx>, + all_facts: &'cx mut AllFacts, + location_table: &'cx LocationTable, + borrow_set: &'cx BorrowSet<'tcx>, + body: &'cx Body<'tcx>, +} + +impl<'cx, 'tcx> Visitor<'tcx> for LoanKillsGenerator<'cx, 'tcx> { + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { + // Also record CFG facts here. + self.all_facts.cfg_edge.push(( + self.location_table.start_index(location), + self.location_table.mid_index(location), + )); + + self.all_facts.cfg_edge.push(( + self.location_table.mid_index(location), + self.location_table.start_index(location.successor_within_block()), + )); + + // If there are borrows on this now dead local, we need to record them as `killed`. + if let StatementKind::StorageDead(local) = statement.kind { + self.record_killed_borrows_for_local(local, location); + } + + self.super_statement(statement, location); + } + + fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { + // When we see `X = ...`, then kill borrows of + // `(*X).foo` and so forth. + self.record_killed_borrows_for_place(*place, location); + self.super_assign(place, rvalue, location); + } + + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { + // Also record CFG facts here. + self.all_facts.cfg_edge.push(( + self.location_table.start_index(location), + self.location_table.mid_index(location), + )); + + let successor_blocks = terminator.successors(); + self.all_facts.cfg_edge.reserve(successor_blocks.size_hint().0); + for successor_block in successor_blocks { + self.all_facts.cfg_edge.push(( + self.location_table.mid_index(location), + self.location_table.start_index(successor_block.start_location()), + )); + } + + // A `Call` terminator's return value can be a local which has borrows, + // so we need to record those as `killed` as well. + if let TerminatorKind::Call { destination, .. } = terminator.kind { + self.record_killed_borrows_for_place(destination, location); + } + + self.super_terminator(terminator, location); + } +} + +impl<'tcx> LoanKillsGenerator<'_, 'tcx> { + /// Records the borrows on the specified place as `killed`. For example, when assigning to a + /// local, or on a call's return destination. + fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) { + // Depending on the `Place` we're killing: + // - if it's a local, or a single deref of a local, + // we kill all the borrows on the local. + // - if it's a deeper projection, we have to filter which + // of the borrows are killed: the ones whose `borrowed_place` + // conflicts with the `place`. + match place.as_ref() { + PlaceRef { local, projection: &[] } + | PlaceRef { local, projection: &[ProjectionElem::Deref] } => { + debug!( + "Recording `killed` facts for borrows of local={:?} at location={:?}", + local, location + ); + + self.record_killed_borrows_for_local(local, location); + } + + PlaceRef { local, projection: &[.., _] } => { + // Kill conflicting borrows of the innermost local. + debug!( + "Recording `killed` facts for borrows of \ + innermost projected local={:?} at location={:?}", + local, location + ); + + if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) { + for &borrow_index in borrow_indices { + let places_conflict = places_conflict::places_conflict( + self.tcx, + self.body, + self.borrow_set[borrow_index].borrowed_place, + place, + places_conflict::PlaceConflictBias::NoOverlap, + ); + + if places_conflict { + let location_index = self.location_table.mid_index(location); + self.all_facts.loan_killed_at.push((borrow_index, location_index)); + } + } + } + } + } + } + + /// Records the borrows on the specified local as `killed`. + fn record_killed_borrows_for_local(&mut self, local: Local, location: Location) { + if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) { + let location_index = self.location_table.mid_index(location); + self.all_facts.loan_killed_at.reserve(borrow_indices.len()); + for &borrow_index in borrow_indices { + self.all_facts.loan_killed_at.push((borrow_index, location_index)); + } + } + } +} diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs new file mode 100644 index 00000000000..40126d50d57 --- /dev/null +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -0,0 +1,188 @@ +//! Functions dedicated to fact generation for the `-Zpolonius=legacy` datalog implementation. +//! +//! Will be removed in the future, once the in-tree `-Zpolonius=next` implementation reaches feature +//! parity. + +use rustc_middle::mir::{Body, LocalKind, Location, START_BLOCK}; +use rustc_middle::ty::TyCtxt; +use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData}; + +use crate::borrow_set::BorrowSet; +use crate::facts::AllFacts; +use crate::location::LocationTable; +use crate::type_check::free_region_relations::UniversalRegionRelations; +use crate::universal_regions::UniversalRegions; + +mod loan_invalidations; +mod loan_kills; + +/// When requested, emit most of the facts needed by polonius: +/// - moves and assignments +/// - universal regions and their relations +/// - CFG points and edges +/// - loan kills +/// - loan invalidations +/// +/// The rest of the facts are emitted during typeck and liveness. +pub(crate) fn emit_facts<'tcx>( + all_facts: &mut Option<AllFacts>, + tcx: TyCtxt<'tcx>, + location_table: &LocationTable, + body: &Body<'tcx>, + borrow_set: &BorrowSet<'tcx>, + move_data: &MoveData<'_>, + universal_regions: &UniversalRegions<'_>, + universal_region_relations: &UniversalRegionRelations<'_>, +) { + let Some(all_facts) = all_facts else { + // We don't do anything if there are no facts to fill. + return; + }; + let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation"); + emit_move_facts(all_facts, move_data, location_table, body); + emit_universal_region_facts( + all_facts, + borrow_set, + &universal_regions, + &universal_region_relations, + ); + emit_cfg_and_loan_kills_facts(all_facts, tcx, location_table, body, borrow_set); + emit_loan_invalidations_facts(all_facts, tcx, location_table, body, borrow_set); +} + +/// Emit facts needed for move/init analysis: moves and assignments. +fn emit_move_facts( + all_facts: &mut AllFacts, + move_data: &MoveData<'_>, + location_table: &LocationTable, + body: &Body<'_>, +) { + all_facts + .path_is_var + .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l))); + + for (child, move_path) in move_data.move_paths.iter_enumerated() { + if let Some(parent) = move_path.parent { + all_facts.child_path.push((child, parent)); + } + } + + let fn_entry_start = + location_table.start_index(Location { block: START_BLOCK, statement_index: 0 }); + + // initialized_at + for init in move_data.inits.iter() { + match init.location { + InitLocation::Statement(location) => { + let block_data = &body[location.block]; + let is_terminator = location.statement_index == block_data.statements.len(); + + if is_terminator && init.kind == InitKind::NonPanicPathOnly { + // We are at the terminator of an init that has a panic path, + // and where the init should not happen on panic + + for successor in block_data.terminator().successors() { + if body[successor].is_cleanup { + continue; + } + + // The initialization happened in (or rather, when arriving at) + // the successors, but not in the unwind block. + let first_statement = Location { block: successor, statement_index: 0 }; + all_facts + .path_assigned_at_base + .push((init.path, location_table.start_index(first_statement))); + } + } else { + // In all other cases, the initialization just happens at the + // midpoint, like any other effect. + all_facts + .path_assigned_at_base + .push((init.path, location_table.mid_index(location))); + } + } + // Arguments are initialized on function entry + InitLocation::Argument(local) => { + assert!(body.local_kind(local) == LocalKind::Arg); + all_facts.path_assigned_at_base.push((init.path, fn_entry_start)); + } + } + } + + for (local, path) in move_data.rev_lookup.iter_locals_enumerated() { + if body.local_kind(local) != LocalKind::Arg { + // Non-arguments start out deinitialised; we simulate this with an + // initial move: + all_facts.path_moved_at_base.push((path, fn_entry_start)); + } + } + + // moved_out_at + // deinitialisation is assumed to always happen! + all_facts + .path_moved_at_base + .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source)))); +} + +/// Emit universal regions facts, and their relations. +fn emit_universal_region_facts( + all_facts: &mut AllFacts, + borrow_set: &BorrowSet<'_>, + universal_regions: &UniversalRegions<'_>, + universal_region_relations: &UniversalRegionRelations<'_>, +) { + // 1: universal regions are modeled in Polonius as a pair: + // - the universal region vid itself. + // - a "placeholder loan" associated to this universal region. Since they don't exist in + // the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index + // added to the existing number of loans, as if they succeeded them in the set. + // + all_facts.universal_region.extend(universal_regions.universal_regions()); + let borrow_count = borrow_set.len(); + debug!( + "emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}", + universal_regions.len(), + borrow_count + ); + + for universal_region in universal_regions.universal_regions() { + let universal_region_idx = universal_region.index(); + let placeholder_loan_idx = borrow_count + universal_region_idx; + all_facts.placeholder.push((universal_region, placeholder_loan_idx.into())); + } + + // 2: the universal region relations `outlives` constraints are emitted as + // `known_placeholder_subset` facts. + for (fr1, fr2) in universal_region_relations.known_outlives() { + if fr1 != fr2 { + debug!( + "emit_universal_region_facts: emitting polonius `known_placeholder_subset` \ + fr1={:?}, fr2={:?}", + fr1, fr2 + ); + all_facts.known_placeholder_subset.push((fr1, fr2)); + } + } +} + +/// Emit facts about loan invalidations. +fn emit_loan_invalidations_facts<'tcx>( + all_facts: &mut AllFacts, + tcx: TyCtxt<'tcx>, + location_table: &LocationTable, + body: &Body<'tcx>, + borrow_set: &BorrowSet<'tcx>, +) { + loan_invalidations::emit_loan_invalidations(tcx, all_facts, location_table, body, borrow_set); +} + +/// Emit facts about CFG points and edges, as well as locations where loans are killed. +fn emit_cfg_and_loan_kills_facts<'tcx>( + all_facts: &mut AllFacts, + tcx: TyCtxt<'tcx>, + location_table: &LocationTable, + body: &Body<'tcx>, + borrow_set: &BorrowSet<'tcx>, +) { + loan_kills::emit_loan_kills(tcx, all_facts, location_table, body, borrow_set); +} diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 1c082b7a56c..b308cd82e54 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -7,7 +7,6 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::scc::Sccs; use rustc_errors::Diagnostic; use rustc_hir::def_id::CRATE_DEF_ID; -use rustc_index::bit_set::SparseBitMatrix; use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; @@ -31,8 +30,8 @@ use crate::{ nll::PoloniusOutput, region_infer::reverse_sccs::ReverseSccGraph, region_infer::values::{ - LivenessValues, PlaceholderIndices, PointIndex, RegionElement, RegionValueElements, - RegionValues, ToElementIndex, + LivenessValues, PlaceholderIndices, RegionElement, RegionValueElements, RegionValues, + ToElementIndex, }, type_check::{free_region_relations::UniversalRegionRelations, Locations}, universal_regions::UniversalRegions, @@ -120,9 +119,6 @@ pub struct RegionInferenceContext<'tcx> { /// Information about how the universally quantified regions in /// scope on this function relate to one another. universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, - - /// The set of loans that are live at a given point in the CFG, when using `-Zpolonius=next`. - live_loans: SparseBitMatrix<PointIndex, BorrowIndex>, } /// Each time that `apply_member_constraint` is successful, it appends @@ -335,7 +331,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { type_tests: Vec<TypeTest<'tcx>>, liveness_constraints: LivenessValues, elements: &Rc<RegionValueElements>, - live_loans: SparseBitMatrix<PointIndex, BorrowIndex>, ) -> Self { debug!("universal_regions: {:#?}", universal_regions); debug!("outlives constraints: {:#?}", outlives_constraints); @@ -389,7 +384,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { type_tests, universal_regions, universal_region_relations, - live_loans, }; result.init_free_and_bound_regions(); @@ -2325,7 +2319,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Note: for now, the sets of live loans is only available when using `-Zpolonius=next`. pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, location: Location) -> bool { let point = self.liveness_constraints.point_from_location(location); - self.live_loans.contains(point, loan_idx) + self.liveness_constraints.is_loan_live_at(loan_idx, point) } } diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 41ae65268f2..dc3ee849d00 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -11,6 +11,8 @@ use rustc_middle::ty::{self, RegionVid}; use std::fmt::Debug; use std::rc::Rc; +use crate::dataflow::BorrowIndex; + /// Maps between a `Location` and a `PointIndex` (and vice versa). pub(crate) struct RegionValueElements { /// For each basic block, how many points are contained within? @@ -120,14 +122,45 @@ pub(crate) enum RegionElement { /// Records the CFG locations where each region is live. When we initially compute liveness, we use /// an interval matrix storing liveness ranges for each region-vid. pub(crate) struct LivenessValues { + /// The map from locations to points. elements: Rc<RegionValueElements>, + + /// For each region: the points where it is live. points: SparseIntervalMatrix<RegionVid, PointIndex>, + + /// When using `-Zpolonius=next`, for each point: the loans flowing into the live regions at + /// that point. + pub(crate) loans: Option<LiveLoans>, +} + +/// Data used to compute the loans that are live at a given point in the CFG, when using +/// `-Zpolonius=next`. +pub(crate) struct LiveLoans { + /// The set of loans that flow into a given region. When individual regions are marked as live + /// in the CFG, these inflowing loans are recorded as live. + pub(crate) inflowing_loans: SparseBitMatrix<RegionVid, BorrowIndex>, + + /// The set of loans that are live at a given point in the CFG. + pub(crate) live_loans: SparseBitMatrix<PointIndex, BorrowIndex>, +} + +impl LiveLoans { + pub(crate) fn new(num_loans: usize) -> Self { + LiveLoans { + live_loans: SparseBitMatrix::new(num_loans), + inflowing_loans: SparseBitMatrix::new(num_loans), + } + } } impl LivenessValues { /// Create an empty map of regions to locations where they're live. pub(crate) fn new(elements: Rc<RegionValueElements>) -> Self { - Self { points: SparseIntervalMatrix::new(elements.num_points), elements } + LivenessValues { + points: SparseIntervalMatrix::new(elements.num_points), + elements, + loans: None, + } } /// Iterate through each region that has a value in this set. @@ -140,12 +173,30 @@ impl LivenessValues { debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location); let point = self.elements.point_from_location(location); self.points.insert(region, point); + + // When available, record the loans flowing into this region as live at the given point. + if let Some(loans) = self.loans.as_mut() { + if let Some(inflowing) = loans.inflowing_loans.row(region) { + loans.live_loans.union_row(point, inflowing); + } + } } /// Records `region` as being live at all the given `points`. pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet<PointIndex>) { debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points); self.points.union_row(region, points); + + // When available, record the loans flowing into this region as live at the given points. + if let Some(loans) = self.loans.as_mut() { + if let Some(inflowing) = loans.inflowing_loans.row(region) { + if !inflowing.is_empty() { + for point in points.iter() { + loans.live_loans.union_row(point, inflowing); + } + } + } + } } /// Records `region` as being live at all the control-flow points. @@ -185,6 +236,15 @@ impl LivenessValues { pub(crate) fn point_from_location(&self, location: Location) -> PointIndex { self.elements.point_from_location(location) } + + /// When using `-Zpolonius=next`, returns whether the `loan_idx` is live at the given `point`. + pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, point: PointIndex) -> bool { + self.loans + .as_ref() + .expect("Accessing live loans requires `-Zpolonius=next`") + .live_loans + .contains(point, loan_idx) + } } /// Maps from `ty::PlaceholderRegion` values that are used in the rest of diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 28cc8be8ac9..8e141bb3864 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -77,7 +77,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if argument_index + 1 >= body.local_decls.len() { self.tcx() .sess - .delay_span_bug(body.span, "found more normalized_input_ty than local_decls"); + .span_delayed_bug(body.span, "found more normalized_input_ty than local_decls"); break; } @@ -101,10 +101,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); // We will not have a universal_regions.yield_ty if we yield (by accident) - // outside of a coroutine and return an `impl Trait`, so emit a delay_span_bug + // outside of a coroutine and return an `impl Trait`, so emit a span_delayed_bug // because we don't want to panic in an assert here if we've already got errors. if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() { - self.tcx().sess.delay_span_bug( + self.tcx().sess.span_delayed_bug( body.span, format!( "Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})", diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index a970dadc479..dc4695fd2b0 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -1,7 +1,9 @@ use itertools::{Either, Itertools}; use rustc_data_structures::fx::FxHashSet; -use rustc_middle::mir::{Body, Local}; -use rustc_middle::ty::{RegionVid, TyCtxt}; +use rustc_middle::mir::visit::{TyContext, Visitor}; +use rustc_middle::mir::{Body, Local, Location, SourceInfo}; +use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt}; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; @@ -11,7 +13,7 @@ use crate::{ constraints::OutlivesConstraintSet, facts::{AllFacts, AllFactsExt}, location::LocationTable, - region_infer::values::RegionValueElements, + region_infer::values::{LivenessValues, RegionValueElements}, universal_regions::UniversalRegions, }; @@ -65,6 +67,14 @@ pub(super) fn generate<'mir, 'tcx>( boring_locals, polonius_drop_used, ); + + // Mark regions that should be live where they appear within rvalues or within a call: like + // args, regions, and types. + record_regular_live_regions( + typeck.tcx(), + &mut typeck.borrowck_context.constraints.liveness_constraints, + body, + ); } // The purpose of `compute_relevant_live_locals` is to define the subset of `Local` @@ -132,3 +142,71 @@ fn regions_that_outlive_free_regions<'tcx>( // Return the final set of things we visited. outlives_free_region } + +/// Some variables are "regular live" at `location` -- i.e., they may be used later. This means that +/// all regions appearing in their type must be live at `location`. +fn record_regular_live_regions<'tcx>( + tcx: TyCtxt<'tcx>, + liveness_constraints: &mut LivenessValues, + body: &Body<'tcx>, +) { + let mut visitor = LiveVariablesVisitor { tcx, liveness_constraints }; + for (bb, data) in body.basic_blocks.iter_enumerated() { + visitor.visit_basic_block_data(bb, data); + } +} + +/// Visitor looking for regions that should be live within rvalues or calls. +struct LiveVariablesVisitor<'cx, 'tcx> { + tcx: TyCtxt<'tcx>, + liveness_constraints: &'cx mut LivenessValues, +} + +impl<'cx, 'tcx> Visitor<'tcx> for LiveVariablesVisitor<'cx, 'tcx> { + /// We sometimes have `args` within an rvalue, or within a + /// call. Make them live at the location where they appear. + fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) { + self.record_regions_live_at(*args, location); + self.super_args(args); + } + + /// We sometimes have `region`s within an rvalue, or within a + /// call. Make them live at the location where they appear. + fn visit_region(&mut self, region: Region<'tcx>, location: Location) { + self.record_regions_live_at(region, location); + self.super_region(region); + } + + /// We sometimes have `ty`s within an rvalue, or within a + /// call. Make them live at the location where they appear. + fn visit_ty(&mut self, ty: Ty<'tcx>, ty_context: TyContext) { + match ty_context { + TyContext::ReturnTy(SourceInfo { span, .. }) + | TyContext::YieldTy(SourceInfo { span, .. }) + | TyContext::UserTy(span) + | TyContext::LocalDecl { source_info: SourceInfo { span, .. }, .. } => { + span_bug!(span, "should not be visiting outside of the CFG: {:?}", ty_context); + } + TyContext::Location(location) => { + self.record_regions_live_at(ty, location); + } + } + + self.super_ty(ty); + } +} + +impl<'cx, 'tcx> LiveVariablesVisitor<'cx, 'tcx> { + /// Some variable is "regular live" at `location` -- i.e., it may be used later. This means that + /// all regions appearing in the type of `value` must be live at `location`. + fn record_regions_live_at<T>(&mut self, value: T, location: Location) + where + T: TypeVisitable<TyCtxt<'tcx>>, + { + debug!("record_regions_live_at(value={:?}, location={:?})", value, location); + self.tcx.for_each_free_region(&value, |live_region| { + let live_region_vid = live_region.as_var(); + self.liveness_constraints.add_location(live_region_vid, location); + }); + } +} diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 02ccf928d8e..c718d57bec3 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -1,12 +1,12 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::WithSuccessors; -use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix}; +use rustc_index::bit_set::HybridBitSet; use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::for_liveness; use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; use rustc_middle::traits::query::DropckOutlivesResult; -use rustc_middle::ty::{RegionVid, Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -16,9 +16,8 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex}; use rustc_mir_dataflow::ResultsCursor; -use crate::dataflow::BorrowIndex; use crate::{ - region_infer::values::{self, PointIndex, RegionValueElements}, + region_infer::values::{self, LiveLoans, PointIndex, RegionValueElements}, type_check::liveness::local_use_map::LocalUseMap, type_check::liveness::polonius, type_check::NormalizeLocation, @@ -49,22 +48,17 @@ pub(super) fn trace<'mir, 'tcx>( boring_locals: Vec<Local>, polonius_drop_used: Option<Vec<(Local, Location)>>, ) { - debug!("trace()"); - let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body); // When using `-Zpolonius=next`, compute the set of loans that can reach a given region. - let num_loans = typeck.borrowck_context.borrow_set.len(); - let mut inflowing_loans = SparseBitMatrix::new(num_loans); if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() { - let borrowck_context = &typeck.borrowck_context; + let borrowck_context = &mut typeck.borrowck_context; let borrow_set = &borrowck_context.borrow_set; - let constraint_set = &borrowck_context.constraints.outlives_constraints; - - let num_region_vars = typeck.infcx.num_region_vars(); - let graph = constraint_set.graph(num_region_vars); + let mut live_loans = LiveLoans::new(borrow_set.len()); + let outlives_constraints = &borrowck_context.constraints.outlives_constraints; + let graph = outlives_constraints.graph(typeck.infcx.num_region_vars()); let region_graph = - graph.region_graph(constraint_set, borrowck_context.universal_regions.fr_static); + graph.region_graph(outlives_constraints, borrowck_context.universal_regions.fr_static); // Traverse each issuing region's constraints, and record the loan as flowing into the // outlived region. @@ -75,9 +69,13 @@ pub(super) fn trace<'mir, 'tcx>( continue; } - inflowing_loans.insert(succ, loan); + live_loans.inflowing_loans.insert(succ, loan); } } + + // Store the inflowing loans in the liveness constraints: they will be used to compute live + // loans when liveness data is recorded there. + borrowck_context.constraints.liveness_constraints.loans = Some(live_loans); }; let cx = LivenessContext { @@ -88,7 +86,6 @@ pub(super) fn trace<'mir, 'tcx>( local_use_map, move_data, drop_data: FxIndexMap::default(), - inflowing_loans, }; let mut results = LivenessResults::new(cx); @@ -126,9 +123,6 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { /// Index indicating where each variable is assigned, used, or /// dropped. local_use_map: &'me LocalUseMap, - - /// Set of loans that flow into a given region, when using `-Zpolonius=next`. - inflowing_loans: SparseBitMatrix<RegionVid, BorrowIndex>, } struct DropData<'tcx> { @@ -519,14 +513,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { live_at: &IntervalSet<PointIndex>, ) { debug!("add_use_live_facts_for(value={:?})", value); - - Self::make_all_regions_live( - self.elements, - self.typeck, - value, - live_at, - &self.inflowing_loans, - ); + Self::make_all_regions_live(self.elements, self.typeck, value, live_at); } /// Some variable with type `live_ty` is "drop live" at `location` @@ -577,14 +564,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { // All things in the `outlives` array may be touched by // the destructor and must be live at this point. for &kind in &drop_data.dropck_result.kinds { - Self::make_all_regions_live( - self.elements, - self.typeck, - kind, - live_at, - &self.inflowing_loans, - ); - + Self::make_all_regions_live(self.elements, self.typeck, kind, live_at); polonius::add_drop_of_var_derefs_origin(self.typeck, dropped_local, &kind); } } @@ -594,7 +574,6 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { typeck: &mut TypeChecker<'_, 'tcx>, value: impl TypeVisitable<TyCtxt<'tcx>>, live_at: &IntervalSet<PointIndex>, - inflowing_loans: &SparseBitMatrix<RegionVid, BorrowIndex>, ) { debug!("make_all_regions_live(value={:?})", value); debug!( @@ -602,12 +581,6 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { values::pretty_print_points(elements, live_at.iter()), ); - // When using `-Zpolonius=next`, we want to record the loans that flow into this value's - // regions as being live at the given `live_at` points: this will be used to compute the - // location where a loan goes out of scope. - let num_loans = typeck.borrowck_context.borrow_set.len(); - let value_loans = &mut HybridBitSet::new_empty(num_loans); - value.visit_with(&mut for_liveness::FreeRegionsVisitor { tcx: typeck.tcx(), param_env: typeck.param_env, @@ -619,21 +592,8 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { .constraints .liveness_constraints .add_points(live_region_vid, live_at); - - // There can only be inflowing loans for this region when we are using - // `-Zpolonius=next`. - if let Some(inflowing) = inflowing_loans.row(live_region_vid) { - value_loans.union(inflowing); - } }, }); - - // Record the loans reaching the value. - if !value_loans.is_empty() { - for point in live_at.iter() { - typeck.borrowck_context.live_loans.union_row(point, value_loans); - } - } } fn compute_drop_data( diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d4fd1a3cf2a..ecc9905e33e 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -14,7 +14,6 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; -use rustc_index::bit_set::SparseBitMatrix; use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; @@ -51,8 +50,6 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; -use crate::dataflow::BorrowIndex; -use crate::region_infer::values::PointIndex; use crate::session_diagnostics::{MoveUnsized, SimdShuffleLastConst}; use crate::{ borrow_set::BorrowSet, @@ -166,9 +163,6 @@ pub(crate) fn type_check<'mir, 'tcx>( debug!(?normalized_inputs_and_output); - // When using `-Zpolonius=next`, liveness will record the set of live loans per point. - let mut live_loans = SparseBitMatrix::new(borrow_set.len()); - let mut borrowck_context = BorrowCheckContext { universal_regions, location_table, @@ -176,7 +170,6 @@ pub(crate) fn type_check<'mir, 'tcx>( all_facts, constraints: &mut constraints, upvars, - live_loans: &mut live_loans, }; let mut checker = TypeChecker::new( @@ -232,7 +225,7 @@ pub(crate) fn type_check<'mir, 'tcx>( let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); if hidden_type.has_non_region_infer() { - let reported = infcx.tcx.sess.delay_span_bug( + let reported = infcx.tcx.sess.span_delayed_bug( decl.hidden_type.span, format!("could not resolve {:#?}", hidden_type.ty.kind()), ); @@ -243,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>( }) .collect(); - MirTypeckResults { constraints, universal_region_relations, opaque_type_values, live_loans } + MirTypeckResults { constraints, universal_region_relations, opaque_type_values } } fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) { @@ -274,9 +267,9 @@ fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) { #[track_caller] fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: String) { // We sometimes see MIR failures (notably predicate failures) due to - // the fact that we check rvalue sized predicates here. So use `delay_span_bug` + // the fact that we check rvalue sized predicates here. So use `span_delayed_bug` // to avoid reporting bugs in those cases. - tcx.sess.diagnostic().delay_span_bug(span, msg); + tcx.sess.diagnostic().span_delayed_bug(span, msg); } enum FieldAccessError { @@ -858,10 +851,6 @@ struct BorrowCheckContext<'a, 'tcx> { borrow_set: &'a BorrowSet<'tcx>, pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>, upvars: &'a [&'a ty::CapturedPlace<'tcx>], - - /// The set of loans that are live at a given point in the CFG, filled in by `liveness::trace`, - /// when using `-Zpolonius=next`. - pub(crate) live_loans: &'a mut SparseBitMatrix<PointIndex, BorrowIndex>, } /// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions @@ -870,9 +859,6 @@ pub(crate) struct MirTypeckResults<'tcx> { pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, pub(crate) opaque_type_values: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>, - - /// The set of loans that are live at a given point in the CFG, when using `-Zpolonius=next`. - pub(crate) live_loans: SparseBitMatrix<PointIndex, BorrowIndex>, } /// A collection of region constraints that must be satisfied for the @@ -1082,7 +1068,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); if result.is_err() { - self.infcx.tcx.sess.delay_span_bug( + self.infcx.tcx.sess.span_delayed_bug( self.body.span, "failed re-defining predefined opaques in mir typeck", ); diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 070d50708ff..e13d217ef01 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -31,10 +31,7 @@ pub fn expand( { (item, true, ecx.with_def_site_ctxt(fn_kind.sig.span)) } else { - ecx.sess - .parse_sess - .span_diagnostic - .emit_err(errors::AllocErrorMustBeFn { span: item.span() }); + ecx.sess.diagnostic().emit_err(errors::AllocErrorMustBeFn { span: item.span() }); return vec![orig_item]; }; diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 5499852e177..96e9584c209 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -19,8 +19,8 @@ fn invalid_type_err( let snippet = cx.sess.source_map().span_to_snippet(span).ok(); match ast::LitKind::from_token_lit(token_lit) { Ok(ast::LitKind::CStr(_, _)) => { - // FIXME(c_str_literals): should concatenation of C string literals - // include the null bytes in the end? + // Avoid ambiguity in handling of terminal `NUL` by refusing to + // concatenate C string literals as bytes. cx.emit_err(errors::ConcatCStrLit { span: span }); } Ok(ast::LitKind::Char(_)) => { diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 33392edf060..6dc75e3ba4c 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -34,10 +34,7 @@ pub fn expand( { (item, true, ecx.with_def_site_ctxt(ty.span)) } else { - ecx.sess - .parse_sess - .span_diagnostic - .emit_err(errors::AllocMustStatics { span: item.span() }); + ecx.sess.diagnostic().emit_err(errors::AllocMustStatics { span: item.span() }); return vec![orig_item]; }; diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index c0055380c25..bf1e1ebf5dd 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -389,7 +389,7 @@ pub fn expand_test_or_bench( } fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) { - let diag = &cx.sess.parse_sess.span_diagnostic; + let diag = cx.sess.diagnostic(); let msg = "the `#[test]` attribute may only be used on a non-associated function"; let mut err = match item.map(|i| &i.kind) { // These were a warning before #92959 and need to continue being that to avoid breaking @@ -466,7 +466,7 @@ fn should_ignore_message(i: &ast::Item) -> Option<Symbol> { fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { match attr::find_by_name(&i.attrs, sym::should_panic) { Some(attr) => { - let sd = &cx.sess.parse_sess.span_diagnostic; + let sd = cx.sess.diagnostic(); match attr.meta_item_list() { // Handle #[should_panic(expected = "foo")] @@ -535,7 +535,7 @@ fn check_test_signature( f: &ast::Fn, ) -> Result<(), ErrorGuaranteed> { let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic); - let sd = &cx.sess.parse_sess.span_diagnostic; + let sd = cx.sess.diagnostic(); if let ast::Unsafe::Yes(span) = f.sig.header.unsafety { return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" })); @@ -579,7 +579,7 @@ fn check_bench_signature( // N.B., inadequate check, but we're running // well before resolve, can't get too deep. if f.sig.decl.inputs.len() != 1 { - return Err(cx.sess.parse_sess.span_diagnostic.emit_err(errors::BenchSig { span: i.span })); + return Err(cx.sess.diagnostic().emit_err(errors::BenchSig { span: i.span })); } Ok(()) } diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 8655aeec13d..db297425b03 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -25,6 +25,7 @@ use std::ffi::{CStr, CString}; use std::fs::File; use std::io; use std::iter; +use std::mem::ManuallyDrop; use std::path::Path; use std::slice; use std::sync::Arc; @@ -734,7 +735,7 @@ pub unsafe fn optimize_thin_module( let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &diag_handler)? as *const _; let mut module = ModuleCodegen { - module_llvm: ModuleLlvm { llmod_raw, llcx, tm }, + module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }, name: thin_module.name().to_string(), kind: ModuleKind::Regular, }; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 3a8b8e1ad11..1a567c0fce8 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -571,7 +571,6 @@ pub(crate) unsafe fn llvm_optimize( unroll_loops, config.vectorize_slp, config.vectorize_loop, - config.no_builtins, config.emit_lifetime_markers, sanitizer_options.as_ref(), pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), @@ -686,7 +685,6 @@ pub(crate) unsafe fn codegen( unsafe fn with_codegen<'ll, F, R>( tm: &'ll llvm::TargetMachine, llmod: &'ll llvm::Module, - no_builtins: bool, f: F, ) -> R where @@ -694,7 +692,7 @@ pub(crate) unsafe fn codegen( { let cpm = llvm::LLVMCreatePassManager(); llvm::LLVMAddAnalysisPasses(tm, cpm); - llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins); + llvm::LLVMRustAddLibraryInfo(cpm, llmod); f(cpm) } @@ -797,7 +795,7 @@ pub(crate) unsafe fn codegen( } else { llmod }; - with_codegen(tm, llmod, config.no_builtins, |cpm| { + with_codegen(tm, llmod, |cpm| { write_output_file( diag_handler, tm, @@ -832,7 +830,7 @@ pub(crate) unsafe fn codegen( (_, SplitDwarfKind::Split) => Some(dwo_out.as_path()), }; - with_codegen(tm, llmod, config.no_builtins, |cpm| { + with_codegen(tm, llmod, |cpm| { write_output_file( diag_handler, tm, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index f8a0423e9b1..915cf31de08 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -52,6 +52,7 @@ use rustc_span::symbol::Symbol; use std::any::Any; use std::ffi::CStr; use std::io::Write; +use std::mem::ManuallyDrop; mod back { pub mod archive; @@ -407,8 +408,9 @@ pub struct ModuleLlvm { llcx: &'static mut llvm::Context, llmod_raw: *const llvm::Module, - // independent from llcx and llmod_raw, resources get disposed by drop impl - tm: OwnedTargetMachine, + // This field is `ManuallyDrop` because it is important that the `TargetMachine` + // is disposed prior to the `Context` being disposed otherwise UAFs can occur. + tm: ManuallyDrop<OwnedTargetMachine>, } unsafe impl Send for ModuleLlvm {} @@ -419,7 +421,11 @@ impl ModuleLlvm { unsafe { let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; - ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, mod_name) } + ModuleLlvm { + llmod_raw, + llcx, + tm: ManuallyDrop::new(create_target_machine(tcx, mod_name)), + } } } @@ -427,7 +433,11 @@ impl ModuleLlvm { unsafe { let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; - ModuleLlvm { llmod_raw, llcx, tm: create_informational_target_machine(tcx.sess) } + ModuleLlvm { + llmod_raw, + llcx, + tm: ManuallyDrop::new(create_informational_target_machine(tcx.sess)), + } } } @@ -448,7 +458,7 @@ impl ModuleLlvm { } }; - Ok(ModuleLlvm { llmod_raw, llcx, tm }) + Ok(ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) }) } } @@ -460,6 +470,7 @@ impl ModuleLlvm { impl Drop for ModuleLlvm { fn drop(&mut self) { unsafe { + ManuallyDrop::drop(&mut self.tm); llvm::LLVMContextDispose(&mut *(self.llcx as *mut _)); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index d701b20e953..6c3ccc9cf0d 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2163,13 +2163,8 @@ extern "C" { ArgsCstrBuff: *const c_char, ArgsCstrBuffLen: usize, ) -> *mut TargetMachine; - pub fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine); - pub fn LLVMRustAddLibraryInfo<'a>( - PM: &PassManager<'a>, - M: &'a Module, - DisableSimplifyLibCalls: bool, - ); + pub fn LLVMRustAddLibraryInfo<'a>(PM: &PassManager<'a>, M: &'a Module); pub fn LLVMRustWriteOutputFile<'a>( T: &'a TargetMachine, PM: &PassManager<'a>, @@ -2191,7 +2186,6 @@ extern "C" { UnrollLoops: bool, SLPVectorize: bool, LoopVectorize: bool, - DisableSimplifyLibCalls: bool, EmitLifetimeMarkers: bool, SanitizerOptions: Option<&SanitizerOptions>, PGOGenPath: *const c_char, diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index be895417bbe..000b2748e4f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -143,7 +143,7 @@ pub fn link_binary<'a>( } } if sess.opts.json_artifact_notifications { - sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename, "link"); + sess.diagnostic().emit_artifact_notification(&out_filename, "link"); } if sess.prof.enabled() { @@ -270,8 +270,14 @@ pub fn each_linked_rlib( for &cnum in crates { match fmts.get(cnum.as_usize() - 1) { - Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue, - Some(_) => {} + Some(&Linkage::NotLinked | &Linkage::Dynamic) => continue, + Some(&Linkage::IncludedFromDylib) => { + // We always link crate `compiler_builtins` statically. When enabling LTO, we include it as well. + if info.compiler_builtins != Some(cnum) { + continue; + } + } + Some(&Linkage::Static) => {} None => return Err(errors::LinkRlibError::MissingFormat), } let crate_name = info.crate_name[&cnum]; @@ -520,8 +526,7 @@ fn link_staticlib<'a>( &codegen_results.crate_info, Some(CrateType::Staticlib), &mut |cnum, path| { - let lto = are_upstream_rust_objects_already_included(sess) - && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); + let lto = are_upstream_rust_objects_already_included(sess); let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter(); let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib)); @@ -1256,24 +1261,6 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { } } -/// Returns a boolean indicating whether the specified crate should be ignored -/// during LTO. -/// -/// Crates ignored during LTO are not lumped together in the "massive object -/// file" that we create and are linked in their normal rlib states. See -/// comments below for what crates do not participate in LTO. -/// -/// It's unusual for a crate to not participate in LTO. Typically only -/// compiler-specific and unstable crates have a reason to not participate in -/// LTO. -pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool { - // If our target enables builtin function lowering in LLVM then the - // crates providing these functions don't participate in LTO (e.g. - // no_builtins or compiler builtins crates). - !sess.target.no_builtins - && (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum)) -} - /// This functions tries to determine the appropriate linker (and corresponding LinkerFlavor) to use pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { fn infer_from( @@ -1477,7 +1464,7 @@ fn print_native_static_libs( sess.emit_note(errors::StaticLibraryNativeArtifacts); // Prefix for greppability // Note: This must not be translated as tools are allowed to depend on this exact string. - sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" "))); + sess.note(format!("native-static-libs: {}", &lib_args.join(" "))); } } } @@ -2739,10 +2726,6 @@ fn rehome_sysroot_lib_dir<'a>(sess: &'a Session, lib_dir: &Path) -> PathBuf { // symbols). We must continue to include the rest of the rlib, however, as // it may contain static native libraries which must be linked in. // -// (*) Crates marked with `#![no_builtins]` don't participate in LTO and -// their bytecode wasn't included. The object files in those libraries must -// still be passed to the linker. -// // Note, however, that if we're not doing LTO we can just pass the rlib // blindly to the linker (fast) because it's fine if it's not actually // included as we're at the end of the dependency chain. @@ -2768,9 +2751,7 @@ fn add_static_crate<'a>( cmd.link_rlib(&rlib_path); }; - if !are_upstream_rust_objects_already_included(sess) - || ignored_for_lto(sess, &codegen_results.crate_info, cnum) - { + if !are_upstream_rust_objects_already_included(sess) { link_upstream(cratepath); return; } @@ -2784,8 +2765,6 @@ fn add_static_crate<'a>( let canonical_name = name.replace('-', "_"); let upstream_rust_objects_already_included = are_upstream_rust_objects_already_included(sess); - let is_builtins = - sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum); let mut archive = archive_builder_builder.new_archive_builder(sess); if let Err(error) = archive.add_archive( @@ -2802,9 +2781,8 @@ fn add_static_crate<'a>( // If we're performing LTO and this is a rust-generated object // file, then we don't need the object file as it's part of the - // LTO module. Note that `#![no_builtins]` is excluded from LTO, - // though, so we let that object file slide. - if upstream_rust_objects_already_included && is_rust_object && is_builtins { + // LTO module. + if upstream_rust_objects_already_included && is_rust_object { return true; } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index d716774690a..3e26e3653ea 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -12,9 +12,9 @@ use object::{ use rustc_data_structures::memmap::Mmap; use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice}; +use rustc_metadata::creader::MetadataLoader; use rustc_metadata::fs::METADATA_FILENAME; use rustc_metadata::EncodedMetadata; -use rustc_session::cstore::MetadataLoader; use rustc_session::Session; use rustc_span::sym; use rustc_target::abi::Endian; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index b12ac881100..5f2fad0536b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -54,8 +54,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S // export level, however, as they're just implementation details. // Down below we'll hardwire all of the symbols to the `Rust` export // level instead. - let special_runtime_crate = - tcx.is_panic_runtime(LOCAL_CRATE) || tcx.is_compiler_builtins(LOCAL_CRATE); + let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE); + let special_runtime_crate = tcx.is_panic_runtime(LOCAL_CRATE) || is_compiler_builtins; let mut reachable_non_generics: DefIdMap<_> = tcx .reachable_set(()) @@ -107,7 +107,11 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S .map(|def_id| { // We won't link right if this symbol is stripped during LTO. let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name; - let used = name == "rust_eh_personality"; + // We have to preserve the symbols of the built-in functions during LTO. + let is_builtin_fn = is_compiler_builtins + && symbol_export_level(tcx, def_id.to_def_id()) + .is_below_threshold(SymbolExportLevel::C); + let used = is_builtin_fn || name == "rust_eh_personality"; let export_level = if special_runtime_crate { SymbolExportLevel::Rust diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 8f17e4ea0bd..618a72272e5 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -148,23 +148,12 @@ impl ModuleConfig { let emit_obj = if !should_emit_obj { EmitObj::None - } else if sess.target.obj_is_bitcode - || (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins) - { + } else if sess.target.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() { // This case is selected if the target uses objects as bitcode, or // if linker plugin LTO is enabled. In the linker plugin LTO case // the assumption is that the final link-step will read the bitcode // and convert it to object code. This may be done by either the // native linker or rustc itself. - // - // Note, however, that the linker-plugin-lto requested here is - // explicitly ignored for `#![no_builtins]` crates. These crates are - // specifically ignored by rustc's LTO passes and wouldn't work if - // loaded into the linker. These crates define symbols that LLVM - // lowers intrinsics to, and these symbol dependencies aren't known - // until after codegen. As a result any crate marked - // `#![no_builtins]` is assumed to not participate in LTO and - // instead goes on to generate object code. EmitObj::Bitcode } else if need_bitcode_in_object(tcx) { EmitObj::ObjectCode(BitcodeSection::Full) @@ -1037,9 +1026,6 @@ fn start_executing_work<B: ExtraBackendMethods>( let mut each_linked_rlib_for_lto = Vec::new(); drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| { - if link::ignored_for_lto(sess, crate_info, cnum) { - return; - } each_linked_rlib_for_lto.push((cnum, path.to_path_buf())); })); @@ -1870,7 +1856,7 @@ impl SharedEmitterMain { let mut err = match level { Level::Error { lint: false } => sess.struct_err(msg).forget_guarantee(), Level::Warning(_) => sess.struct_warn(msg), - Level::Note => sess.struct_note_without_error(msg), + Level::Note => sess.struct_note(msg), _ => bug!("Invalid inline asm diagnostic level"), }; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 1d5205ac67a..b87f4b6bf89 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -858,7 +858,6 @@ impl CrateInfo { local_crate_name, compiler_builtins, profiler_runtime: None, - is_no_builtins: Default::default(), native_libraries: Default::default(), used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(), crate_name: Default::default(), @@ -885,9 +884,6 @@ impl CrateInfo { if tcx.is_profiler_runtime(cnum) { info.profiler_runtime = Some(cnum); } - if tcx.is_no_builtins(cnum) { - info.is_no_builtins.insert(cnum); - } } // Handle circular dependencies in the standard library. @@ -895,9 +891,7 @@ impl CrateInfo { // If global LTO is enabled then almost everything (*) is glued into a single object file, // so this logic is not necessary and can cause issues on some targets (due to weak lang // item symbols being "privatized" to that object file), so we disable it. - // (*) Native libs, and `#[compiler_builtins]` and `#[no_builtins]` crates are not glued, - // and we assume that they cannot define weak lang items. This is not currently enforced - // by the compiler, but that's ok because all this stuff is unstable anyway. + // (*) Native libs are not glued, and we assume that they cannot define weak lang items. let target = &tcx.sess.target; if !are_upstream_rust_objects_already_included(tcx.sess) { let missing_weak_lang_items: FxHashSet<Symbol> = info diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index e2b36fbd65b..40a985cf255 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -91,7 +91,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { Some(tcx.fn_sig(did)) } else { tcx.sess - .delay_span_bug(attr.span, "this attribute can only be applied to functions"); + .span_delayed_bug(attr.span, "this attribute can only be applied to functions"); None } }; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index bfd0a458884..cd5eb77e06e 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -25,7 +25,7 @@ extern crate tracing; extern crate rustc_middle; use rustc_ast as ast; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_hir::def_id::CrateNum; use rustc_middle::dep_graph::WorkProduct; @@ -157,7 +157,6 @@ pub struct CrateInfo { pub local_crate_name: Symbol, pub compiler_builtins: Option<CrateNum>, pub profiler_runtime: Option<CrateNum>, - pub is_no_builtins: FxHashSet<CrateNum>, pub native_libraries: FxHashMap<CrateNum, Vec<NativeLib>>, pub crate_name: FxHashMap<CrateNum, Symbol>, pub used_libraries: Vec<NativeLib>, diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 35744d9a167..8e9907ed8bb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -9,6 +9,7 @@ use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_errors::ErrorGuaranteed; +use rustc_metadata::creader::MetadataLoaderDyn; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout}; @@ -16,7 +17,6 @@ use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::util::Providers; use rustc_session::{ config::{self, OutputFilenames, PrintRequest}, - cstore::MetadataLoaderDyn, Session, }; use rustc_span::symbol::Symbol; diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index bf1e0a37073..4934fcc75ec 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -148,7 +148,7 @@ where let mut err = tcx.sess.create_err(err); let msg = error.diagnostic_message(); - error.add_args(&tcx.sess.parse_sess.span_diagnostic, &mut err); + error.add_args(tcx.sess.diagnostic(), &mut err); // Use *our* span to label the interp error err.span_label(our_span, msg); diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 4b13a3404a0..2d8ca67c3a5 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -391,7 +391,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, if ecx.tcx.is_ctfe_mir_available(def) { Ok(ecx.tcx.mir_for_ctfe(def)) } else if ecx.tcx.def_kind(def) == DefKind::AssocConst { - let guar = ecx.tcx.sess.delay_span_bug( + let guar = ecx.tcx.sess.span_delayed_bug( rustc_span::DUMMY_SP, "This is likely a const item that is missing from its impl", ); @@ -622,7 +622,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, let guard = ecx .tcx .sess - .delay_span_bug(span, "The deny lint should have already errored"); + .span_delayed_bug(span, "The deny lint should have already errored"); throw_inval!(AlreadyReported(guard.into())); } } else if new_steps > start && new_steps.is_power_of_two() { diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index cc8f3387238..8343dc2dd35 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -437,7 +437,7 @@ pub trait ReportErrorExt { { ty::tls::with(move |tcx| { let mut builder = tcx.sess.struct_allow(DiagnosticMessage::Str(String::new().into())); - let handler = &tcx.sess.parse_sess.span_diagnostic; + let handler = tcx.sess.diagnostic(); let message = self.diagnostic_message(); self.add_args(handler, &mut builder); let s = handler.eagerly_translate_to_string(message, builder.args()); diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 3bdfc1db913..c0a20e51482 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -173,6 +173,9 @@ impl<Prov: Provenance> std::fmt::Debug for LocalState<'_, Prov> { } /// Current value of a local variable +/// +/// This does not store the type of the local; the type is given by `body.local_decls` and can never +/// change, so by not storing here we avoid having to maintain that as an invariant. #[derive(Copy, Clone, Debug)] // Miri debug-prints these pub(super) enum LocalValue<Prov: Provenance = AllocId> { /// This local is not currently alive, and cannot be used at all. @@ -284,9 +287,9 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> { { write!(f, "inside closure") } else { - // Note: this triggers a `good_path_bug` state, which means that if we ever get here - // we must emit a diagnostic. We should never display a `FrameInfo` unless we - // actually want to emit a warning or error to the user. + // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever + // get here we must emit a diagnostic. We should never display a `FrameInfo` unless + // we actually want to emit a warning or error to the user. write!(f, "inside `{}`", self.instance) } }) @@ -300,8 +303,8 @@ impl<'tcx> FrameInfo<'tcx> { errors::FrameNote { where_: "closure", span, instance: String::new(), times: 0 } } else { let instance = format!("{}", self.instance); - // Note: this triggers a `good_path_bug` state, which means that if we ever get here - // we must emit a diagnostic. We should never display a `FrameInfo` unless we + // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever get + // here we must emit a diagnostic. We should never display a `FrameInfo` unless we // actually want to emit a warning or error to the user. errors::FrameNote { where_: "instance", span, instance, times: 0 } } @@ -470,7 +473,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { backtrace.print_backtrace(); // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the // label and arguments from the InterpError. - let handler = &self.tcx.sess.parse_sess.span_diagnostic; + let handler = self.tcx.sess.diagnostic(); #[allow(rustc::untranslatable_diagnostic)] let mut diag = self.tcx.sess.struct_allow(""); let msg = e.diagnostic_message(); diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 413963b2fdc..881df9b04ab 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -94,9 +94,9 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval: // If the pointer is dangling (neither in local nor global memory), we leave it // to validation to error -- it has the much better error messages, pointing out where // in the value the dangling reference lies. - // The `delay_span_bug` ensures that we don't forget such a check in validation. + // The `span_delayed_bug` ensures that we don't forget such a check in validation. if tcx.try_get_global_alloc(alloc_id).is_none() { - tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer"); + tcx.sess.span_delayed_bug(ecx.tcx.span, "tried to intern dangling pointer"); } // treat dangling pointers like other statics // just to stop trying to recurse into them @@ -186,7 +186,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory // Validation will error (with a better message) on an invalid vtable pointer. // Let validation show the error message, but make sure it *does* error. tcx.sess - .delay_span_bug(tcx.span, "vtables pointers cannot be integer pointers"); + .span_delayed_bug(tcx.span, "vtables pointers cannot be integer pointers"); } } // Check if we have encountered this pointer+layout combination before. @@ -375,7 +375,7 @@ pub fn intern_const_alloc_recursive< match res { Ok(()) => {} Err(error) => { - ecx.tcx.sess.delay_span_bug( + ecx.tcx.sess.span_delayed_bug( ecx.tcx.span, format!( "error during interning should later cause validation failure: {}", diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 13742ad273b..bcc42a376ea 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -248,7 +248,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's // no need to emit duplicate errors here. if self.ccx.is_async() || body.coroutine.is_some() { - tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`"); + tcx.sess.span_delayed_bug(body.span, "`async` functions cannot be `const fn`"); return; } @@ -357,7 +357,9 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { fn check_static(&mut self, def_id: DefId, span: Span) { if self.tcx.is_thread_local_static(def_id) { - self.tcx.sess.delay_span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`"); + self.tcx + .sess + .span_delayed_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`"); } self.check_op_spanned(ops::StaticAccess, span) } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 4c2492d1867..4f7e165c575 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -112,7 +112,7 @@ pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { None if is_parent_const_stable_trait(tcx, def_id) => { // Remove this when `#![feature(const_trait_impl)]` is stabilized, // returning `true` unconditionally. - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( tcx.def_span(def_id), "trait implementations cannot be const stable yet", ); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 3e8a0a2b7df..eaf4abf39b7 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -128,9 +128,9 @@ impl<'a, 'tcx> CfgChecker<'a, 'tcx> { #[track_caller] fn fail(&self, location: Location, msg: impl AsRef<str>) { let span = self.body.source_info(location).span; - // We use `delay_span_bug` as we might see broken MIR when other errors have already + // We use `span_delayed_bug` as we might see broken MIR when other errors have already // occurred. - self.tcx.sess.diagnostic().delay_span_bug( + self.tcx.sess.diagnostic().span_delayed_bug( span, format!( "broken MIR in {:?} ({}) at {:?}:\n{}", @@ -571,7 +571,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { fn visit_source_scope(&mut self, scope: SourceScope) { if self.body.source_scopes.get(scope).is_none() { - self.tcx.sess.diagnostic().delay_span_bug( + self.tcx.sess.diagnostic().span_delayed_bug( self.body.span, format!( "broken MIR in {:?} ({}):\ninvalid source scope {:?}", diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 6af11ce8479..450e1ead0b2 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -33,10 +33,10 @@ use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::unerased_lint_store; +use rustc_metadata::creader::MetadataLoader; use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths}; -use rustc_session::cstore::MetadataLoader; use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; use rustc_session::{config, EarlyErrorHandler, Session}; diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 85acf8ab5aa..3823a1707ec 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -351,18 +351,10 @@ impl<'a> DiagnosticBuilder<'a, !> { /// `struct_*` methods on [`Handler`]. #[track_caller] pub(crate) fn new_fatal(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self { - let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); - Self::new_diagnostic_fatal(handler, diagnostic) - } - - /// Creates a new `DiagnosticBuilder` with an already constructed - /// diagnostic. - pub(crate) fn new_diagnostic_fatal(handler: &'a Handler, diagnostic: Diagnostic) -> Self { - debug!("Created new diagnostic"); Self { inner: DiagnosticBuilderInner { state: DiagnosticBuilderState::Emittable(handler), - diagnostic: Box::new(diagnostic), + diagnostic: Box::new(Diagnostic::new_with_code(Level::Fatal, None, message)), }, _marker: PhantomData, } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6bd87f54140..5966fd80f97 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -431,10 +431,10 @@ struct HandlerInner { warn_count: usize, deduplicated_err_count: usize, emitter: Box<DynEmitter>, - delayed_span_bugs: Vec<DelayedDiagnostic>, - delayed_good_path_bugs: Vec<DelayedDiagnostic>, + span_delayed_bugs: Vec<DelayedDiagnostic>, + good_path_delayed_bugs: Vec<DelayedDiagnostic>, /// This flag indicates that an expected diagnostic was emitted and suppressed. - /// This is used for the `delayed_good_path_bugs` check. + /// This is used for the `good_path_delayed_bugs` check. suppressed_expected_diag: bool, /// This set contains the `DiagnosticId` of all emitted diagnostics to avoid @@ -528,7 +528,7 @@ pub struct HandlerFlags { /// If true, immediately emit diagnostics that would otherwise be buffered. /// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`) pub dont_buffer_diagnostics: bool, - /// If true, immediately print bugs registered with `delay_span_bug`. + /// If true, immediately print bugs registered with `span_delayed_bug`. /// (rustc: see `-Z report-delayed-bugs`) pub report_delayed_bugs: bool, /// Show macro backtraces. @@ -545,20 +545,20 @@ impl Drop for HandlerInner { self.emit_stashed_diagnostics(); if !self.has_errors() { - let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new()); - self.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued"); + let bugs = std::mem::replace(&mut self.span_delayed_bugs, Vec::new()); + self.flush_delayed(bugs, "no errors encountered even though `span_delayed_bug` issued"); } - // FIXME(eddyb) this explains what `delayed_good_path_bugs` are! - // They're `delayed_span_bugs` but for "require some diagnostic happened" + // FIXME(eddyb) this explains what `good_path_delayed_bugs` are! + // They're `span_delayed_bugs` but for "require some diagnostic happened" // instead of "require some error happened". Sadly that isn't ideal, as // lints can be `#[allow]`'d, potentially leading to this triggering. // Also, "good path" should be replaced with a better naming. if !self.has_any_message() && !self.suppressed_expected_diag && !std::thread::panicking() { - let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new()); + let bugs = std::mem::replace(&mut self.good_path_delayed_bugs, Vec::new()); self.flush_delayed( bugs, - "no warnings or errors encountered even though `delayed_good_path_bugs` issued", + "no warnings or errors encountered even though `good_path_delayed_bugs` issued", ); } @@ -609,8 +609,8 @@ impl Handler { deduplicated_err_count: 0, deduplicated_warn_count: 0, emitter, - delayed_span_bugs: Vec::new(), - delayed_good_path_bugs: Vec::new(), + span_delayed_bugs: Vec::new(), + good_path_delayed_bugs: Vec::new(), suppressed_expected_diag: false, taught_diagnostics: Default::default(), emitted_diagnostic_codes: Default::default(), @@ -648,7 +648,7 @@ impl Handler { // This is here to not allow mutation of flags; // as of this writing it's only used in tests in librustc_middle. pub fn can_emit_warnings(&self) -> bool { - self.inner.lock().flags.can_emit_warnings + self.inner.borrow_mut().flags.can_emit_warnings } /// Resets the diagnostic error count as well as the cached emitted diagnostics. @@ -664,8 +664,8 @@ impl Handler { inner.deduplicated_warn_count = 0; // actually free the underlying memory (which `clear` would not do) - inner.delayed_span_bugs = Default::default(); - inner.delayed_good_path_bugs = Default::default(); + inner.span_delayed_bugs = Default::default(); + inner.good_path_delayed_bugs = Default::default(); inner.taught_diagnostics = Default::default(); inner.emitted_diagnostic_codes = Default::default(); inner.emitted_diagnostics = Default::default(); @@ -675,14 +675,13 @@ impl Handler { /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key. /// Retrieve a stashed diagnostic with `steal_diagnostic`. pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) { - let mut inner = self.inner.borrow_mut(); - inner.stash((span.with_parent(None), key), diag); + self.inner.borrow_mut().stash((span.with_parent(None), key), diag); } /// Steal a previously stashed diagnostic with the given `Span` and [`StashKey`] as the key. pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> { - let mut inner = self.inner.borrow_mut(); - inner + self.inner + .borrow_mut() .steal((span.with_parent(None), key)) .map(|diag| DiagnosticBuilder::new_diagnostic(self, diag)) } @@ -927,10 +926,7 @@ impl Handler { /// Construct a builder at the `Note` level with the `msg`. #[rustc_lint_diagnostics] #[track_caller] - pub fn struct_note_without_error( - &self, - msg: impl Into<DiagnosticMessage>, - ) -> DiagnosticBuilder<'_, ()> { + pub fn struct_note(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Note, msg) } @@ -970,11 +966,12 @@ impl Handler { span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>, code: DiagnosticId, - ) { + ) -> ErrorGuaranteed { self.emit_diag_at_span( Diagnostic::new_with_code(Error { lint: false }, Some(code), msg), span, - ); + ) + .unwrap() } #[rustc_lint_diagnostics] @@ -998,20 +995,20 @@ impl Handler { self.inner.borrow_mut().span_bug(span, msg) } - /// For documentation on this, see `Session::delay_span_bug`. + /// For documentation on this, see `Session::span_delayed_bug`. #[track_caller] - pub fn delay_span_bug( + pub fn span_delayed_bug( &self, span: impl Into<MultiSpan>, msg: impl Into<String>, ) -> ErrorGuaranteed { - self.inner.borrow_mut().delay_span_bug(span, msg) + self.inner.borrow_mut().span_delayed_bug(span, msg) } // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). - pub fn delay_good_path_bug(&self, msg: impl Into<DiagnosticMessage>) { - self.inner.borrow_mut().delay_good_path_bug(msg) + pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) { + self.inner.borrow_mut().good_path_delayed_bug(msg) } #[track_caller] @@ -1021,17 +1018,13 @@ impl Handler { #[track_caller] #[rustc_lint_diagnostics] - pub fn span_note_without_error( - &self, - span: impl Into<MultiSpan>, - msg: impl Into<DiagnosticMessage>, - ) { + pub fn span_note(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) { self.emit_diag_at_span(Diagnostic::new(Note, msg), span); } #[track_caller] #[rustc_lint_diagnostics] - pub fn span_note_diag( + pub fn struct_span_note( &self, span: Span, msg: impl Into<DiagnosticMessage>, @@ -1054,12 +1047,11 @@ impl Handler { #[rustc_lint_diagnostics] pub fn warn(&self, msg: impl Into<DiagnosticMessage>) { - let mut db = DiagnosticBuilder::new(self, Warning(None), msg); - db.emit(); + DiagnosticBuilder::new(self, Warning(None), msg).emit(); } #[rustc_lint_diagnostics] - pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) { + pub fn note(&self, msg: impl Into<DiagnosticMessage>) { DiagnosticBuilder::new(self, Note, msg).emit(); } @@ -1085,8 +1077,8 @@ impl Handler { ErrorGuaranteed::unchecked_claim_error_was_emitted() }) } - pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> { - self.inner.borrow().has_errors_or_delayed_span_bugs().then(|| { + pub fn has_errors_or_span_delayed_bugs(&self) -> Option<ErrorGuaranteed> { + self.inner.borrow().has_errors_or_span_delayed_bugs().then(|| { #[allow(deprecated)] ErrorGuaranteed::unchecked_claim_error_was_emitted() }) @@ -1204,8 +1196,7 @@ impl Handler { mut diag: Diagnostic, sp: impl Into<MultiSpan>, ) -> Option<ErrorGuaranteed> { - let mut inner = self.inner.borrow_mut(); - inner.emit_diagnostic(diag.set_span(sp)) + self.inner.borrow_mut().emit_diagnostic(diag.set_span(sp)) } pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { @@ -1273,9 +1264,9 @@ impl Handler { } pub fn flush_delayed(&self) { - let mut inner = self.inner.lock(); - let bugs = std::mem::replace(&mut inner.delayed_span_bugs, Vec::new()); - inner.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued"); + let mut inner = self.inner.borrow_mut(); + let bugs = std::mem::replace(&mut inner.span_delayed_bugs, Vec::new()); + inner.flush_delayed(bugs, "no errors encountered even though `span_delayed_bug` issued"); } } @@ -1332,11 +1323,11 @@ impl HandlerInner { if diagnostic.level == Level::DelayedBug { // FIXME(eddyb) this should check for `has_errors` and stop pushing - // once *any* errors were emitted (and truncate `delayed_span_bugs` + // once *any* errors were emitted (and truncate `span_delayed_bugs` // when an error is first emitted, also), but maybe there's a case // in which that's not sound? otherwise this is really inefficient. let backtrace = std::backtrace::Backtrace::capture(); - self.delayed_span_bugs + self.span_delayed_bugs .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace)); if !self.flags.report_delayed_bugs { @@ -1451,7 +1442,7 @@ impl HandlerInner { } fn delayed_bug_count(&self) -> usize { - self.delayed_span_bugs.len() + self.delayed_good_path_bugs.len() + self.span_delayed_bugs.len() + self.good_path_delayed_bugs.len() } fn print_error_count(&mut self, registry: &Registry) { @@ -1502,18 +1493,18 @@ impl HandlerInner { error_codes.sort(); if error_codes.len() > 1 { let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; - self.failure(format!( + self.failure_note(format!( "Some errors have detailed explanations: {}{}", error_codes[..limit].join(", "), if error_codes.len() > 9 { "..." } else { "." } )); - self.failure(format!( + self.failure_note(format!( "For more information about an error, try \ `rustc --explain {}`.", &error_codes[0] )); } else { - self.failure(format!( + self.failure_note(format!( "For more information about this error, try \ `rustc --explain {}`.", &error_codes[0] @@ -1572,15 +1563,15 @@ impl HandlerInner { fn has_errors_or_lint_errors(&self) -> bool { self.has_errors() || self.lint_err_count > 0 } - fn has_errors_or_delayed_span_bugs(&self) -> bool { - self.has_errors() || !self.delayed_span_bugs.is_empty() + fn has_errors_or_span_delayed_bugs(&self) -> bool { + self.has_errors() || !self.span_delayed_bugs.is_empty() } fn has_any_message(&self) -> bool { self.err_count() > 0 || self.lint_err_count > 0 || self.warn_count > 0 } fn is_compilation_going_to_fail(&self) -> bool { - self.has_errors() || self.lint_err_count > 0 || !self.delayed_span_bugs.is_empty() + self.has_errors() || self.lint_err_count > 0 || !self.span_delayed_bugs.is_empty() } fn abort_if_errors(&mut self) { @@ -1601,14 +1592,17 @@ impl HandlerInner { self.emit_diagnostic(diag.set_span(sp)); } - /// For documentation on this, see `Session::delay_span_bug`. + /// For documentation on this, see `Session::span_delayed_bug`. + /// + /// Note: this function used to be called `delay_span_bug`. It was renamed + /// to match similar functions like `span_bug`, `span_err`, etc. #[track_caller] - fn delay_span_bug( + fn span_delayed_bug( &mut self, sp: impl Into<MultiSpan>, msg: impl Into<String>, ) -> ErrorGuaranteed { - // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before + // This is technically `self.treat_err_as_bug()` but `span_delayed_bug` is called before // incrementing `err_count` by one, so we need to +1 the comparing. // FIXME: Would be nice to increment err_count in a more coherent way. if self.flags.treat_err_as_bug.is_some_and(|c| { @@ -1624,16 +1618,16 @@ impl HandlerInner { // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). - fn delay_good_path_bug(&mut self, msg: impl Into<DiagnosticMessage>) { + fn good_path_delayed_bug(&mut self, msg: impl Into<DiagnosticMessage>) { let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); if self.flags.report_delayed_bugs { self.emit_diagnostic(&mut diagnostic); } let backtrace = std::backtrace::Backtrace::capture(); - self.delayed_good_path_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace)); + self.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace)); } - fn failure(&mut self, msg: impl Into<DiagnosticMessage>) { + fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) { self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg)); } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 88e90a3b3d1..91f3ca1d115 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1119,7 +1119,7 @@ impl<'a> ExtCtxt<'a> { sp: S, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - self.sess.parse_sess.span_diagnostic.struct_span_err(sp, msg) + self.sess.diagnostic().struct_span_err(sp, msg) } #[track_caller] @@ -1143,15 +1143,15 @@ impl<'a> ExtCtxt<'a> { #[rustc_lint_diagnostics] #[track_caller] pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) { - self.sess.parse_sess.span_diagnostic.span_err(sp, msg); + self.sess.diagnostic().span_err(sp, msg); } #[rustc_lint_diagnostics] #[track_caller] pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) { - self.sess.parse_sess.span_diagnostic.span_warn(sp, msg); + self.sess.diagnostic().span_warn(sp, msg); } pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<String>) -> ! { - self.sess.parse_sess.span_diagnostic.span_bug(sp, msg); + self.sess.diagnostic().span_bug(sp, msg); } pub fn trace_macros_diag(&mut self) { for (span, notes) in self.expansions.iter() { @@ -1165,7 +1165,7 @@ impl<'a> ExtCtxt<'a> { self.expansions.clear(); } pub fn bug(&self, msg: &'static str) -> ! { - self.sess.parse_sess.span_diagnostic.bug(msg); + self.sess.diagnostic().bug(msg); } pub fn trace_macros(&self) -> bool { self.ecfg.trace_mac @@ -1286,9 +1286,8 @@ pub fn expr_to_string( /// Non-fatally assert that `tts` is empty. Note that this function /// returns even when `tts` is non-empty, macros that *need* to stop -/// compilation should call -/// `cx.parse_sess.span_diagnostic.abort_if_errors()` (this should be -/// done as rarely as possible). +/// compilation should call `cx.diagnostic().abort_if_errors()` +/// (this should be done as rarely as possible). pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) { if !tts.is_empty() { cx.emit_err(errors::TakesNoArguments { span, name }); diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 1b51d80fb38..ad21a73f063 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -435,7 +435,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { invocations = mem::take(&mut undetermined_invocations); force = !mem::replace(&mut progress, false); if force && self.monotonic { - self.cx.sess.delay_span_bug( + self.cx.sess.span_delayed_bug( invocations.last().unwrap().0.span(), "expansion entered force mode without producing any errors", ); diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 64cf9ced9c1..8f80e6e2927 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -34,7 +34,7 @@ pub(super) fn failed_to_match_macro<'cx>( if try_success_result.is_ok() { // Nonterminal parser recovery might turn failed matches into successful ones, // but for that it must have emitted an error already - tracker.cx.sess.delay_span_bug(sp, "Macro matching returned a success on the second try"); + tracker.cx.sess.span_delayed_bug(sp, "Macro matching returned a success on the second try"); } if let Some(result) = tracker.result { @@ -151,7 +151,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, Success(_) => { // Nonterminal parser recovery might turn failed matches into successful ones, // but for that it must have emitted an error already - self.cx.sess.delay_span_bug( + self.cx.sess.span_delayed_bug( self.root_span, "should not collect detailed info for successful macro match", ); diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index bc3f0ce5a70..19734394382 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -475,17 +475,14 @@ pub fn compile_declarative_macro( let s = parse_failure_msg(&token); let sp = token.span.substitute_dummy(def.span); - let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, s); + let mut err = sess.diagnostic().struct_span_err(sp, s); err.span_label(sp, msg); annotate_doc_comment(&mut err, sess.source_map(), sp); err.emit(); return dummy_syn_ext(); } Error(sp, msg) => { - sess.parse_sess - .span_diagnostic - .struct_span_err(sp.substitute_dummy(def.span), msg) - .emit(); + sess.diagnostic().struct_span_err(sp.substitute_dummy(def.span), msg).emit(); return dummy_syn_ext(); } ErrorReported(_) => { @@ -514,10 +511,10 @@ pub fn compile_declarative_macro( valid &= check_lhs_nt_follows(&sess.parse_sess, def, &tt); return tt; } - sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs") + sess.diagnostic().span_bug(def.span, "wrong-structured lhs") }) .collect::<Vec<mbe::TokenTree>>(), - _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"), + _ => sess.diagnostic().span_bug(def.span, "wrong-structured lhs"), }; let rhses = match &argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] { @@ -536,10 +533,10 @@ pub fn compile_declarative_macro( .pop() .unwrap(); } - sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs") + sess.diagnostic().span_bug(def.span, "wrong-structured rhs") }) .collect::<Vec<mbe::TokenTree>>(), - _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"), + _ => sess.diagnostic().span_bug(def.span, "wrong-structured rhs"), }; for rhs in &rhses { @@ -595,7 +592,7 @@ pub fn compile_declarative_macro( mbe::TokenTree::Delimited(_, delimited) => { mbe::macro_parser::compute_locs(&delimited.tts) } - _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "malformed macro lhs"), + _ => sess.diagnostic().span_bug(def.span, "malformed macro lhs"), } }) .collect() @@ -648,10 +645,8 @@ fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool iter.next(); } let span = t.span.to(now.span); - sess.span_diagnostic.span_note_without_error( - span, - "doc comments are ignored in matcher position", - ); + sess.span_diagnostic + .span_note(span, "doc comments are ignored in matcher position"); } mbe::TokenTree::Sequence(_, sub_seq) if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 6c6dfe53305..6a99412fc5b 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -357,7 +357,7 @@ fn parse_sep_and_kleene_op<'a>( fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &ParseSess, token: &Token) { sess.span_diagnostic .span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token))); - sess.span_diagnostic.span_note_without_error( + sess.span_diagnostic.span_note( token.span, "`$$` and meta-variable expressions are not allowed inside macro parameter definitions", ); diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 39a16259fa6..d08026b9c14 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -156,7 +156,7 @@ impl MultiItemModifier for DeriveProcMacro { } }; - let error_count_before = ecx.sess.parse_sess.span_diagnostic.err_count(); + let error_count_before = ecx.sess.diagnostic().err_count(); let mut parser = rustc_parse::stream_to_parser(&ecx.sess.parse_sess, stream, Some("proc-macro derive")); let mut items = vec![]; @@ -179,7 +179,7 @@ impl MultiItemModifier for DeriveProcMacro { } // fail if there have been errors emitted - if ecx.sess.parse_sess.span_diagnostic.err_count() > error_count_before { + if ecx.sess.diagnostic().err_count() > error_count_before { ecx.sess.emit_err(errors::ProcMacroDeriveTokens { span }); } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 37ef4d86989..94e79144593 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -77,6 +77,8 @@ declare_features! ( (accepted, bindings_after_at, "1.56.0", Some(65490), None), /// Allows empty structs and enum variants with braces. (accepted, braced_empty_structs, "1.8.0", Some(29720), None), + /// Allows `c"foo"` literals. + (accepted, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None), /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`. (accepted, cfg_attr_multi, "1.33.0", Some(54881), None), /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 214de3ca402..9754f7acaae 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -813,7 +813,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing), rustc_attr!( TEST, rustc_error, Normal, - template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly + template!(Word, List: "span_delayed_bug_from_inside_query"), WarnFollowingWordOnly ), rustc_attr!(TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8182c8779ff..dee68bff21d 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -354,8 +354,6 @@ declare_features! ( (unstable, async_fn_track_caller, "1.73.0", Some(110011), None), /// Allows builtin # foo() syntax (unstable, builtin_syntax, "1.71.0", Some(110680), None), - /// Allows `c"foo"` literals. - (unstable, c_str_literals, "1.71.0", Some(105723), None), /// Treat `extern "C"` function as nounwind. (unstable, c_unwind, "1.52.0", Some(74990), None), /// Allows using C-variadics. @@ -500,6 +498,9 @@ declare_features! ( (incomplete, lazy_type_alias, "1.72.0", Some(112792), None), /// Allows `if/while p && let q = r && ...` chains. (unstable, let_chains, "1.37.0", Some(53667), None), + /// Allows using `#[link(kind = "link-arg", name = "...")]` + /// to pass custom arguments to the linker. + (unstable, link_arg_attribute, "CURRENT_RUSTC_VERSION", Some(99427), None), /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. (unstable, lint_reasons, "1.31.0", Some(54503), None), /// Give access to additional metadata about declarative macro meta-variables. diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index b9a4806e6c2..fd3e6bd44e7 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -720,9 +720,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // since we should have emitten an error for them earlier, and they will // not be well-formed! if polarity == ty::ImplPolarity::Negative { - self.tcx() - .sess - .delay_span_bug(binding.span, "negative trait bounds should not have bindings"); + self.tcx().sess.span_delayed_bug( + binding.span, + "negative trait bounds should not have bindings", + ); continue; } @@ -1419,7 +1420,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // trait reference. let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else { // A cycle error occurred, most likely. - let guar = tcx.sess.delay_span_bug(span, "expected cycle error"); + let guar = tcx.sess.span_delayed_bug(span, "expected cycle error"); return Err(guar); }; @@ -2376,7 +2377,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let e = self .tcx() .sess - .delay_span_bug(path.span, "path with `Res::Err` but no error emitted"); + .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted"); self.set_tainted_by_errors(e); Ty::new_error(self.tcx(), e) } diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index 78c5809f8b4..6cb38c741b7 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -325,7 +325,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { false }); if references_self { - let guar = tcx.sess.delay_span_bug( + let guar = tcx.sess.span_delayed_bug( span, "trait object projection bounds reference `Self`", ); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index fbed6f33e59..56e272b14bd 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -130,7 +130,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b for field in &def.non_enum_variant().fields { let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args)) else { - tcx.sess.delay_span_bug(span, "could not normalize field type"); + tcx.sess.span_delayed_bug(span, "could not normalize field type"); continue; }; @@ -151,7 +151,8 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b return false; } else if field_ty.needs_drop(tcx, param_env) { // This should never happen. But we can get here e.g. in case of name resolution errors. - tcx.sess.delay_span_bug(span, "we should never accept maybe-dropping union fields"); + tcx.sess + .span_delayed_bug(span, "we should never accept maybe-dropping union fields"); } } } else { @@ -181,7 +182,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { } // Generic statics are rejected, but we still reach this case. Err(e) => { - tcx.sess.delay_span_bug(span, format!("{e:?}")); + tcx.sess.span_delayed_bug(span, format!("{e:?}")); return; } }; @@ -204,7 +205,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) { let item = tcx.hir().item(id); let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else { - tcx.sess.delay_span_bug(item.span, "expected opaque item"); + tcx.sess.span_delayed_bug(item.span, "expected opaque item"); return; }; @@ -313,7 +314,7 @@ fn check_opaque_meets_bounds<'tcx>( Ok(()) => {} Err(ty_err) => { let ty_err = ty_err.to_string(tcx); - return Err(tcx.sess.delay_span_bug( + return Err(tcx.sess.span_delayed_bug( span, format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"), )); @@ -655,7 +656,7 @@ pub(super) fn check_specialization_validity<'tcx>( if !tcx.is_impl_trait_in_trait(impl_item) { report_forbidden_specialization(tcx, impl_item, parent_impl); } else { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( DUMMY_SP, format!("parent item: {parent_impl:?} not marked as default"), ); @@ -703,7 +704,7 @@ fn check_impl_items_against_trait<'tcx>( tcx.associated_item(trait_item_id) } else { // Checked in `associated_item`. - tcx.sess.delay_span_bug(tcx.def_span(impl_item), "missing associated item in trait"); + tcx.sess.span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait"); continue; }; match ty_impl_item.kind { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 16fd1a951b5..1412fd1a987 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -439,7 +439,7 @@ fn compare_method_predicate_entailment<'tcx>( } return Err(tcx .sess - .delay_span_bug(rustc_span::DUMMY_SP, "error should have been emitted")); + .span_delayed_bug(rustc_span::DUMMY_SP, "error should have been emitted")); } } } @@ -937,7 +937,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( remapped_types.insert(def_id, ty::EarlyBinder::bind(ty)); } Err(err) => { - let reported = tcx.sess.delay_span_bug( + let reported = tcx.sess.span_delayed_bug( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); @@ -1114,7 +1114,9 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> { .note(format!("hidden type inferred to be `{}`", self.ty)) .emit() } - _ => self.tcx.sess.delay_span_bug(DUMMY_SP, "should've been able to remap region"), + _ => { + self.tcx.sess.span_delayed_bug(DUMMY_SP, "should've been able to remap region") + } }; return Err(guar); }; @@ -1473,7 +1475,7 @@ fn compare_number_of_generics<'tcx>( // inheriting the generics from will also have mismatched arguments, and // we'll report an error for that instead. Delay a bug for safety, though. if trait_.is_impl_trait_in_trait() { - return Err(tcx.sess.delay_span_bug( + return Err(tcx.sess.span_delayed_bug( rustc_span::DUMMY_SP, "errors comparing numbers of generics of trait/impl functions were not emitted", )); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index bcd317f78ef..86c38480d57 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -153,7 +153,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( trait_m_sig.inputs_and_output, )); if !ocx.select_all_or_error().is_empty() { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( DUMMY_SP, "encountered errors when checking RPITIT refinement (selection)", ); @@ -165,7 +165,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( ); let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( DUMMY_SP, "encountered errors when checking RPITIT refinement (regions)", ); @@ -173,7 +173,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( } // Resolve any lifetime variables that may have been introduced during normalization. let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( DUMMY_SP, "encountered errors when checking RPITIT refinement (resolution)", ); diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 0a05c1039b6..58c77bb45cb 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -66,7 +66,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro // already checked by coherence, but compilation may // not have been terminated. let span = tcx.def_span(drop_impl_did); - let reported = tcx.sess.delay_span_bug( + let reported = tcx.sess.span_delayed_bug( span, format!("should have been rejected by coherence check: {dtor_self_type}"), ); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index ba627c740df..2428fe6ae79 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -281,7 +281,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) { let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id()); let Some(asm_arch) = self.tcx.sess.asm_arch else { - self.tcx.sess.delay_span_bug(DUMMY_SP, "target architecture does not support asm"); + self.tcx.sess.span_delayed_bug(DUMMY_SP, "target architecture does not support asm"); return; }; for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 177e4611cc9..92619ae417b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -118,10 +118,10 @@ where if tcx.sess.err_count() > 0 { return Err(err); } else { - // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs causes an - // error (delay_span_bug) during normalization, without reporting an error, so we need to act as if - // no error happened, in order to let our callers continue and report an error later in - // check_impl_items_against_trait. + // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs + // causes an error (span_delayed_bug) during normalization, without reporting an error, + // so we need to act as if no error happened, in order to let our callers continue and + // report an error later in check_impl_items_against_trait. return Ok(()); } } @@ -1040,7 +1040,7 @@ fn check_type_defn<'tcx>( let ty = tcx.erase_regions(ty); if ty.has_infer() { tcx.sess - .delay_span_bug(item.span, format!("inference variables in {ty:?}")); + .span_delayed_bug(item.span, format!("inference variables in {ty:?}")); // Just treat unresolved type expression as if it needs drop. true } else { @@ -1812,8 +1812,10 @@ fn check_variances_for_type_defn<'tcx>( // // if they aren't in the same order, then the user has written invalid code, and already // got an error about it (or I'm wrong about this) - tcx.sess - .delay_span_bug(hir_param.span, "hir generics and ty generics in different order"); + tcx.sess.span_delayed_bug( + hir_param.span, + "hir generics and ty generics in different order", + ); continue; } diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 46f77780a52..45100457629 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -453,7 +453,7 @@ fn lint_auto_trait_impl<'tcx>( impl_def_id: LocalDefId, ) { if trait_ref.args.len() != 1 { - tcx.sess.diagnostic().delay_span_bug( + tcx.sess.diagnostic().span_delayed_bug( tcx.def_span(impl_def_id), "auto traits cannot have generic parameters", ); diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 6b18b0ebe9d..42e2818b63f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -82,7 +82,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => { // Reported in AST validation - tcx.sess.delay_span_bug(item.span, "unsafe negative impl"); + tcx.sess.span_delayed_bug(item.span, "unsafe negative impl"); } (_, _, Unsafety::Normal, hir::ImplPolarity::Negative(_)) | (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive) diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index e49bd0917a8..c6ea853b9ba 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -335,7 +335,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // though this may happen when we call `poly_trait_ref_binder_info` with // an (erroneous, #113423) associated return type bound in an impl header. if !supertrait_bound_vars.is_empty() { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( DUMMY_SP, format!( "found supertrait lifetimes without a binder to append \ @@ -1363,7 +1363,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( lifetime_ref.ident.span, format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,), ); @@ -1493,7 +1493,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( self.tcx.hir().span(hir_id), format!("could not resolve {param_def_id:?}"), ); @@ -1724,7 +1724,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } else { self.tcx .sess - .delay_span_bug(binding.ident.span, "bad return type notation here"); + .span_delayed_bug(binding.ident.span, "bad return type notation here"); vec![] }; self.with(scope, |this| { @@ -2057,7 +2057,7 @@ fn is_late_bound_map( Some(true) => Some(arg), Some(false) => None, None => { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( *span, format!( "Incorrect generic arg count for alias {alias_def:?}" diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index f22b836b42b..4ed1377e7fc 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -29,7 +29,7 @@ fn diagnostic_hir_wf_check<'tcx>( // HIR wfcheck should only ever happen as part of improving an existing error tcx.sess - .delay_span_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!"); + .span_delayed_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!"); let icx = ItemCtxt::new(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 788121f7a30..fff4a919e91 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -74,7 +74,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) if impl_self_ty.references_error() { // Don't complain about unconstrained type params when self ty isn't known due to errors. // (#36836) - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( tcx.def_span(impl_def_id), format!( "potentially unconstrained type parameters weren't evaluated: {impl_self_ty:?}", diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 1c3ac297457..91cdffbbe4f 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -209,8 +209,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module)) }); - // HACK: `check_mod_type_wf` may spuriously emit errors due to `delay_span_bug`, even if those errors - // only actually get emitted in `check_mod_item_types`. + // HACK: `check_mod_type_wf` may spuriously emit errors due to `span_delayed_bug`, even if + // those errors only actually get emitted in `check_mod_item_types`. errs?; if tcx.features().rustc_attrs { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index d3abe0d7e1a..a907acba0e0 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -244,7 +244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { // Check for `self` receiver on the method, otherwise we can't use this as a `Fn*` trait. if !self.tcx.associated_item(ok.value.def_id).fn_has_self_parameter { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( call_expr.span, "input to overloaded call fn is not a self receiver", ); @@ -259,9 +259,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else { // The `fn`/`fn_mut` lang item is ill-formed, which should have // caused an error elsewhere. - self.tcx - .sess - .delay_span_bug(call_expr.span, "input to call/call_mut is not a ref"); + self.tcx.sess.span_delayed_bug( + call_expr.span, + "input to call/call_mut is not a ref", + ); return None; }; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 00af6d46213..d89af297560 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -142,7 +142,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let reported = self .tcx .sess - .delay_span_bug(span, format!("`{t:?}` should be sized but is not?")); + .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?")); return Err(reported); } }) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 587038d57bd..f39d795f0ed 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1549,7 +1549,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // any superfluous errors we might encounter while trying to // emit or provide suggestions on how to fix the initial error. fcx.set_tainted_by_errors( - fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"), + fcx.tcx + .sess + .span_delayed_bug(cause.span, "coercion error but no error emitted"), ); let (expected, found) = if label_expression_as_expected { // In the case where this is a "forced unit", like diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 33d14476b2c..8f633834885 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -256,7 +256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.adjust_expr_for_assert_eq_macro(&mut expr, &mut expected_ty_expr); - self.set_tainted_by_errors(self.tcx.sess.delay_span_bug( + self.set_tainted_by_errors(self.tcx.sess.span_delayed_bug( expr.span, "`TypeError` when attempting coercion but no error emitted", )); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index ed5ac2cea38..7c157c0eae0 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // coercions from ! to `expected`. if ty.is_never() { if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) { - let reported = self.tcx().sess.delay_span_bug( + let reported = self.tcx().sess.span_delayed_bug( expr.span, "expression with never type wound up being adjusted", ); @@ -514,7 +514,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Res::Err => { self.suggest_assoc_method_call(segs); let e = - self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); + self.tcx.sess.span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); Ty::new_error(tcx, e) } @@ -623,7 +623,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Set expectation to error in that case and set tainted // by error (#114529) let coerce_to = opt_coerce_to.unwrap_or_else(|| { - let guar = tcx.sess.delay_span_bug( + let guar = tcx.sess.span_delayed_bug( expr.span, "illegal break with value found but no error reported", ); @@ -1292,7 +1292,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // permit break with a value [1]. if ctxt.coerce.is_none() && !ctxt.may_break { // [1] - self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break"); + self.tcx.sess.span_delayed_bug(body.span, "no coercion, but loop may not break"); } ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| Ty::new_unit(self.tcx)) } @@ -2090,7 +2090,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [] => unreachable!(), }; err.note(format!( - "... and other private field{s} {names}that {were} not provided", + "{}private field{s} {names}that {were} not provided", + if used_fields.is_empty() { "" } else { "...and other " }, s = pluralize!(remaining_private_fields_len), were = pluralize!("was", remaining_private_fields_len), )); @@ -2186,7 +2187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let guar = self .tcx .sess - .delay_span_bug(expr.span, "parser recovered but no error was emitted"); + .span_delayed_bug(expr.span, "parser recovered but no error was emitted"); self.set_tainted_by_errors(guar); return guar; } @@ -2402,7 +2403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let guar = if field.name == kw::Empty { - self.tcx.sess.delay_span_bug(field.span, "field name with no name") + self.tcx.sess.span_delayed_bug(field.span, "field name with no name") } else if self.method_exists(field, base_ty, expr.hir_id, expected.only_has_type(self)) { self.ban_take_value_of_method(expr, base_ty, field) } else if !base_ty.is_primitive_ty() { diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 9991050d7b2..c22b15231a1 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -538,7 +538,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // The struct path probably didn't resolve if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() { - self.tcx().sess.delay_span_bug(field.span, "couldn't resolve index for field"); + self.tcx().sess.span_delayed_bug(field.span, "couldn't resolve index for field"); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 23b9ac4139d..e1a2a260df7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -277,7 +277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME: currently we never try to compose autoderefs // and ReifyFnPointer/UnsafeFnPointer, but we could. _ => { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( expr.span, format!( "while adjusting {:?}, can't compose {:?} and {:?}", @@ -866,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let guar = self .tcx .sess - .delay_span_bug(span, "method resolution should've emitted an error"); + .span_delayed_bug(span, "method resolution should've emitted an error"); let result = match error { method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)), _ => Err(guar), @@ -1440,7 +1440,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { Ok(ok) => self.register_infer_ok_obligations(ok), Err(_) => { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( span, format!( "instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index f1720dc98e6..509596c1e90 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -517,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; // FIXME: taint after emitting errors and pass through an `ErrorGuaranteed` self.set_tainted_by_errors( - tcx.sess.delay_span_bug(call_span, "no errors reported for args"), + tcx.sess.span_delayed_bug(call_span, "no errors reported for args"), ); // Get the argument span in the context of the call span so that @@ -1361,7 +1361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let variant = match def { Res::Err => { let guar = - self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"); + self.tcx.sess.span_delayed_bug(path_span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(guar); return Err(guar); } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 5d516eaf507..a3c77af62a7 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -48,7 +48,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let to = normalize(to); trace!(?from, ?to); if from.has_non_region_infer() || to.has_non_region_infer() { - tcx.sess.delay_span_bug(span, "argument to transmute has inference variables"); + tcx.sess.span_delayed_bug(span, "argument to transmute has inference variables"); return; } // Transmutes that are only changing lifetimes are always ok. diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index a22c95ac8ff..29e4fd9239a 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -420,20 +420,16 @@ fn fatally_break_rust(tcx: TyCtxt<'_>) { MultiSpan::new(), "It looks like you're trying to break rust; would you like some ICE?", ); - handler.note_without_error("the compiler expectedly panicked. this is a feature."); - handler.note_without_error( + handler.note("the compiler expectedly panicked. this is a feature."); + handler.note( "we would appreciate a joke overview: \ https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675", ); - handler.note_without_error(format!( - "rustc {} running on {}", - tcx.sess.cfg_version, - config::host_triple(), - )); + handler.note(format!("rustc {} running on {}", tcx.sess.cfg_version, config::host_triple(),)); if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() { - handler.note_without_error(format!("compiler flags: {}", flags.join(" "))); + handler.note(format!("compiler flags: {}", flags.join(" "))); if excluded_cargo_defaults { - handler.note_without_error("some of the compiler flags provided by cargo are hidden"); + handler.note("some of the compiler flags provided by cargo are hidden"); } } } diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 0bcb7c7b5d7..ebb15e072aa 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -540,7 +540,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { let ty::Adt(adt_def, _) = ty.kind() else { self.tcx() .sess - .delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT"); + .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT"); return Err(()); }; @@ -575,7 +575,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { _ => { self.tcx() .sess - .delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT"); + .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT"); Err(()) } } @@ -588,7 +588,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { match ty.kind() { ty::Tuple(args) => Ok(args.len()), _ => { - self.tcx().sess.delay_span_bug(span, "tuple pattern not applied to a tuple"); + self.tcx().sess.span_delayed_bug(span, "tuple pattern not applied to a tuple"); Err(()) } } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index d69d2529b18..f820835acef 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -385,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // type parameters or early-bound regions. let tcx = self.tcx; let Some(method_item) = self.associated_value(trait_def_id, m_name) else { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( obligation.cause.span, "operator trait does not have corresponding operator method", ); @@ -393,7 +393,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if method_item.kind != ty::AssocKind::Fn { - self.tcx.sess.delay_span_bug(tcx.def_span(method_item.def_id), "not a method"); + self.tcx.sess.span_delayed_bug(tcx.def_span(method_item.def_id), "not a method"); return None; } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 7d83f4a12b1..b980a7d1d28 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -802,7 +802,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let trait_ref = principal.with_self_ty(self.tcx, self_ty); self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| { if new_trait_ref.has_non_region_bound_vars() { - this.tcx.sess.delay_span_bug( + this.tcx.sess.span_delayed_bug( this.span, "tried to select method from HRTB with non-lifetime bound vars", ); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a7764f4ff96..858385246dd 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -813,7 +813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: item_span, .. })) => { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( *item_span, "auto trait is invoked with no method error, but no error reported?", ); diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index fcb3f8f47bd..1e9387ef041 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -900,7 +900,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { self.tcx .sess - .delay_span_bug(span, "operator didn't have the right number of generic args"); + .span_delayed_bug(span, "operator didn't have the right number of generic args"); return Err(vec![]); } @@ -933,7 +933,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This path may do some inference, so make sure we've really // doomed compilation so as to not accidentally stabilize new // inference or something here... - self.tcx.sess.delay_span_bug(span, "this path really should be doomed..."); + self.tcx.sess.span_delayed_bug(span, "this path really should be doomed..."); // Guide inference for the RHS expression if it's provided -- // this will allow us to better error reporting, at the expense // of making some error messages a bit more specific. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 1ecf553d71d..b63bb1e00cb 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -899,7 +899,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = path_resolution; match res { Res::Err => { - let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); + let e = tcx.sess.span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); return Ty::new_error(tcx, e); } @@ -1068,7 +1068,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None); if res == Res::Err { - let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted"); + let e = tcx.sess.span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); return Ty::new_error(tcx, e); @@ -1084,7 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let variant = match res { Res::Err => { - let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted"); + let e = tcx.sess.span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); return Ty::new_error(tcx, e); diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 3a0f46c3a8c..c0a5818b9e5 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -725,7 +725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( closure_span, format!( "two identical projections: ({:?}, {:?})", diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index fc635a8da2e..cc617fd2d0b 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -218,7 +218,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // When encountering `return [0][0]` outside of a `fn` body we can encounter a base // that isn't in the type table. We assume more relevant errors have already been // emitted, so we delay an ICE if none have. (#64638) - self.tcx().sess.delay_span_bug(e.span, format!("bad base: `{base:?}`")); + self.tcx().sess.span_delayed_bug(e.span, format!("bad base: `{base:?}`")); } if let Some(base_ty) = base_ty && let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() @@ -311,7 +311,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { // Nothing to write back here } hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => { - self.tcx().sess.delay_span_bug(p.span, format!("unexpected generic param: {p:?}")); + self.tcx() + .sess + .span_delayed_bug(p.span, format!("unexpected generic param: {p:?}")); } } } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 2d809030e58..92297a27a63 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -262,7 +262,7 @@ pub(crate) fn prepare_session_directory( directory." ); - sess.init_incr_comp_session(session_dir, directory_lock, false); + sess.init_incr_comp_session(session_dir, directory_lock); return Ok(()); }; @@ -276,7 +276,7 @@ pub(crate) fn prepare_session_directory( sess.emit_warning(errors::HardLinkFailed { path: &session_dir }); } - sess.init_incr_comp_session(session_dir, directory_lock, true); + sess.init_incr_comp_session(session_dir, directory_lock); return Ok(()); } else { debug!("copying failed - trying next directory"); @@ -312,7 +312,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) { let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone(); - if let Some(_) = sess.has_errors_or_delayed_span_bugs() { + if let Some(_) = sess.has_errors_or_span_delayed_bugs() { // If there have been any errors during compilation, we don't want to // publish this session directory. Rather, we'll just delete it. diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index d6320d680e7..ff0953e9f7b 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -32,7 +32,7 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) { return; } // This is going to be deleted in finalize_session_directory, so let's not create it - if let Some(_) = sess.has_errors_or_delayed_span_bugs() { + if let Some(_) = sess.has_errors_or_span_delayed_bugs() { return; } @@ -87,7 +87,7 @@ pub fn save_work_product_index( return; } // This is going to be deleted in finalize_session_directory, so let's not create it - if let Some(_) = sess.has_errors_or_delayed_span_bugs() { + if let Some(_) = sess.has_errors_or_span_delayed_bugs() { return; } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 6fbab0ef299..473a3965885 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -194,8 +194,8 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { // // rust-lang/rust#57464: `impl Trait` can leak local // scopes (in manner violating typeck). Therefore, use - // `delay_span_bug` to allow type error over an ICE. - canonicalizer.tcx.sess.delay_span_bug( + // `span_delayed_bug` to allow type error over an ICE. + canonicalizer.tcx.sess.span_delayed_bug( rustc_span::DUMMY_SP, format!("unexpected region in query response: `{r:?}`"), ); diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 2a9e20b9f8f..c3d07415bb8 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -175,7 +175,7 @@ impl<'tcx> InferCtxt<'tcx> { &mut OriginalQueryValues::default(), ); self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( DUMMY_SP, format!("cannot relate consts of different types (a={a:?}, b={b:?})",), ) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3be23796550..9cdf78484d4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -131,13 +131,13 @@ pub struct TypeErrCtxt<'a, 'tcx> { impl Drop for TypeErrCtxt<'_, '_> { fn drop(&mut self) { - if let Some(_) = self.infcx.tcx.sess.has_errors_or_delayed_span_bugs() { + if let Some(_) = self.infcx.tcx.sess.has_errors_or_span_delayed_bugs() { // ok, emitted an error. } else { self.infcx .tcx .sess - .delay_good_path_bug("used a `TypeErrCtxt` without raising an error or lint"); + .good_path_delayed_bug("used a `TypeErrCtxt` without raising an error or lint"); } } } @@ -517,7 +517,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.tcx .sess - .delay_span_bug(self.tcx.def_span(generic_param_scope), "expected region errors") + .span_delayed_bug(self.tcx.def_span(generic_param_scope), "expected region errors") } // This method goes through all the errors and try to group certain types diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 7dd19c8e15f..8fe6c1b0d86 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -374,7 +374,7 @@ impl<'tcx> InferCtxt<'tcx> { multi_suggestions, bad_label, } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), + .into_diagnostic(self.tcx.sess.diagnostic()), TypeAnnotationNeeded::E0283 => AmbiguousImpl { span, source_kind, @@ -384,7 +384,7 @@ impl<'tcx> InferCtxt<'tcx> { multi_suggestions, bad_label, } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), + .into_diagnostic(self.tcx.sess.diagnostic()), TypeAnnotationNeeded::E0284 => AmbiguousReturn { span, source_kind, @@ -394,7 +394,7 @@ impl<'tcx> InferCtxt<'tcx> { multi_suggestions, bad_label, } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), + .into_diagnostic(self.tcx.sess.diagnostic()), } } } @@ -581,7 +581,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { multi_suggestions, bad_label: None, } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), + .into_diagnostic(self.tcx.sess.diagnostic()), TypeAnnotationNeeded::E0283 => AmbiguousImpl { span, source_kind, @@ -591,7 +591,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { multi_suggestions, bad_label: None, } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), + .into_diagnostic(self.tcx.sess.diagnostic()), TypeAnnotationNeeded::E0284 => AmbiguousReturn { span, source_kind, @@ -601,7 +601,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { multi_suggestions, bad_label: None, } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), + .into_diagnostic(self.tcx.sess.diagnostic()), } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 781cc192ae5..fed76cd65cf 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -140,7 +140,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span, notes: reference_valid.into_iter().chain(content_valid).collect(), } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) + .into_diagnostic(self.tcx.sess.diagnostic()) } infer::RelateObjectBound(span) => { let object_valid = note_and_explain::RegionExplanation::new( @@ -161,7 +161,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span, notes: object_valid.into_iter().chain(pointer_valid).collect(), } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) + .into_diagnostic(self.tcx.sess.diagnostic()) } infer::RelateParamBound(span, ty, opt_span) => { let prefix = match *sub { @@ -177,7 +177,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.tcx, sub, opt_span, prefix, suffix, ); FulfillReqLifetime { span, ty: self.resolve_vars_if_possible(ty), note } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) + .into_diagnostic(self.tcx.sess.diagnostic()) } infer::RelateRegionParamBound(span) => { let param_instantiated = note_and_explain::RegionExplanation::new( @@ -198,7 +198,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span, notes: param_instantiated.into_iter().chain(param_must_outlive).collect(), } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) + .into_diagnostic(self.tcx.sess.diagnostic()) } infer::ReferenceOutlivesReferent(ty, span) => { let pointer_valid = note_and_explain::RegionExplanation::new( @@ -220,7 +220,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty: self.resolve_vars_if_possible(ty), notes: pointer_valid.into_iter().chain(data_valid).collect(), } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) + .into_diagnostic(self.tcx.sess.diagnostic()) } infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { let mut err = self.report_extra_impl_obligation( @@ -281,7 +281,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span, notes: instantiated.into_iter().chain(must_outlive).collect(), } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) + .into_diagnostic(self.tcx.sess.diagnostic()) } }; if sub.is_error() || sup.is_error() { diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index b0e82a92674..b6e86e2b676 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -798,7 +798,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Errors in earlier passes can yield error variables without // resolution errors here; delay ICE in favor of those errors. - self.tcx().sess.delay_span_bug( + self.tcx().sess.span_delayed_bug( self.var_infos[node_idx].origin.span(), format!( "collect_error_for_expanding_node() could not find \ diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bb16d97eb85..32c09e491c7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1433,7 +1433,7 @@ impl<'tcx> InferCtxt<'tcx> { let guar = self .tcx .sess - .delay_span_bug(DUMMY_SP, format!("`{value:?}` is not fully resolved")); + .span_delayed_bug(DUMMY_SP, format!("`{value:?}` is not fully resolved")); Ok(self.tcx.fold_regions(value, |re, _| { if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re } })) diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index ee6a3fd0c82..77c1d6a7313 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -494,7 +494,7 @@ where // shouldn't ever fail. Instead, it unconditionally emits an // alias-relate goal. assert!(!self.infcx.next_trait_solver()); - self.tcx().sess.delay_span_bug( + self.tcx().sess.span_delayed_bug( self.delegate.span(), "failure to relate an opaque to itself should result in an error later on", ); @@ -552,7 +552,7 @@ where match b.kind() { ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { // Forbid inference variables in the RHS. - self.infcx.tcx.sess.delay_span_bug( + self.infcx.tcx.sess.span_delayed_bug( self.delegate.span(), format!("unexpected inference var {b:?}",), ); diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index a737761ba22..715006a50d3 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -41,7 +41,7 @@ impl<'tcx> Drop for OpaqueTypeStorage<'tcx> { fn drop(&mut self) { if !self.opaque_types.is_empty() { ty::tls::with(|tcx| { - tcx.sess.delay_span_bug(DUMMY_SP, format!("{:?}", self.opaque_types)) + tcx.sess.span_delayed_bug(DUMMY_SP, format!("{:?}", self.opaque_types)) }); } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index c6cbde4dba9..395830d937b 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -254,7 +254,7 @@ where // ignore this, we presume it will yield an error // later, since if a type variable is not resolved by // this point it never will be - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( origin.span(), format!("unresolved inference variable in outlives: {v:?}"), ); diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 35a8fe6dc47..ce619ae8a0d 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -180,7 +180,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // ignore this, we presume it will yield an error // later, since if a type variable is not resolved by // this point it never will be - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( rustc_span::DUMMY_SP, format!("unresolved inference variable in outlives: {v:?}"), ); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 88212d164bc..fab8a18f2dc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -519,9 +519,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P match result { Ok(_) => { if sess.opts.json_artifact_notifications { - sess.parse_sess - .span_diagnostic - .emit_artifact_notification(deps_filename, "dep-info"); + sess.diagnostic().emit_artifact_notification(deps_filename, "dep-info"); } } Err(error) => { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index e81c3f42a16..e9611c74a68 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -194,16 +194,16 @@ impl<'tcx> Queries<'tcx> { let Some((def_id, _)) = tcx.entry_fn(()) else { return }; for attr in tcx.get_attrs(def_id, sym::rustc_error) { match attr.meta_item_list() { - // Check if there is a `#[rustc_error(delay_span_bug_from_inside_query)]`. + // Check if there is a `#[rustc_error(span_delayed_bug_from_inside_query)]`. Some(list) if list.iter().any(|list_item| { matches!( list_item.ident().map(|i| i.name), - Some(sym::delay_span_bug_from_inside_query) + Some(sym::span_delayed_bug_from_inside_query) ) }) => { - tcx.ensure().trigger_delay_span_bug(def_id); + tcx.ensure().trigger_span_delayed_bug(def_id); } // Bare `#[rustc_error]`. diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 9bc9f88d3f7..024e542d4af 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -926,6 +926,10 @@ pub trait LintContext { if elided { "'static " } else { "'static" }, Applicability::MachineApplicable ); + }, + BuiltinLintDiagnostics::RedundantImportVisibility { max_vis, span } => { + db.span_note(span, format!("the most public imported item is `{max_vis}`")); + db.help("reduce the glob import's visibility or increase visibility of imported items"); } } // Rewrap `db`, and pass control to the user. diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 36aa959ddc9..4cccaeeca84 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -430,7 +430,7 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>( // that was not lint-checked (perhaps it doesn't exist?). This is a bug. for (id, lints) in cx.context.buffered.map { for early_lint in lints { - sess.delay_span_bug( + sess.span_delayed_bug( early_lint.span, format!( "failed to process buffered lint here (dummy = {})", diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 878c1a65dbf..de0abe04611 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -583,6 +583,10 @@ pub enum BuiltinLintDiagnostics { elided: bool, span: Span, }, + RedundantImportVisibility { + span: Span, + max_vis: String, + }, } /// Lints that are buffered up early on in the `Session` before the diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 7f033265136..0edcac93b62 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -525,12 +525,9 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) { // Unfortunately, the LLVM C API doesn't provide a way to create the // TargetLibraryInfo pass, so we use this method to do so. -extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M, - bool DisableSimplifyLibCalls) { +extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M) { Triple TargetTriple(unwrap(M)->getTargetTriple()); TargetLibraryInfoImpl TLII(TargetTriple); - if (DisableSimplifyLibCalls) - TLII.disableAllFunctions(); unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII)); } @@ -697,7 +694,7 @@ LLVMRustOptimize( bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, - bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, + bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, const char *InstrProfileOutput, @@ -795,8 +792,6 @@ LLVMRustOptimize( Triple TargetTriple(TheModule->getTargetTriple()); std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple)); - if (DisableSimplifyLibCalls) - TLII->disableAllFunctions(); FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); PB.registerModuleAnalyses(MAM); diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 44b235a6d3d..8da6f0007f0 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -269,7 +269,7 @@ metadata_unknown_import_name_type = unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated metadata_unknown_link_kind = - unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib + unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib, link-arg .label = unknown link kind metadata_unknown_link_modifier = diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 169b56d40fa..301e3f2620d 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -7,8 +7,9 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob use rustc_ast::expand::allocator::{alloc_error_handler_name, global_fn_name, AllocatorKind}; use rustc_ast::{self as ast, *}; use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::owned_slice::OwnedSlice; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard}; +use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard}; use rustc_expand::base::SyntaxExtension; use rustc_fs_util::try_canonicalize; use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE}; @@ -16,16 +17,14 @@ use rustc_hir::definitions::Definitions; use rustc_index::IndexVec; use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType, ExternLocation}; -use rustc_session::cstore::{ - CrateDepKind, CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn, -}; +use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; use rustc_session::lint; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; use rustc_span::edition::Edition; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::spec::{PanicStrategy, TargetTriple}; +use rustc_target::spec::{PanicStrategy, Target, TargetTriple}; use proc_macro::bridge::client::ProcMacro; use std::error::Error; @@ -34,6 +33,17 @@ use std::path::Path; use std::time::Duration; use std::{cmp, iter}; +/// The backend's way to give the crate store access to the metadata in a library. +/// Note that it returns the raw metadata bytes stored in the library file, whether +/// it is compressed, uncompressed, some weird mix, etc. +/// rmeta files are backend independent and not handled here. +pub trait MetadataLoader { + fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>; + fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>; +} + +pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync; + pub struct CStore { metadata_loader: Box<MetadataLoaderDyn>, @@ -257,7 +267,7 @@ impl CStore { let unused_externs = self.unused_externs.iter().map(|ident| ident.to_ident_string()).collect::<Vec<_>>(); let unused_externs = unused_externs.iter().map(String::as_str).collect::<Vec<&str>>(); - tcx.sess.parse_sess.span_diagnostic.emit_unused_externs( + tcx.sess.diagnostic().emit_unused_externs( level, json_unused_externs.is_loud(), &unused_externs, diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs index 4b451253f2b..c95ef01faa7 100644 --- a/compiler/rustc_metadata/src/fs.rs +++ b/compiler/rustc_metadata/src/fs.rs @@ -91,10 +91,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) { } }; if tcx.sess.opts.json_artifact_notifications { - tcx.sess - .parse_sess - .span_diagnostic - .emit_artifact_notification(out_filename.as_path(), "metadata"); + tcx.sess.diagnostic().emit_artifact_notification(out_filename.as_path(), "metadata"); } (filename, None) } else { diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 2b5773320b4..bcc124524eb 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -212,7 +212,7 @@ //! no means all of the necessary details. Take a look at the rest of //! metadata::locator or metadata::creader for all the juicy details! -use crate::creader::Library; +use crate::creader::{Library, MetadataLoader}; use crate::errors; use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER}; @@ -223,7 +223,7 @@ use rustc_data_structures::svh::Svh; use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; use rustc_fs_util::try_canonicalize; use rustc_session::config; -use rustc_session::cstore::{CrateSource, MetadataLoader}; +use rustc_session::cstore::CrateSource; use rustc_session::filesearch::FileSearch; use rustc_session::search_paths::PathKind; use rustc_session::utils::CanonicalizedPath; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index f352fa6d46a..b3760b1099b 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -160,6 +160,18 @@ impl<'tcx> Collector<'tcx> { } NativeLibKind::RawDylib } + "link-arg" => { + if !features.link_arg_attribute { + feature_err( + &sess.parse_sess, + sym::link_arg_attribute, + span, + "link kind `link-arg` is unstable", + ) + .emit(); + } + NativeLibKind::LinkArg + } kind => { sess.emit_err(errors::UnknownLinkKind { span, kind }); continue; diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index c1884bb8068..8c1e58fefc5 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -4,9 +4,10 @@ /// /// If you have a span available, you should use [`span_bug`] instead. /// -/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful. +/// If the bug should only be emitted when compilation didn't fail, [`Session::span_delayed_bug`] +/// may be useful. /// -/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug +/// [`Session::span_delayed_bug`]: rustc_session::Session::span_delayed_bug /// [`span_bug`]: crate::span_bug #[macro_export] macro_rules! bug { @@ -23,9 +24,10 @@ macro_rules! bug { /// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger /// ICEs. /// -/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful. +/// If the bug should only be emitted when compilation didn't fail, [`Session::span_delayed_bug`] +/// may be useful. /// -/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug +/// [`Session::span_delayed_bug`]: rustc_session::Session::span_delayed_bug #[macro_export] macro_rules! span_bug { ($span:expr, $msg:expr) => ({ $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) }); diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index f7a55fa95b6..27d82f5fefc 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -566,7 +566,7 @@ impl<'tcx> TyCtxt<'tcx> { |span, def_id| { // The API could be uncallable for other reasons, for example when a private module // was referenced. - self.sess.delay_span_bug(span, format!("encountered unmarked API: {def_id:?}")); + self.sess.span_delayed_bug(span, format!("encountered unmarked API: {def_id:?}")); }, ) } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index aded3e495d9..09e56b2e4a8 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -315,7 +315,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> { pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> { Self::uninit_inner(size, align, || { ty::tls::with(|tcx| { - tcx.sess.delay_span_bug(DUMMY_SP, "exhausted memory during interpretation") + tcx.sess.span_delayed_bug(DUMMY_SP, "exhausted memory during interpretation") }); InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted).into() }) diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index e360fb3eaaf..e5f891fcc91 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -199,7 +199,7 @@ pub struct LitToConstInput<'tcx> { #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] pub enum LitToConstError { /// The literal's inferred type did not match the expected `ty` in the input. - /// This is used for graceful error handling (`delay_span_bug`) in + /// This is used for graceful error handling (`span_delayed_bug`) in /// type checking (`Const::from_anon_const`). TypeError, Reported(ErrorGuaranteed), diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 29decd0f050..03f3ceb8d17 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -108,9 +108,9 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue // Queries marked with `fatal_cycle` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. rustc_queries! { - /// This exists purely for testing the interactions between delay_span_bug and incremental. - query trigger_delay_span_bug(key: DefId) -> () { - desc { "triggering a delay span bug for testing incremental" } + /// This exists purely for testing the interactions between span_delayed_bug and incremental. + query trigger_span_delayed_bug(key: DefId) -> () { + desc { "triggering a span delayed bug for testing incremental" } } /// Collects the list of all tools registered using `#![register_tool]`. diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 9a6eba89655..0d1f3c1f8b5 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -551,7 +551,7 @@ macro_rules! define_feedable { // We have an inconsistency. This can happen if one of the two // results is tainted by errors. In this case, delay a bug to // ensure compilation is doomed, and keep the `old` value. - tcx.sess.delay_span_bug(DUMMY_SP, format!( + tcx.sess.span_delayed_bug(DUMMY_SP, format!( "Trying to feed an already recorded value for query {} key={key:?}:\n\ old value: {old:?}\nnew value: {value:?}", stringify!($name), diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 7650389415c..1d9a25628b0 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -481,7 +481,7 @@ impl<'tcx> AdtDef<'tcx> { ErrorHandled::Reported(..) => "enum discriminant evaluation failed", ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics", }; - tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg); + tcx.sess.span_delayed_bug(tcx.def_span(expr_did), msg); None } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index d0a1c943292..b478d95be1b 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -144,7 +144,7 @@ impl<'tcx> Const<'tcx> { span: S, msg: &'static str, ) -> Const<'tcx> { - let reported = tcx.sess.delay_span_bug(span, msg); + let reported = tcx.sess.span_delayed_bug(span, msg); Const::new_error(tcx, reported, ty) } @@ -208,7 +208,7 @@ impl<'tcx> Const<'tcx> { match tcx.at(expr.span).lit_to_const(lit_input) { Ok(c) => return Some(c), Err(e) => { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( expr.span, format!("Const::from_anon_const: couldn't lit_to_const {e:?}"), ); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index bb02c6e0c78..ff690db7bee 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -714,8 +714,10 @@ impl<'tcx> TyCtxt<'tcx> { { Bound::Included(a) } else { - self.sess - .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute"); + self.sess.span_delayed_bug( + attr.span, + "invalid rustc_layout_scalar_valid_range attribute", + ); Bound::Unbounded } }; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4d8ac19dbe2..e1d1f361091 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -282,8 +282,8 @@ pub struct LayoutCx<'tcx, C> { impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> { type TargetDataLayoutRef = &'tcx TargetDataLayout; - fn delay_bug(&self, txt: String) { - self.tcx.sess.delay_span_bug(DUMMY_SP, txt); + fn delayed_bug(&self, txt: String) { + self.tcx.sess.span_delayed_bug(DUMMY_SP, txt); } fn current_data_layout(&self) -> Self::TargetDataLayoutRef { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 24cba913bb8..9feda4d205e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -296,6 +296,23 @@ pub enum Visibility<Id = LocalDefId> { Restricted(Id), } +impl Visibility { + pub fn to_string(self, def_id: LocalDefId, tcx: TyCtxt<'_>) -> String { + match self { + ty::Visibility::Restricted(restricted_id) => { + if restricted_id.is_top_level_module() { + "pub(crate)".to_string() + } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() { + "pub(self)".to_string() + } else { + format!("pub({})", tcx.item_name(restricted_id.to_def_id())) + } + } + ty::Visibility::Public => "pub".to_string(), + } + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] pub enum BoundConstness { /// `T: Trait` diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d50743bc207..68dd8dee87c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3025,7 +3025,7 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> { // // For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths` // wrapper can be used to suppress this query, in exchange for full paths being formatted. - tcx.sess.delay_good_path_bug( + tcx.sess.good_path_delayed_bug( "trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging", ); } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f12a512da31..e10b5706b48 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1545,7 +1545,7 @@ impl<'tcx> Region<'tcx> { tcx.intern_region(ty::ReError(reported)) } - /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` to ensure it + /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` to ensure it /// gets used. #[track_caller] pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> { @@ -1556,7 +1556,7 @@ impl<'tcx> Region<'tcx> { ) } - /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` with the given + /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` with the given /// `msg` to ensure it gets used. #[track_caller] pub fn new_error_with_message<S: Into<MultiSpan>>( @@ -1564,7 +1564,7 @@ impl<'tcx> Region<'tcx> { span: S, msg: &'static str, ) -> Region<'tcx> { - let reported = tcx.sess.delay_span_bug(span, msg); + let reported = tcx.sess.span_delayed_bug(span, msg); Region::new_error(tcx, reported) } @@ -1997,13 +1997,13 @@ impl<'tcx> Ty<'tcx> { Ty::new(tcx, Error(reported)) } - /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. + /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` to ensure it gets used. #[track_caller] pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { Ty::new_error_with_message(tcx, DUMMY_SP, "TyKind::Error constructed but no error reported") } - /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to + /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to /// ensure it gets used. #[track_caller] pub fn new_error_with_message<S: Into<MultiSpan>>( @@ -2011,7 +2011,7 @@ impl<'tcx> Ty<'tcx> { span: S, msg: impl Into<String>, ) -> Ty<'tcx> { - let reported = tcx.sess.delay_span_bug(span, msg); + let reported = tcx.sess.span_delayed_bug(span, msg); Ty::new(tcx, Error(reported)) } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 4a5c89411da..d372c1cd604 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -391,7 +391,7 @@ impl<'tcx> TypeckResults<'tcx> { pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> { self.pat_binding_modes().get(id).copied().or_else(|| { - s.delay_span_bug(sp, "missing binding mode"); + s.span_delayed_bug(sp, "missing binding mode"); None }) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 40d592ddef0..70252a4dc67 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -361,7 +361,7 @@ impl<'tcx> TyCtxt<'tcx> { let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { self.sess - .delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); + .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function"); return; }; diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index 634ed5ec54b..21c1a93fde8 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -38,16 +38,16 @@ fn opt_span_bug_fmt<S: Into<MultiSpan>>( }) } -/// A query to trigger a `delay_span_bug`. Clearly, if one has a `tcx` one can already trigger a -/// `delay_span_bug`, so what is the point of this? It exists to help us test `delay_span_bug`'s +/// A query to trigger a `span_delayed_bug`. Clearly, if one has a `tcx` one can already trigger a +/// `span_delayed_bug`, so what is the point of this? It exists to help us test `span_delayed_bug`'s /// interactions with the query system and incremental. -pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) { - tcx.sess.delay_span_bug( +pub fn trigger_span_delayed_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) { + tcx.sess.span_delayed_bug( tcx.def_span(key), - "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]", + "delayed span bug triggered by #[rustc_error(span_delayed_bug_from_inside_query)]", ); } pub fn provide(providers: &mut crate::query::Providers) { - *providers = crate::query::Providers { trigger_delay_span_bug, ..*providers }; + *providers = crate::query::Providers { trigger_span_delayed_bug, ..*providers }; } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 4ed49e78738..3bfffa7354d 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -114,7 +114,7 @@ fn lit_to_mir_constant<'tcx>( let width = tcx .layout_of(param_ty) .map_err(|_| { - LitToConstError::Reported(tcx.sess.delay_span_bug( + LitToConstError::Reported(tcx.sess.span_delayed_bug( DUMMY_SP, format!("couldn't compute width of literal: {:?}", lit_input.lit), )) @@ -158,7 +158,7 @@ fn lit_to_mir_constant<'tcx>( } (ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg) .ok_or_else(|| { - LitToConstError::Reported(tcx.sess.delay_span_bug( + LitToConstError::Reported(tcx.sess.span_delayed_bug( DUMMY_SP, format!("couldn't parse float literal: {:?}", lit_input.lit), )) @@ -167,7 +167,7 @@ fn lit_to_mir_constant<'tcx>( (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), (ast::LitKind::Err, _) => { return Err(LitToConstError::Reported( - tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), + tcx.sess.span_delayed_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), )); } _ => return Err(LitToConstError::TypeError), diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index c17fdf71b55..1f7c6d7875b 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -470,7 +470,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { if let Some((assigned_ty, assignment_span)) = self.assignment_info { if assigned_ty.needs_drop(self.tcx, self.param_env) { // This would be unsafe, but should be outright impossible since we reject such unions. - self.tcx.sess.delay_span_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}")); + self.tcx.sess.span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}")); } } else { self.requires_unsafe(expr.span, AccessToUnionField); diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index fbb74650faa..240aa10ac91 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -16,7 +16,7 @@ pub(crate) fn lit_to_const<'tcx>( let width = tcx .layout_of(param_ty) .map_err(|_| { - LitToConstError::Reported(tcx.sess.delay_span_bug( + LitToConstError::Reported(tcx.sess.span_delayed_bug( DUMMY_SP, format!("couldn't compute width of literal: {:?}", lit_input.lit), )) @@ -62,7 +62,7 @@ pub(crate) fn lit_to_const<'tcx>( (ast::LitKind::Float(n, _), ty::Float(fty)) => { let bits = parse_float_into_scalar(*n, *fty, neg) .ok_or_else(|| { - LitToConstError::Reported(tcx.sess.delay_span_bug( + LitToConstError::Reported(tcx.sess.span_delayed_bug( DUMMY_SP, format!("couldn't parse float literal: {:?}", lit_input.lit), )) @@ -73,7 +73,7 @@ pub(crate) fn lit_to_const<'tcx>( (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), (ast::LitKind::Err, _) => { return Err(LitToConstError::Reported( - tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), + tcx.sess.span_delayed_bug(DUMMY_SP, "encountered LitKind::Err during mir build"), )); } _ => return Err(LitToConstError::TypeError), diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 5edb2054fd4..eb548ad29eb 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -108,7 +108,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let msg = format!( "found bad range pattern endpoint `{expr:?}` outside of error recovery" ); - return Err(self.tcx.sess.delay_span_bug(expr.span, msg)); + return Err(self.tcx.sess.span_delayed_bug(expr.span, msg)); }; Ok((Some(PatRangeBoundary::Finite(value)), ascr, inline_const)) } @@ -178,7 +178,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ) -> Result<PatKind<'tcx>, ErrorGuaranteed> { if lo_expr.is_none() && hi_expr.is_none() { let msg = format!("found twice-open range pattern (`..`) outside of error recovery"); - return Err(self.tcx.sess.delay_span_bug(span, msg)); + return Err(self.tcx.sess.span_delayed_bug(span, msg)); } let (lo, lo_ascr, lo_inline) = self.lower_pattern_range_endpoint(lo_expr)?; diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 84e7362c3d0..f246de55ca8 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -242,7 +242,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty; if assigned_ty.needs_drop(self.tcx, self.param_env) { // This would be unsafe, but should be outright impossible since we reject such unions. - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( self.source_info.span, format!("union fields that need dropping should be impossible: {assigned_ty}") ); diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index d626fed3275..1373596fd2b 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1510,8 +1510,10 @@ impl<'tcx> MirPass<'tcx> for StateTransform { (args.discr_ty(tcx), movability == hir::Movability::Movable) } _ => { - tcx.sess - .delay_span_bug(body.span, format!("unexpected coroutine type {coroutine_ty}")); + tcx.sess.span_delayed_bug( + body.span, + format!("unexpected coroutine type {coroutine_ty}"), + ); return; } }; diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 83517aef7e2..f7188ea83fc 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -316,7 +316,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { self.init_data.seek_before(self.body.terminator_loc(bb)); let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent); if maybe_dead { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( terminator.source_info.span, format!( "drop of untracked, uninitialized value {bb:?}, place {place:?} ({path:?})" @@ -381,7 +381,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { LookupResult::Parent(None) => {} LookupResult::Parent(Some(_)) => { if !replace { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( terminator.source_info.span, format!("drop of untracked value {bb:?}"), ); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index fff760ba399..89e897191e8 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -266,7 +266,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { let body = &tcx.mir_const(def).borrow(); if body.return_ty().references_error() { - tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors"); + tcx.sess.span_delayed_bug(body.span, "mir_const_qualif: MIR had errors"); return Default::default(); } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 6e0765f74fe..92df2da8710 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -223,9 +223,6 @@ impl<'a> StringReader<'a> { rustc_lexer::TokenKind::Literal { kind, suffix_start } => { let suffix_start = start + BytePos(suffix_start); let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind); - if let token::LitKind::CStr | token::LitKind::CStrRaw(_) = kind { - self.sess.gated_spans.gate(sym::c_str_literals, self.mk_sp(start, self.pos)); - } let suffix = if suffix_start < self.pos { let string = self.str_from(suffix_start); if string == "_" { diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index bad7c19cc27..422bb79308d 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -56,7 +56,7 @@ impl<'a> Parser<'a> { } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind { if attr_style != ast::AttrStyle::Outer { let span = self.token.span; - let mut err = self.sess.span_diagnostic.struct_span_err_with_code( + let mut err = self.diagnostic().struct_span_err_with_code( span, fluent::parse_inner_doc_comment_not_permitted, error_code!(E0753), @@ -418,7 +418,7 @@ impl<'a> Parser<'a> { } Err(InvalidMetaItem { span: self.token.span, token: self.token.clone() } - .into_diagnostic(&self.sess.span_diagnostic)) + .into_diagnostic(self.diagnostic())) } } diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index c4e8d9006e6..c66a7176aab 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -41,7 +41,7 @@ impl AttrWrapper { } pub(crate) fn take_for_recovery(self, sess: &ParseSess) -> AttrVec { - sess.span_diagnostic.delay_span_bug( + sess.span_diagnostic.span_delayed_bug( self.attrs.get(0).map(|attr| attr.span).unwrap_or(DUMMY_SP), "AttrVec is taken for recovery but no error is produced", ); @@ -266,9 +266,8 @@ impl<'a> Parser<'a> { if let Some(attr_range) = self.capture_state.inner_attr_ranges.remove(&inner_attr.id) { inner_attr_replace_ranges.push(attr_range); } else { - self.sess - .span_diagnostic - .delay_span_bug(inner_attr.span, "Missing token range for attribute"); + self.diagnostic() + .span_delayed_bug(inner_attr.span, "Missing token range for attribute"); } } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 8921c1c6a03..a4eb36dd92c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -247,11 +247,11 @@ impl<'a> Parser<'a> { sp: S, m: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - self.sess.span_diagnostic.struct_span_err(sp, m) + self.diagnostic().struct_span_err(sp, m) } pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: impl Into<String>) -> ! { - self.sess.span_diagnostic.span_bug(sp, m) + self.diagnostic().span_bug(sp, m) } pub(super) fn diagnostic(&self) -> &'a Handler { @@ -285,7 +285,7 @@ impl<'a> Parser<'a> { span: self.prev_token.span, missing_comma: None, } - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(self.diagnostic())); } let valid_follow = &[ @@ -348,7 +348,7 @@ impl<'a> Parser<'a> { suggest_remove_comma, help_cannot_start_number, }; - let mut err = err.into_diagnostic(&self.sess.span_diagnostic); + let mut err = err.into_diagnostic(self.diagnostic()); // if the token we have is a `<` // it *might* be a misplaced generic @@ -1426,7 +1426,7 @@ impl<'a> Parser<'a> { // Not entirely sure now, but we bubble the error up with the // suggestion. self.restore_snapshot(snapshot); - Err(err.into_diagnostic(&self.sess.span_diagnostic)) + Err(err.into_diagnostic(self.diagnostic())) } } } else if token::OpenDelim(Delimiter::Parenthesis) == self.token.kind { @@ -1441,7 +1441,7 @@ impl<'a> Parser<'a> { } // Consume the fn call arguments. match self.consume_fn_args() { - Err(()) => Err(err.into_diagnostic(&self.sess.span_diagnostic)), + Err(()) => Err(err.into_diagnostic(self.diagnostic())), Ok(()) => { self.sess.emit_err(err); // FIXME: actually check that the two expressions in the binop are @@ -1467,7 +1467,7 @@ impl<'a> Parser<'a> { mk_err_expr(self, inner_op.span.to(self.prev_token.span)) } else { // These cases cause too many knock-down errors, bail out (#61329). - Err(err.into_diagnostic(&self.sess.span_diagnostic)) + Err(err.into_diagnostic(self.diagnostic())) } }; } @@ -2522,8 +2522,7 @@ impl<'a> Parser<'a> { Ok(Some(GenericArg::Const(self.parse_const_arg()?))) } else { let after_kw_const = self.token.span; - self.recover_const_arg(after_kw_const, err.into_diagnostic(&self.sess.span_diagnostic)) - .map(Some) + self.recover_const_arg(after_kw_const, err.into_diagnostic(self.diagnostic())).map(Some) } } @@ -2886,7 +2885,7 @@ impl<'a> Parser<'a> { span: path.span.shrink_to_hi(), between: between_span, } - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(self.diagnostic())); } } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b1b77305e4f..f8444881d1a 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1269,7 +1269,7 @@ impl<'a> Parser<'a> { .collect(), }, } - .into_diagnostic(&self.sess.span_diagnostic); + .into_diagnostic(self.diagnostic()); replacement_err.emit(); let old_err = mem::replace(err, replacement_err); @@ -1691,7 +1691,7 @@ impl<'a> Parser<'a> { err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>, ) -> L { if let Some(mut diag) = - self.sess.span_diagnostic.steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) + self.diagnostic().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) { diag.span_suggestion_verbose( lifetime.span.shrink_to_hi(), @@ -1882,7 +1882,7 @@ impl<'a> Parser<'a> { let Some((ident, false)) = self.token.ident() else { let err = errors::ExpectedBuiltinIdent { span: self.token.span } - .into_diagnostic(&self.sess.span_diagnostic); + .into_diagnostic(self.diagnostic()); return Err(err); }; self.sess.gated_spans.gate(sym::builtin_syntax, ident.span); @@ -1893,7 +1893,7 @@ impl<'a> Parser<'a> { Ok(res) } else { let err = errors::UnknownBuiltinConstruct { span: lo.to(ident.span), name: ident.name } - .into_diagnostic(&self.sess.span_diagnostic); + .into_diagnostic(self.diagnostic()); return Err(err); }; self.expect(&TokenKind::CloseDelim(Delimiter::Parenthesis))?; @@ -1957,7 +1957,7 @@ impl<'a> Parser<'a> { && matches!(e.kind, ExprKind::Err) { let mut err = errors::InvalidInterpolatedExpression { span: self.token.span } - .into_diagnostic(&self.sess.span_diagnostic); + .into_diagnostic(self.diagnostic()); err.downgrade_to_delayed_bug(); return Err(err); } @@ -2169,7 +2169,7 @@ impl<'a> Parser<'a> { return Err(errors::MissingSemicolonBeforeArray { open_delim: open_delim_span, semicolon: prev_span.shrink_to_hi(), - }.into_diagnostic(&self.sess.span_diagnostic)); + }.into_diagnostic(self.diagnostic())); } Ok(_) => (), Err(err) => err.cancel(), @@ -2309,7 +2309,7 @@ impl<'a> Parser<'a> { if self.check_keyword(kw::Async) { let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo); Err(errors::AsyncMoveOrderIncorrect { span: move_async_span } - .into_diagnostic(&self.sess.span_diagnostic)) + .into_diagnostic(self.diagnostic())) } else { Ok(CaptureBy::Value { move_kw: move_kw_span }) } @@ -2499,7 +2499,7 @@ impl<'a> Parser<'a> { }; if self.prev_token.kind == token::BinOp(token::Or) { // This was part of a closure, the that part of the parser recover. - return Err(err.into_diagnostic(&self.sess.span_diagnostic)); + return Err(err.into_diagnostic(self.diagnostic())); } else { Some(self.sess.emit_err(err)) } @@ -3148,7 +3148,7 @@ impl<'a> Parser<'a> { let (attrs, body) = self.parse_inner_attrs_and_block()?; if self.eat_keyword(kw::Catch) { Err(errors::CatchAfterTry { span: self.prev_token.span } - .into_diagnostic(&self.sess.span_diagnostic)) + .into_diagnostic(self.diagnostic())) } else { let span = span_lo.to(body.span); self.sess.gated_spans.gate(sym::try_blocks, span); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ab18e40482e..a737f37a104 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -444,11 +444,7 @@ impl<'a> Parser<'a> { None }; - if let Some(err) = err { - Err(err.into_diagnostic(&self.sess.span_diagnostic)) - } else { - Ok(()) - } + if let Some(err) = err { Err(err.into_diagnostic(self.diagnostic())) } else { Ok(()) } } fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> { @@ -1382,8 +1378,7 @@ impl<'a> Parser<'a> { let span = self.prev_token.span.shrink_to_hi(); let err: DiagnosticBuilder<'_, ErrorGuaranteed> = - errors::MissingConstType { span, colon, kind } - .into_diagnostic(&self.sess.span_diagnostic); + errors::MissingConstType { span, colon, kind }.into_diagnostic(self.diagnostic()); err.stash(span, StashKey::ItemNoType); // The user intended that the type be inferred, @@ -1400,7 +1395,7 @@ impl<'a> Parser<'a> { self.bump(); self.sess.emit_err(err); } else { - return Err(err.into_diagnostic(&self.sess.span_diagnostic)); + return Err(err.into_diagnostic(self.diagnostic())); } } @@ -1600,7 +1595,7 @@ impl<'a> Parser<'a> { } else { let err = errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token.clone()); - return Err(err.into_diagnostic(&self.sess.span_diagnostic)); + return Err(err.into_diagnostic(self.diagnostic())); }; Ok((class_name, ItemKind::Struct(vdata, generics))) @@ -1796,7 +1791,7 @@ impl<'a> Parser<'a> { let sp = previous_span.shrink_to_hi(); err.missing_comma = Some(sp); } - return Err(err.into_diagnostic(&self.sess.span_diagnostic)); + return Err(err.into_diagnostic(self.diagnostic())); } } _ => { @@ -1846,7 +1841,7 @@ impl<'a> Parser<'a> { // Make sure an error was emitted (either by recovering an angle bracket, // or by finding an identifier as the next token), since we're // going to continue parsing - assert!(self.sess.span_diagnostic.has_errors().is_some()); + assert!(self.diagnostic().has_errors().is_some()); } else { return Err(err); } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 06cc39fbb5a..4360a69e501 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -115,7 +115,7 @@ impl<'a> Parser<'a> { Some(item) => NtItem(item), None => { return Err(UnexpectedNonterminal::Item(self.token.span) - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(self.diagnostic())); } }, NonterminalKind::Block => { @@ -127,7 +127,7 @@ impl<'a> Parser<'a> { Some(s) => NtStmt(P(s)), None => { return Err(UnexpectedNonterminal::Statement(self.token.span) - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(self.diagnostic())); } }, NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => { @@ -163,7 +163,7 @@ impl<'a> Parser<'a> { span: self.token.span, token: self.token.clone(), } - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(self.diagnostic())); } NonterminalKind::Path => { NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) @@ -181,7 +181,7 @@ impl<'a> Parser<'a> { span: self.token.span, token: self.token.clone(), } - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(self.diagnostic())); } } }; diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 3d1d1ec8108..bd1bf2c7859 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -877,7 +877,7 @@ impl<'a> Parser<'a> { // will direct us over to `parse_enum_variant()`. if self.token == token::OpenDelim(Delimiter::Parenthesis) { return Err(EnumPatternInsteadOfIdentifier { span: self.prev_token.span } - .into_diagnostic(&self.sess.span_diagnostic)); + .into_diagnostic(self.diagnostic())); } Ok(PatKind::Ident(binding_annotation, ident, sub)) @@ -991,7 +991,7 @@ impl<'a> Parser<'a> { // check that a comma comes after every field if !ate_comma { let mut err = ExpectedCommaAfterPatternField { span: self.token.span } - .into_diagnostic(&self.sess.span_diagnostic); + .into_diagnostic(self.diagnostic()); if let Some(mut delayed) = delayed_err { delayed.emit(); } diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index f825363ae39..18a80aa34f8 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -31,7 +31,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { if !errors.is_empty() { let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2); - tcx.sess.delay_span_bug(rustc_span::DUMMY_SP, message); + tcx.sess.span_delayed_bug(rustc_span::DUMMY_SP, message); } } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index a0ba4e481f6..c9e5eb50b3a 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -592,7 +592,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match self.successors[ln] { Some(successor) => self.assigned_on_entry(successor, var), None => { - self.ir.tcx.sess.delay_span_bug(DUMMY_SP, "no successor"); + self.ir.tcx.sess.span_delayed_bug(DUMMY_SP, "no successor"); true } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index b8109d5bb06..e7ec4749efe 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -888,21 +888,6 @@ pub struct TestReachabilityVisitor<'tcx, 'a> { effective_visibilities: &'a EffectiveVisibilities, } -fn vis_to_string<'tcx>(def_id: LocalDefId, vis: ty::Visibility, tcx: TyCtxt<'tcx>) -> String { - match vis { - ty::Visibility::Restricted(restricted_id) => { - if restricted_id.is_top_level_module() { - "pub(crate)".to_string() - } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() { - "pub(self)".to_string() - } else { - format!("pub({})", tcx.item_name(restricted_id.to_def_id())) - } - } - ty::Visibility::Public => "pub".to_string(), - } -} - impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) { if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) { @@ -910,7 +895,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { let span = self.tcx.def_span(def_id.to_def_id()); if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) { for level in Level::all_levels() { - let vis_str = vis_to_string(def_id, *effective_vis.at_level(level), self.tcx); + let vis_str = effective_vis.at_level(level).to_string(def_id, self.tcx); if level != Level::Direct { error_msg.push_str(", "); } @@ -1268,7 +1253,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { } else { self.tcx .sess - .delay_span_bug(expr.span, "no type-dependent def for method call"); + .span_delayed_bug(expr.span, "no type-dependent def for method call"); } } _ => {} @@ -1506,11 +1491,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { tcx: self.tcx, }) .into(), - item_vis_descr: &vis_to_string(self.item_def_id, reachable_at_vis, self.tcx), + item_vis_descr: &reachable_at_vis.to_string(self.item_def_id, self.tcx), ty_span: vis_span, ty_kind: kind, ty_descr: descr.into(), - ty_vis_descr: &vis_to_string(local_def_id, vis, self.tcx), + ty_vis_descr: &vis.to_string(local_def_id, self.tcx), }, ); } @@ -1589,8 +1574,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { span, kind: self.tcx.def_descr(def_id.to_def_id()), descr: (&LazyDefPathStr { def_id: def_id.to_def_id(), tcx: self.tcx }).into(), - reachable_vis: &vis_to_string(def_id, *reachable_at_vis, self.tcx), - reexported_vis: &vis_to_string(def_id, *reexported_at_vis, self.tcx), + reachable_vis: &reachable_at_vis.to_string(def_id, self.tcx), + reexported_vis: &reexported_at_vis.to_string(def_id, self.tcx), }, ); } @@ -1843,7 +1828,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility { .. }) => tr.path.res.opt_def_id().map_or_else( || { - tcx.sess.delay_span_bug(tr.path.span, "trait without a def-id"); + tcx.sess.span_delayed_bug(tr.path.span, "trait without a def-id"); ty::Visibility::Public }, |def_id| tcx.visibility(def_id).expect_local(), diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 5acd012ef04..bc09972185a 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -818,7 +818,7 @@ impl<D: Deps> DepGraphData<D> { None => {} } - if let None = qcx.dep_context().sess().has_errors_or_delayed_span_bugs() { + if let None = qcx.dep_context().sess().has_errors_or_span_delayed_bugs() { panic!("try_mark_previous_green() - Forcing the DepNode should have set its color") } diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 2a55ec72c5f..d933f897833 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -605,7 +605,7 @@ pub(crate) fn report_cycle<'a>( note_span: (), }; - cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic) + cycle_diag.into_diagnostic(sess.diagnostic()) } pub fn print_query_stack<Qcx: QueryContext>( diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 2f9f094dae2..41638b38c74 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -138,7 +138,7 @@ where && let Some(span) = root.query.span { error.stash(span, StashKey::Cycle); - qcx.dep_context().sess().delay_span_bug(span, "delayed cycle error") + qcx.dep_context().sess().span_delayed_bug(span, "delayed cycle error") } else { error.emit() }; @@ -421,7 +421,7 @@ where // We have an inconsistency. This can happen if one of the two // results is tainted by errors. In this case, delay a bug to // ensure compilation is doomed. - qcx.dep_context().sess().delay_span_bug( + qcx.dep_context().sess().span_delayed_bug( DUMMY_SP, format!( "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 272483d4a98..a5faaaab639 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -127,8 +127,6 @@ resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here resolve_generic_params_from_outer_item_ty_param = type parameter from outer item -resolve_glob_import_doesnt_reexport = - glob import doesn't reexport anything because no candidate is public enough resolve_ident_bound_more_than_once_in_parameter_list = identifier `{$identifier}` is bound more than once in this parameter list @@ -200,7 +198,7 @@ resolve_param_in_non_trivial_anon_const = .label = cannot perform const operation using `{$name}` resolve_param_in_non_trivial_anon_const_help = - use `#![feature(generic_const_exprs)]` to allow generic const expressions + add `#![feature(generic_const_exprs)]` to allow generic const expressions resolve_param_in_ty_of_const_param = the type of const parameters must not depend on other generic parameters diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index a069c6f8e04..a9f7002e564 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1201,7 +1201,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } }; self.report_error(span, error); - self.tcx.sess.delay_span_bug(span, CG_BUG_STR); + self.tcx.sess.span_delayed_bug(span, CG_BUG_STR); } return Res::Err; diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 3774ae66420..b28ad671f12 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -8,7 +8,7 @@ use crate::errors::{ ItemsInTraitsAreNotImportable, }; use crate::Determinacy::{self, *}; -use crate::{fluent_generated as fluent, Namespace::*}; +use crate::Namespace::*; use crate::{module_to_string, names_to_string, ImportSuggestion}; use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment}; use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet}; @@ -987,13 +987,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if !is_prelude && let Some(max_vis) = max_vis.get() - && !max_vis.is_at_least(import.expect_vis(), self.tcx) + && let import_vis = import.expect_vis() + && !max_vis.is_at_least(import_vis, self.tcx) { - self.lint_buffer.buffer_lint( + let def_id = self.local_def_id(id); + let msg = format!( + "glob import doesn't reexport anything with visibility `{}` because no imported item is public enough", + import_vis.to_string(def_id, self.tcx) + ); + self.lint_buffer.buffer_lint_with_diagnostic( UNUSED_IMPORTS, id, import.span, - fluent::resolve_glob_import_doesnt_reexport, + msg.to_string(), + BuiltinLintDiagnostics::RedundantImportVisibility { + max_vis: max_vis.to_string(def_id, self.tcx), + span: import.span, + }, ); } return None; @@ -1059,7 +1069,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if res == Res::Err || has_ambiguity_error { this.tcx .sess - .delay_span_bug(import.span, "some error happened for an import"); + .span_delayed_bug(import.span, "some error happened for an import"); return; } if let Ok(initial_res) = initial_res { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 75a0541b89b..f20d5829030 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3544,7 +3544,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { Res::SelfCtor(_) => { // We resolve `Self` in pattern position as an ident sometimes during recovery, // so delay a bug instead of ICEing. - self.r.tcx.sess.delay_span_bug( + self.r.tcx.sess.span_delayed_bug( ident.span, "unexpected `SelfCtor` in pattern, expected identifier" ); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 5f21741223b..ca225416e36 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Make sure compilation does not succeed if preferred macro resolution // has changed after the macro had been expanded. In theory all such // situations should be reported as errors, so this is a bug. - this.tcx.sess.delay_span_bug(span, "inconsistent resolution for a macro"); + this.tcx.sess.span_delayed_bug(span, "inconsistent resolution for a macro"); } } else { // It's possible that the macro was unresolved (indeterminate) and silently diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 77874bd9c07..e694e150b31 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -8,23 +8,19 @@ use crate::search_paths::SearchPath; use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; use crate::{lint, HashStableContext}; use crate::{EarlyErrorHandler, Session}; - use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey}; -use rustc_target::abi::Align; -use rustc_target::spec::LinkSelfContainedComponents; -use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo}; -use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS}; - +use rustc_errors::emitter::HumanReadableErrorType; +use rustc_errors::{ColorConfig, DiagnosticArgValue, HandlerFlags, IntoDiagnosticArg}; use rustc_feature::UnstableFeatures; use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm}; - -use rustc_errors::emitter::HumanReadableErrorType; -use rustc_errors::{ColorConfig, DiagnosticArgValue, HandlerFlags, IntoDiagnosticArg}; - +use rustc_target::abi::Align; +use rustc_target::spec::LinkSelfContainedComponents; +use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo}; +use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS}; use std::collections::btree_map::{ Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter, }; @@ -555,12 +551,15 @@ impl Default for ErrorOutputType { /// Parameter to control path trimming. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub enum TrimmedDefPaths { - /// `try_print_trimmed_def_path` never prints a trimmed path and never calls the expensive query + /// `try_print_trimmed_def_path` never prints a trimmed path and never calls the expensive + /// query. #[default] Never, - /// `try_print_trimmed_def_path` calls the expensive query, the query doesn't call `delay_good_path_bug` + /// `try_print_trimmed_def_path` calls the expensive query, the query doesn't call + /// `good_path_delayed_bug`. Always, - /// `try_print_trimmed_def_path` calls the expensive query, the query calls `delay_good_path_bug` + /// `try_print_trimmed_def_path` calls the expensive query, the query calls + /// `good_path_delayed_bug`. GoodPath, } @@ -1250,7 +1249,7 @@ fn default_configuration(sess: &Session) -> Cfg { // NOTE: This should be kept in sync with `CheckCfg::fill_well_known` below. let end = &sess.target.endian; let arch = &sess.target.arch; - let wordsz = sess.target.pointer_width.to_string(); + let wordsz = sess.target.pointer_width as u64; let os = &sess.target.os; let env = &sess.target.env; let abi = &sess.target.abi; @@ -1277,7 +1276,7 @@ fn default_configuration(sess: &Session) -> Cfg { } ret.insert((sym::target_arch, Some(Symbol::intern(arch)))); ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str())))); - ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz)))); + ret.insert((sym::target_pointer_width, Some(sym::integer(wordsz)))); ret.insert((sym::target_env, Some(Symbol::intern(env)))); ret.insert((sym::target_abi, Some(Symbol::intern(abi)))); if sess.is_nightly_build() { @@ -1297,19 +1296,18 @@ fn default_configuration(sess: &Session) -> Cfg { ] { if i >= min_atomic_width && i <= max_atomic_width { has_atomic = true; - let mut insert_atomic = |s, align: Align| { - ret.insert((sym::target_has_atomic_load_store, Some(Symbol::intern(s)))); + let mut insert_atomic = |sym, align: Align| { + ret.insert((sym::target_has_atomic_load_store, Some(sym))); if atomic_cas { - ret.insert((sym::target_has_atomic, Some(Symbol::intern(s)))); + ret.insert((sym::target_has_atomic, Some(sym))); } if align.bits() == i { - ret.insert((sym::target_has_atomic_equal_alignment, Some(Symbol::intern(s)))); + ret.insert((sym::target_has_atomic_equal_alignment, Some(sym))); } }; - let s = i.to_string(); - insert_atomic(&s, align); - if s == wordsz { - insert_atomic("ptr", layout.pointer_align.abi); + insert_atomic(sym::integer(i), align); + if wordsz == i { + insert_atomic(sym::ptr, layout.pointer_align.abi); } } } @@ -2150,25 +2148,27 @@ fn collect_print_requests( } const PRINT_KINDS: &[(&str, PrintKind)] = &[ + // tidy-alphabetical-start + ("all-target-specs-json", PrintKind::AllTargetSpecs), + ("calling-conventions", PrintKind::CallingConventions), + ("cfg", PrintKind::Cfg), + ("code-models", PrintKind::CodeModels), ("crate-name", PrintKind::CrateName), + ("deployment-target", PrintKind::DeploymentTarget), ("file-names", PrintKind::FileNames), + ("link-args", PrintKind::LinkArgs), + ("native-static-libs", PrintKind::NativeStaticLibs), + ("relocation-models", PrintKind::RelocationModels), + ("split-debuginfo", PrintKind::SplitDebuginfo), + ("stack-protector-strategies", PrintKind::StackProtectorStrategies), ("sysroot", PrintKind::Sysroot), - ("target-libdir", PrintKind::TargetLibdir), - ("cfg", PrintKind::Cfg), - ("calling-conventions", PrintKind::CallingConventions), - ("target-list", PrintKind::TargetList), ("target-cpus", PrintKind::TargetCPUs), ("target-features", PrintKind::TargetFeatures), - ("relocation-models", PrintKind::RelocationModels), - ("code-models", PrintKind::CodeModels), - ("tls-models", PrintKind::TlsModels), - ("native-static-libs", PrintKind::NativeStaticLibs), - ("stack-protector-strategies", PrintKind::StackProtectorStrategies), + ("target-libdir", PrintKind::TargetLibdir), + ("target-list", PrintKind::TargetList), ("target-spec-json", PrintKind::TargetSpec), - ("all-target-specs-json", PrintKind::AllTargetSpecs), - ("link-args", PrintKind::LinkArgs), - ("split-debuginfo", PrintKind::SplitDebuginfo), - ("deployment-target", PrintKind::DeploymentTarget), + ("tls-models", PrintKind::TlsModels), + // tidy-alphabetical-end ]; // We disallow reusing the same path in multiple prints, such as `--print @@ -2297,14 +2297,7 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf if max_g > max_c { DebugInfo::Full } else { cg.debuginfo } } -fn select_debuginfo_compression( - _handler: &EarlyErrorHandler, - unstable_opts: &UnstableOptions, -) -> DebugInfoCompression { - unstable_opts.debuginfo_compression -} - -pub(crate) fn parse_assert_incr_state( +fn parse_assert_incr_state( handler: &EarlyErrorHandler, opt_assertion: &Option<String>, ) -> Option<IncrementalStateAssertion> { @@ -2460,6 +2453,17 @@ pub fn parse_externs( matches: &getopts::Matches, unstable_opts: &UnstableOptions, ) -> Externs { + fn is_ascii_ident(string: &str) -> bool { + let mut chars = string.chars(); + if let Some(start) = chars.next() + && (start.is_ascii_alphabetic() || start == '_') + { + chars.all(|char| char.is_ascii_alphanumeric() || char == '_') + } else { + false + } + } + let is_unstable_enabled = unstable_opts.unstable_options; let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new(); for arg in matches.opt_strs("extern") { @@ -2472,12 +2476,12 @@ pub fn parse_externs( Some((opts, name)) => (Some(opts), name.to_string()), }; - if !crate::utils::is_ascii_ident(&name) { + if !is_ascii_ident(&name) { let mut error = handler.early_struct_error(format!( "crate name `{name}` passed to `--extern` is not a valid ASCII identifier" )); let adjusted_name = name.replace('-', "_"); - if crate::utils::is_ascii_ident(&adjusted_name) { + if is_ascii_ident(&adjusted_name) { error.help(format!( "consider replacing the dashes with underscores: `{adjusted_name}`" )); @@ -2791,8 +2795,7 @@ pub fn build_session_options( // for more details. let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No); let debuginfo = select_debuginfo(matches, &cg); - let debuginfo_compression: DebugInfoCompression = - select_debuginfo_compression(handler, &unstable_opts); + let debuginfo_compression = unstable_opts.debuginfo_compression; let mut search_paths = vec![]; for s in &matches.opt_strs("L") { @@ -3143,6 +3146,12 @@ impl PpMode { } } +#[derive(Clone, Hash, PartialEq, Eq, Debug)] +pub enum WasiExecModel { + Command, + Reactor, +} + /// Command-line arguments passed to the compiler have to be incorporated with /// the dependency tracking system for incremental compilation. This module /// provides some utilities to make this more convenient. @@ -3168,9 +3177,9 @@ pub(crate) mod dep_tracking { LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths, + WasiExecModel, }; use crate::lint; - use crate::options::WasiExecModel; use crate::utils::NativeLib; use rustc_data_structures::stable_hasher::Hash64; use rustc_errors::LanguageIdentifier; diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index d816842b02b..a0f5eb59b6a 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -6,7 +6,6 @@ use crate::search_paths::PathKind; use crate::utils::NativeLibKind; use crate::Session; use rustc_ast as ast; -use rustc_data_structures::owned_slice::OwnedSlice; use rustc_data_structures::sync::{self, AppendOnlyIndexVec, FreezeLock}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; @@ -14,10 +13,9 @@ use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::symbol::Symbol; use rustc_span::Span; use rustc_target::spec::abi::Abi; -use rustc_target::spec::Target; use std::any::Any; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; // lonely orphan structs and enums looking for a better home @@ -197,21 +195,6 @@ pub enum ExternCrateSource { Path, } -/// The backend's way to give the crate store access to the metadata in a library. -/// Note that it returns the raw metadata bytes stored in the library file, whether -/// it is compressed, uncompressed, some weird mix, etc. -/// rmeta files are backend independent and not handled here. -/// -/// At the time of this writing, there is only one backend and one way to store -/// metadata in library -- this trait just serves to decouple rustc_metadata from -/// the archive reader, which depends on LLVM. -pub trait MetadataLoader: std::fmt::Debug { - fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>; - fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>; -} - -pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync; - /// A store of Rust crates, through which their metadata can be accessed. /// /// Note that this trait should probably not be expanding today. All new diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 3988416d0c7..6e459ac45d3 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -9,12 +9,6 @@ use std::path::{Path, PathBuf}; use crate::search_paths::{PathKind, SearchPath}; use rustc_fs_util::fix_windows_verbatim_for_gcc; -#[derive(Copy, Clone)] -pub enum FileMatch { - FileMatches, - FileDoesntMatch, -} - #[derive(Clone)] pub struct FileSearch<'a> { sysroot: &'a Path, diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index ffc2a250681..0b55af2f73b 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,6 +1,4 @@ -#![feature(if_let_guard)] #![feature(let_chains)] -#![feature(min_specialization)] #![feature(never_type)] #![feature(lazy_cell)] #![feature(option_get_or_insert_default)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 68a39de73b7..7a6108bfbe2 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1813,7 +1813,7 @@ options! { "directory into which to write optimization remarks (if not specified, they will be \ written to standard error output)"), report_delayed_bugs: bool = (false, parse_bool, [TRACKED], - "immediately print bugs registered with `delay_span_bug` (default: no)"), + "immediately print bugs registered with `span_delayed_bug` (default: no)"), sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], "use a sanitizer"), sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED], @@ -1985,9 +1985,3 @@ written to standard error output)"), // - compiler/rustc_interface/src/tests.rs // - src/doc/unstable-book/src/compiler-flags } - -#[derive(Clone, Hash, PartialEq, Eq, Debug)] -pub enum WasiExecModel { - Command, - Reactor, -} diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index 9cd96895a61..2ff32b5bb9a 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -1,4 +1,4 @@ -//! Related to out filenames of compilation (e.g. save analysis, binaries). +//! Related to out filenames of compilation (e.g. binaries). use crate::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use crate::errors::{ CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 4d20d6d4187..f7b33cb598b 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -214,7 +214,7 @@ pub struct ParseSess { pub assume_incomplete_release: bool, /// Spans passed to `proc_macro::quote_span`. Each span has a numerical /// identifier represented by its position in the vector. - pub proc_macro_quoted_spans: AppendOnlyVec<Span>, + proc_macro_quoted_spans: AppendOnlyVec<Span>, /// Used to generate new `AttrId`s. Every `AttrId` is unique. pub attr_id_generator: AttrIdGenerator, } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index e79d7648bef..c6f435a8f92 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -10,8 +10,6 @@ use crate::parse::{add_feature_diagnostics, ParseSess}; use crate::search_paths::{PathKind, SearchPath}; use crate::{filesearch, lint}; -pub use rustc_ast::attr::MarkedAttrs; -pub use rustc_ast::Attribute; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::jobserver::{self, Client}; @@ -48,7 +46,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::{atomic::AtomicBool, Arc}; -pub struct OptimizationFuel { +struct OptimizationFuel { /// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`. remaining: u64, /// We're rejecting all further optimizations. @@ -304,7 +302,7 @@ impl Session { if diags.is_empty() { return; } - self.parse_sess.span_diagnostic.emit_future_breakage_report(diags); + self.diagnostic().emit_future_breakage_report(diags); } /// Returns true if the crate is a testing one. @@ -480,7 +478,7 @@ impl Session { sp: S, msg: impl Into<DiagnosticMessage>, code: DiagnosticId, - ) { + ) -> ErrorGuaranteed { self.diagnostic().span_err_with_code(sp, msg, code) } #[rustc_lint_diagnostics] @@ -553,8 +551,8 @@ impl Session { pub fn has_errors(&self) -> Option<ErrorGuaranteed> { self.diagnostic().has_errors() } - pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> { - self.diagnostic().has_errors_or_delayed_span_bugs() + pub fn has_errors_or_span_delayed_bugs(&self) -> Option<ErrorGuaranteed> { + self.diagnostic().has_errors_or_span_delayed_bugs() } pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> { self.diagnostic().is_compilation_going_to_fail() @@ -580,7 +578,7 @@ impl Session { if self.err_count() == old_count { Ok(result) } else { - Err(self.delay_span_bug( + Err(self.span_delayed_bug( rustc_span::DUMMY_SP, "`self.err_count()` changed but an error was not emitted", )) @@ -621,24 +619,28 @@ impl Session { /// /// This can be used in code paths that should never run on successful compilations. /// For example, it can be used to create an [`ErrorGuaranteed`] - /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission directly). + /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission + /// directly). /// /// If no span is available, use [`DUMMY_SP`]. /// /// [`DUMMY_SP`]: rustc_span::DUMMY_SP + /// + /// Note: this function used to be called `delay_span_bug`. It was renamed + /// to match similar functions like `span_err`, `span_warn`, etc. #[track_caller] - pub fn delay_span_bug<S: Into<MultiSpan>>( + pub fn span_delayed_bug<S: Into<MultiSpan>>( &self, sp: S, msg: impl Into<String>, ) -> ErrorGuaranteed { - self.diagnostic().delay_span_bug(sp, msg) + self.diagnostic().span_delayed_bug(sp, msg) } /// Used for code paths of expensive computations that should only take place when /// warnings or errors are emitted. If no messages are emitted ("good path"), then /// it's likely a bug. - pub fn delay_good_path_bug(&self, msg: impl Into<DiagnosticMessage>) { + pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) { if self.opts.unstable_opts.print_type_sizes || self.opts.unstable_opts.query_dep_graph || self.opts.unstable_opts.dump_mir.is_some() @@ -649,40 +651,33 @@ impl Session { return; } - self.diagnostic().delay_good_path_bug(msg) + self.diagnostic().good_path_delayed_bug(msg) } #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) { - self.diagnostic().note_without_error(msg) + pub fn note(&self, msg: impl Into<DiagnosticMessage>) { + self.diagnostic().note(msg) } #[track_caller] #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub fn span_note_without_error<S: Into<MultiSpan>>( - &self, - sp: S, - msg: impl Into<DiagnosticMessage>, - ) { - self.diagnostic().span_note_without_error(sp, msg) + pub fn span_note<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) { + self.diagnostic().span_note(sp, msg) } #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub fn struct_note_without_error( - &self, - msg: impl Into<DiagnosticMessage>, - ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_note_without_error(msg) + pub fn struct_note(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { + self.diagnostic().struct_note(msg) } #[inline] - pub fn diagnostic(&self) -> &rustc_errors::Handler { + pub fn diagnostic(&self) -> &Handler { &self.parse_sess.span_diagnostic } @@ -816,12 +811,7 @@ impl Session { if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } } - pub fn init_incr_comp_session( - &self, - session_dir: PathBuf, - lock_file: flock::Lock, - load_dep_graph: bool, - ) { + pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) { let mut incr_comp_session = self.incr_comp_session.borrow_mut(); if let IncrCompSession::NotInitialized = *incr_comp_session { @@ -830,7 +820,7 @@ impl Session { } *incr_comp_session = - IncrCompSession::Active { session_directory: session_dir, lock_file, load_dep_graph }; + IncrCompSession::Active { session_directory: session_dir, _lock_file: lock_file }; } pub fn finalize_incr_comp_session(&self, new_directory_path: PathBuf) { @@ -893,7 +883,7 @@ impl Session { if fuel.remaining == 0 && !fuel.out_of_fuel { if self.diagnostic().can_emit_warnings() { // We only call `msg` in case we can actually emit warnings. - // Otherwise, this could cause a `delay_good_path_bug` to + // Otherwise, this could cause a `good_path_delayed_bug` to // trigger (issue #79546). self.emit_warning(errors::OptimisationFuelExhausted { msg: msg() }); } @@ -1417,7 +1407,7 @@ pub fn build_session( ); let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle); - let mut span_diagnostic = rustc_errors::Handler::with_emitter(emitter) + let mut span_diagnostic = Handler::with_emitter(emitter) .with_flags(sopts.unstable_opts.diagnostic_handler_flags(can_emit_warnings)); if let Some(ice_file) = ice_file { span_diagnostic = span_diagnostic.with_ice_file(ice_file); @@ -1704,13 +1694,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) { /// Holds data on the current incremental compilation session, if there is one. #[derive(Debug)] -pub enum IncrCompSession { +enum IncrCompSession { /// This is the state the session will be in until the incr. comp. dir is /// needed. NotInitialized, /// This is the state during which the session directory is private and can - /// be modified. - Active { session_directory: PathBuf, lock_file: flock::Lock, load_dep_graph: bool }, + /// be modified. `_lock_file` is never directly used, but its presence + /// alone has an effect, because the file will unlock when the session is + /// dropped. + Active { session_directory: PathBuf, _lock_file: flock::Lock }, /// This is the state after the session directory has been finalized. In this /// state, the contents of the directory must not be modified any more. Finalized { session_directory: PathBuf }, @@ -1728,7 +1720,7 @@ pub struct EarlyErrorHandler { impl EarlyErrorHandler { pub fn new(output: ErrorOutputType) -> Self { let emitter = mk_emitter(output); - Self { handler: rustc_errors::Handler::with_emitter(emitter) } + Self { handler: Handler::with_emitter(emitter) } } pub fn abort_if_errors(&self) { @@ -1748,7 +1740,7 @@ impl EarlyErrorHandler { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_note(&self, msg: impl Into<DiagnosticMessage>) { - self.handler.struct_note_without_error(msg).emit() + self.handler.struct_note(msg).emit() } #[allow(rustc::untranslatable_diagnostic)] @@ -1772,7 +1764,7 @@ impl EarlyErrorHandler { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub(crate) fn early_struct_error( + pub fn early_struct_error( &self, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, !> { diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index 3ed044ad769..f76c69af526 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -158,14 +158,3 @@ pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> { if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None } } - -pub(crate) fn is_ascii_ident(string: &str) -> bool { - let mut chars = string.chars(); - if let Some(start) = chars.next() - && (start.is_ascii_alphabetic() || start == '_') - { - chars.all(|char| char.is_ascii_alphanumeric() || char == '_') - } else { - false - } -} diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index e9b835f90db..165b8c50e70 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -579,13 +579,12 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt { discr: discr.stable(tables), targets: { - let (value_vec, mut target_vec): (Vec<_>, Vec<_>) = - targets.iter().map(|(value, target)| (value, target.as_usize())).unzip(); - // We need to push otherwise as last element to ensure it's same as in MIR. - target_vec.push(targets.otherwise().as_usize()); - stable_mir::mir::SwitchTargets { value: value_vec, targets: target_vec } + let branches = targets.iter().map(|(val, target)| (val, target.as_usize())); + stable_mir::mir::SwitchTargets::new( + branches.collect(), + targets.otherwise().as_usize(), + ) }, - otherwise: targets.otherwise().as_usize(), }, mir::TerminatorKind::UnwindResume => TerminatorKind::Resume, mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 76be546e945..cc3f0962d6c 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -2247,7 +2247,7 @@ pub struct ErrorGuaranteed(()); impl ErrorGuaranteed { /// To be used only if you really know what you are doing... ideally, we would find a way to /// eliminate all calls to this method. - #[deprecated = "`Session::delay_span_bug` should be preferred over this function"] + #[deprecated = "`Session::span_delayed_bug` should be preferred over this function"] pub fn unchecked_claim_error_was_emitted() -> Self { ErrorGuaranteed(()) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9a2fe01229d..d7e822382ef 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -128,13 +128,11 @@ symbols! { AcqRel, Acquire, AddToDiagnostic, - Alignment, Any, Arc, ArcWeak, Argument, ArgumentMethods, - Arguments, ArrayIntoIter, AsMut, AsRef, @@ -164,7 +162,6 @@ symbols! { Break, C, CStr, - CString, Capture, Center, Cleanup, @@ -174,7 +171,6 @@ symbols! { Context, Continue, Copy, - Count, Cow, Debug, DebugStruct, @@ -199,7 +195,6 @@ symbols! { Fn, FnMut, FnOnce, - FormatSpec, Formatter, From, FromIterator, @@ -208,8 +203,6 @@ symbols! { FsPermissions, Future, FutureOutput, - FxHashMap, - FxHashSet, GlobalAlloc, Hash, HashMap, @@ -253,7 +246,6 @@ symbols! { NonZeroI32, NonZeroI64, NonZeroI8, - NonZeroIsize, NonZeroU128, NonZeroU16, NonZeroU32, @@ -275,7 +267,6 @@ symbols! { Path, PathBuf, Pending, - Pin, Pointer, Poll, ProcMacro, @@ -333,7 +324,6 @@ symbols! { TyCtxt, TyKind, Unknown, - UnsafeArg, Vec, VecDeque, Wrapper, @@ -389,7 +379,6 @@ symbols! { allow_fail, allow_internal_unsafe, allow_internal_unstable, - allowed, alu32, always, and, @@ -405,8 +394,6 @@ symbols! { arm, arm_target_feature, array, - arrays, - as_mut_ptr, as_ptr, as_ref, as_str, @@ -589,7 +576,6 @@ symbols! { const_try, constant, constructor, - context, convert_identity, copy, copy_closures, @@ -655,7 +641,6 @@ symbols! { default_method_body_is_const, default_type_parameter_fallback, default_type_params, - delay_span_bug_from_inside_query, deny, deprecated, deprecated_safe, @@ -776,8 +761,6 @@ symbols! { field, field_init_shorthand, file, - fill, - flags, float, float_to_int_unchecked, floorf32, @@ -950,6 +933,7 @@ symbols! { likely, line, link, + link_arg_attribute, link_args, link_cfg, link_llvm_intrinsics, @@ -1059,7 +1043,6 @@ symbols! { mir_unwind_unreachable, mir_variant, miri, - misc, mmx_reg, modifiers, module, @@ -1157,9 +1140,7 @@ symbols! { omit_gdb_pretty_printer_section, on, on_unimplemented, - oom, opaque, - ops, opt_out_copy, optimize, optimize_attribute, @@ -1217,7 +1198,6 @@ symbols! { pointer, pointer_like, poll, - position, post_dash_lto: "post-lto", powerpc_target_feature, powf32, @@ -1226,7 +1206,6 @@ symbols! { powif64, pre_dash_lto: "pre-lto", precise_pointer_size_matching, - precision, pref_align_of, prefetch_read_data, prefetch_read_instruction, @@ -1236,7 +1215,6 @@ symbols! { prelude, prelude_import, preserves_flags, - primitive, print_macro, println_macro, proc_dash_macro: "proc-macro", @@ -1260,7 +1238,6 @@ symbols! { ptr_const_is_null, ptr_copy, ptr_copy_nonoverlapping, - ptr_drop_in_place, ptr_eq, ptr_from_ref, ptr_guaranteed_cmp, @@ -1579,6 +1556,7 @@ symbols! { slice_patterns, slicing_syntax, soft, + span_delayed_bug_from_inside_query, specialization, speed, spotlight, @@ -1622,7 +1600,6 @@ symbols! { structural_match, structural_peq, structural_teq, - sty, sub, sub_assign, sub_with_overflow, @@ -1744,7 +1721,6 @@ symbols! { unrestricted_attribute_tokens, unsafe_block_in_unsafe_fn, unsafe_cell, - unsafe_cell_from_mut, unsafe_cell_raw_get, unsafe_no_drop_flag, unsafe_pin_internals, @@ -1769,7 +1745,6 @@ symbols! { used_with_arg, using, usize, - v1, va_arg, va_copy, va_end, @@ -1801,7 +1776,6 @@ symbols! { wasm_import_module, wasm_target_feature, while_let, - width, windows, windows_subsystem, with_negative_coherence, diff --git a/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs b/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs index 37bbf32c768..03823569669 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs @@ -196,7 +196,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { }; let error_response = |ecx: &mut EvalCtxt<'_, 'tcx>, reason| { - let guar = tcx.sess.delay_span_bug(tcx.def_span(assoc_def.item.def_id), reason); + let guar = tcx.sess.span_delayed_bug(tcx.def_span(assoc_def.item.def_id), reason); let error_term = match assoc_def.item.kind { ty::AssocKind::Const => ty::Const::new_error( tcx, @@ -286,7 +286,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - ecx.tcx().sess.delay_span_bug( + ecx.tcx().sess.span_delayed_bug( ecx.tcx().def_span(goal.predicate.def_id()), "associated types not allowed on auto traits", ); diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 62ab1e1049b..aee51320792 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -65,7 +65,7 @@ pub fn is_const_evaluatable<'tcx>( // FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but // currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it // is evaluatable or not. For now we just ICE until this is implemented. - Err(NotConstEvaluatable::Error(tcx.sess.delay_span_bug( + Err(NotConstEvaluatable::Error(tcx.sess.span_delayed_bug( span, "evaluating `ConstKind::Expr` is not currently supported", ))) @@ -74,7 +74,7 @@ pub fn is_const_evaluatable<'tcx>( let concrete = infcx.const_eval_resolve(param_env, uv, Some(span)); match concrete { Err(ErrorHandled::TooGeneric(_)) => { - Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug( + Err(NotConstEvaluatable::Error(infcx.tcx.sess.span_delayed_bug( span, "Missing value for constant, but no error reported?", ))) @@ -138,10 +138,10 @@ pub fn is_const_evaluatable<'tcx>( } else if uv.has_non_region_param() { NotConstEvaluatable::MentionsParam } else { - let guar = infcx - .tcx - .sess - .delay_span_bug(span, "Missing value for constant, but no error reported?"); + let guar = infcx.tcx.sess.span_delayed_bug( + span, + "Missing value for constant, but no error reported?", + ); NotConstEvaluatable::Error(guar) }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index feeeaa51f81..ba019c4ff6f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -677,8 +677,9 @@ impl<'tcx> OnUnimplementedDirective { Ok(None) } else { - let reported = - tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); + let reported = tcx + .sess + .span_delayed_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); return Err(reported); }; debug!("of_item({:?}) = {:?}", item_def_id, result); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index e4cb99727fc..d5e1efb9663 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -17,7 +17,7 @@ use rustc_errors::{ ErrorGuaranteed, MultiSpan, Style, SuggestionStyle, }; use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::is_range_literal; @@ -36,7 +36,7 @@ use rustc_middle::ty::{ TypeSuperFoldable, TypeVisitableExt, TypeckResults, }; use rustc_span::def_id::LocalDefId; -use rustc_span::symbol::{sym, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP}; use rustc_target::spec::abi; use std::borrow::Cow; @@ -222,6 +222,15 @@ pub trait TypeErrCtxtExt<'tcx> { param_env: ty::ParamEnv<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; + fn note_conflicting_fn_args( + &self, + err: &mut Diagnostic, + cause: &ObligationCauseCode<'tcx>, + expected: Ty<'tcx>, + found: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ); + fn note_conflicting_closure_bounds( &self, cause: &ObligationCauseCode<'tcx>, @@ -1034,7 +1043,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind else { return; }; - let hir::def::Res::Local(hir_id) = path.res else { + let Res::Local(hir_id) = path.res else { return; }; let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else { @@ -1618,7 +1627,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind - && let hir::def::Res::Local(hir_id) = path.res + && let Res::Local(hir_id) = path.res && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id) && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id) && let None = local.ty @@ -2005,6 +2014,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let signature_kind = format!("{argument_kind} signature"); err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str); + self.note_conflicting_fn_args(&mut err, cause, expected, found, param_env); self.note_conflicting_closure_bounds(cause, &mut err); if let Some(found_node) = found_node { @@ -2014,6 +2024,151 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err } + fn note_conflicting_fn_args( + &self, + err: &mut Diagnostic, + cause: &ObligationCauseCode<'tcx>, + expected: Ty<'tcx>, + found: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) { + let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = cause else { + return; + }; + let ty::FnPtr(expected) = expected.kind() else { + return; + }; + let ty::FnPtr(found) = found.kind() else { + return; + }; + let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) else { + return; + }; + let hir::ExprKind::Path(path) = arg.kind else { + return; + }; + let expected_inputs = self.tcx.instantiate_bound_regions_with_erased(*expected).inputs(); + let found_inputs = self.tcx.instantiate_bound_regions_with_erased(*found).inputs(); + let both_tys = expected_inputs.iter().copied().zip(found_inputs.iter().copied()); + + let arg_expr = |infcx: &InferCtxt<'tcx>, name, expected: Ty<'tcx>, found: Ty<'tcx>| { + let (expected_ty, expected_refs) = get_deref_type_and_refs(expected); + let (found_ty, found_refs) = get_deref_type_and_refs(found); + + if infcx.can_eq(param_env, found_ty, expected_ty) { + if found_refs.len() == expected_refs.len() + && found_refs.iter().eq(expected_refs.iter()) + { + name + } else if found_refs.len() > expected_refs.len() { + let refs = &found_refs[..found_refs.len() - expected_refs.len()]; + if found_refs[..expected_refs.len()].iter().eq(expected_refs.iter()) { + format!( + "{}{name}", + refs.iter() + .map(|mutbl| format!("&{}", mutbl.prefix_str())) + .collect::<Vec<_>>() + .join(""), + ) + } else { + // The refs have different mutability. + format!( + "{}*{name}", + refs.iter() + .map(|mutbl| format!("&{}", mutbl.prefix_str())) + .collect::<Vec<_>>() + .join(""), + ) + } + } else if expected_refs.len() > found_refs.len() { + format!( + "{}{name}", + (0..(expected_refs.len() - found_refs.len())) + .map(|_| "*") + .collect::<Vec<_>>() + .join(""), + ) + } else { + format!( + "{}{name}", + found_refs + .iter() + .map(|mutbl| format!("&{}", mutbl.prefix_str())) + .chain(found_refs.iter().map(|_| "*".to_string())) + .collect::<Vec<_>>() + .join(""), + ) + } + } else { + format!("/* {found} */") + } + }; + let args_have_same_underlying_type = both_tys.clone().all(|(expected, found)| { + let (expected_ty, _) = get_deref_type_and_refs(expected); + let (found_ty, _) = get_deref_type_and_refs(found); + self.can_eq(param_env, found_ty, expected_ty) + }); + let (closure_names, call_names): (Vec<_>, Vec<_>) = if args_have_same_underlying_type + && !expected_inputs.is_empty() + && expected_inputs.len() == found_inputs.len() + && let Some(typeck) = &self.typeck_results + && let Res::Def(_, fn_def_id) = typeck.qpath_res(&path, *arg_hir_id) + { + let closure: Vec<_> = self + .tcx + .fn_arg_names(fn_def_id) + .iter() + .enumerate() + .map(|(i, ident)| { + if ident.name.is_empty() || ident.name == kw::SelfLower { + format!("arg{i}") + } else { + format!("{ident}") + } + }) + .collect(); + let args = closure + .iter() + .zip(both_tys) + .map(|(name, (expected, found))| { + arg_expr(self.infcx, name.to_owned(), expected, found) + }) + .collect(); + (closure, args) + } else { + let closure_args = expected_inputs + .iter() + .enumerate() + .map(|(i, _)| format!("arg{i}")) + .collect::<Vec<_>>(); + let call_args = both_tys + .enumerate() + .map(|(i, (expected, found))| { + arg_expr(self.infcx, format!("arg{i}"), expected, found) + }) + .collect::<Vec<_>>(); + (closure_args, call_args) + }; + let closure_names: Vec<_> = closure_names + .into_iter() + .zip(expected_inputs.iter()) + .map(|(name, ty)| { + format!( + "{name}{}", + if ty.has_infer_types() { String::new() } else { format!(": {ty}") } + ) + }) + .collect(); + err.multipart_suggestion( + format!("consider wrapping the function in a closure"), + vec![ + (arg.span.shrink_to_lo(), format!("|{}| ", closure_names.join(", "))), + (arg.span.shrink_to_hi(), format!("({})", call_names.join(", "))), + ], + Applicability::MaybeIncorrect, + ); + } + // Add a note if there are two `Fn`-family bounds that have conflicting argument // requirements, which will always cause a closure to have a type error. fn note_conflicting_closure_bounds( @@ -3634,7 +3789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind - && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path + && let hir::Path { res: Res::Local(hir_id), .. } = path && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id) && let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id) @@ -3894,7 +4049,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind - && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path + && let hir::Path { res: Res::Local(hir_id), .. } = path && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id) { @@ -4349,17 +4504,6 @@ fn hint_missing_borrow<'tcx>( let args = fn_decl.inputs.iter(); - fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) { - let mut refs = vec![]; - - while let ty::Ref(_, new_ty, mutbl) = ty.kind() { - ty = *new_ty; - refs.push(*mutbl); - } - - (ty, refs) - } - let mut to_borrow = Vec::new(); let mut remove_borrow = Vec::new(); @@ -4519,7 +4663,7 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> { fn visit_ty(&mut self, t: &'hir hir::Ty<'hir>) { if let hir::TyKind::Path(hir::QPath::Resolved( None, - hir::Path { res: hir::def::Res::Def(_, segment_did), .. }, + hir::Path { res: Res::Def(_, segment_did), .. }, )) = t.kind { if self.param_did == *segment_did { @@ -4652,3 +4796,14 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>( Some(sugg) } + +fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) { + let mut refs = vec![]; + + while let ty::Ref(_, new_ty, mutbl) = ty.kind() { + ty = *new_ty; + refs.push(*mutbl); + } + + (ty, refs) +} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index b28bff1ca2a..b3910a2770b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -218,7 +218,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fulfillment errors") + self.tcx.sess.span_delayed_bug(DUMMY_SP, "expected fulfillment errors") } /// Reports that an overflow has occurred and halts compilation. We @@ -369,7 +369,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut span = obligation.cause.span; // FIXME: statically guarantee this by tainting after the diagnostic is emitted self.set_tainted_by_errors( - tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"), + tcx.sess.span_delayed_bug(span, "`report_selection_error` did not emit an error"), ); let mut err = match *error { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 08544b4a93a..fd39fce9dd1 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,4 +1,5 @@ use crate::infer::{InferCtxt, TyOrConstInferVar}; +use crate::traits::error_reporting::TypeErrCtxtExt; use rustc_data_structures::captures::Captures; use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; @@ -410,6 +411,29 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } + ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, + ty::PredicateKind::AliasRelate(..) => { + bug!("AliasRelate is only used for new solver") + } + + // General case overflow check. Allow `process_trait_obligation` + // and `process_projection_obligation` to handle checking for + // the recursion limit themselves. Also don't check some + // predicate kinds that don't give further obligations. + _ if !self + .selcx + .tcx() + .recursion_limit() + .value_within_limit(obligation.recursion_depth) => + { + self.selcx.infcx.err_ctxt().report_overflow_error( + &obligation.predicate, + obligation.cause.span, + false, + |_| {}, + ); + } + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { match wf::obligations( self.selcx.infcx, @@ -440,7 +464,12 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)]; ProcessResult::Unchanged } - Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)), + Ok(Ok(mut ok)) => { + for subobligation in &mut ok.obligations { + subobligation.set_depth_from_parent(obligation.recursion_depth); + } + ProcessResult::Changed(mk_pending(ok.obligations)) + } Ok(Err(err)) => { let expected_found = ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b); @@ -611,10 +640,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } } - ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, - ty::PredicateKind::AliasRelate(..) => { - bug!("AliasRelate is only used for new solver") - } ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( DefineOpaqueTypes::No, diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index ab07b10c65f..2f2411310a9 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -173,7 +173,7 @@ pub fn all_fields_implement_trait<'tcx>( // between expected and found const-generic types. Don't report an // additional copy error here, since it's not typically useful. if !normalization_errors.is_empty() || ty.references_error() { - tcx.sess.delay_span_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking {tr} implementation", tr = tcx.def_path_str(trait_def_id))); + tcx.sess.span_delayed_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking {tr} implementation", tr = tcx.def_path_str(trait_def_id))); continue; } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 2c004c65929..64d2b5fc159 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -215,7 +215,7 @@ fn do_normalize_predicates<'tcx>( // the normalized predicates. let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( span, format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"), ); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8268273884d..fbde7455145 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -509,7 +509,7 @@ fn virtual_call_violations_for_method<'tcx>( Ok(layout) => Some(layout.abi), Err(err) => { // #78372 - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( tcx.def_span(method.def_id), format!("error: {err}\n while computing layout for type {ty:?}"), ); @@ -525,7 +525,7 @@ fn virtual_call_violations_for_method<'tcx>( match abi_of_ty(unit_receiver_ty) { Some(Abi::Scalar(..)) => (), abi => { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( tcx.def_span(method.def_id), format!( "receiver when `Self = ()` should have a Scalar ABI; found {abi:?}" @@ -543,7 +543,7 @@ fn virtual_call_violations_for_method<'tcx>( match abi_of_ty(trait_object_receiver) { Some(Abi::ScalarPair(..)) => (), abi => { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( tcx.def_span(method.def_id), format!( "receiver when `Self = {trait_object_ty}` should have a ScalarPair ABI; found {abi:?}" @@ -597,7 +597,7 @@ fn virtual_call_violations_for_method<'tcx>( if pred_trait_ref.args.len() != 1 { tcx.sess .diagnostic() - .delay_span_bug(span, "auto traits cannot have generic parameters"); + .span_delayed_bug(span, "auto traits cannot have generic parameters"); } return false; } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 1c2966bb3e5..7513f88cfc3 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -111,7 +111,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { let errors = ocx.select_all_or_error(); if !errors.is_empty() { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( span, "implied_outlives_bounds failed to solve obligations from instantiation", ); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 3be14951703..45bdff09dee 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1469,7 +1469,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>( match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) { Ok(mut ok) => obligations.append(&mut ok.obligations), Err(_) => { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( cause.span, format!( "{self_ty:?} was a subtype of {impl_ty:?} during selection but now it is not" @@ -1974,7 +1974,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) | ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => { // These traits have no associated types. - selcx.tcx().sess.delay_span_bug( + selcx.tcx().sess.span_delayed_bug( obligation.cause.span, format!("Cannot project an associated type from `{impl_source:?}`"), ); diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 06d41243e75..ec80df1d658 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -237,7 +237,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( // By the time this code runs, all type variables ought to // be fully resolved. - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( span, format!("upvar_tys for closure not found. Expected capture information for closure {ty}",), ); @@ -286,7 +286,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( if !args.is_valid() { // By the time this code runs, all type variables ought to // be fully resolved. - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( span, format!("upvar_tys for coroutine not found. Expected capture information for coroutine {ty}",), ); diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 8faaa6be9f5..4728fcf3301 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -292,7 +292,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> // Rustdoc normalizes possibly not well-formed types, so only // treat this as a bug if we're not in rustdoc. if !tcx.sess.opts.actually_rustdoc { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( DUMMY_SP, format!("unexpected ambiguity: {c_data:?} {result:?}"), ); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index c81bc579003..18bb56ba4eb 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -82,13 +82,13 @@ where let value = infcx.commit_if_ok(|_| { let ocx = ObligationCtxt::new(infcx); let value = op(&ocx).map_err(|_| { - infcx.tcx.sess.delay_span_bug(span, format!("error performing operation: {name}")) + infcx.tcx.sess.span_delayed_bug(span, format!("error performing operation: {name}")) })?; let errors = ocx.select_all_or_error(); if errors.is_empty() { Ok(value) } else { - Err(infcx.tcx.sess.delay_span_bug( + Err(infcx.tcx.sess.span_delayed_bug( DUMMY_SP, format!("errors selecting obligation during MIR typeck: {errors:?}"), )) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index a5ccf62608e..e87e585ef0b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -160,14 +160,14 @@ where let (output, error_info, mut obligations) = Q::fully_perform_into(self, infcx, &mut region_constraints) .map_err(|_| { - infcx.tcx.sess.delay_span_bug(span, format!("error performing {self:?}")) + infcx.tcx.sess.span_delayed_bug(span, format!("error performing {self:?}")) }) .and_then(|(output, error_info, obligations, certainty)| match certainty { Certainty::Proven => Ok((output, error_info, obligations)), Certainty::Ambiguous => Err(infcx .tcx .sess - .delay_span_bug(span, format!("ambiguity performing {self:?}"))), + .span_delayed_bug(span, format!("ambiguity performing {self:?}"))), })?; // Typically, instantiating NLL query results does not @@ -196,7 +196,7 @@ where } } if !progress { - return Err(infcx.tcx.sess.delay_span_bug( + return Err(infcx.tcx.sess.span_delayed_bug( span, format!("ambiguity processing {obligations:?} from {self:?}"), )); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4763a906172..a33160b7c43 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -553,7 +553,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let defs: &ty::Generics = tcx.generics_of(assoc_type); if !defs.params.is_empty() && !tcx.features().generic_associated_types_extended { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( obligation.cause.span, "GATs in trait object shouldn't have been considered", ); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0c884b7c16a..b26c781100a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2419,7 +2419,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // the placeholder trait ref may fail due the Generalizer relation // raising a CyclicalTy error due to a sub_root_var relation // for a variable being generalized... - let guar = self.infcx.tcx.sess.delay_span_bug( + let guar = self.infcx.tcx.sess.span_delayed_bug( obligation.cause.span, format!( "Impl {impl_def_id:?} was matchable against {obligation:?} but now is not" diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 73ba03a3610..56f5057608f 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -202,7 +202,7 @@ fn fulfill_implication<'tcx>( { Ok(source_trait_ref) => source_trait_ref, Err(_errors) => { - infcx.tcx.sess.delay_span_bug( + infcx.tcx.sess.span_delayed_bug( infcx.tcx.def_span(source_impl), format!("failed to fully normalize {source_trait_ref}"), ); @@ -431,7 +431,10 @@ fn report_conflicting_impls<'tcx>( decorate(tcx, &overlap, impl_span, &mut err); Some(err.emit()) } else { - Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check")) + Some( + tcx.sess + .span_delayed_bug(impl_span, "impl should have failed the orphan check"), + ) }; sg.has_errored = reported; } diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 5960415a88d..f8e47caccb7 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -135,7 +135,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> { bug!("unexpected type during structural-match checking: {:?}", ty); } ty::Error(_) => { - self.tcx.sess.delay_span_bug(self.span, "ty::Error in structural-match check"); + self.tcx.sess.span_delayed_bug(self.span, "ty::Error in structural-match check"); // We still want to check other types after encountering an error, // as this may still emit relevant errors. return ControlFlow::Continue(()); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 31f6a56eaeb..a0f01d9eca9 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -79,7 +79,7 @@ fn resolve_associated_item<'tcx>( let vtbl = match tcx.codegen_select_candidate((param_env, trait_ref)) { Ok(vtbl) => vtbl, Err(CodegenObligationError::Ambiguity) => { - let reported = tcx.sess.delay_span_bug( + let reported = tcx.sess.span_delayed_bug( tcx.def_span(trait_item_id), format!( "encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \ @@ -171,7 +171,7 @@ fn resolve_associated_item<'tcx>( // Any final impl is required to define all associated items. if !leaf_def.item.defaultness(tcx).has_value() { - let guard = tcx.sess.delay_span_bug( + let guard = tcx.sess.span_delayed_bug( tcx.def_span(leaf_def.item.def_id), "missing value for assoc item in impl", ); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 826c69ee716..7599aa9fa41 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -93,7 +93,7 @@ fn univariant_uninterned<'tcx>( let dl = cx.data_layout(); let pack = repr.pack; if pack.is_some() && repr.align.is_some() { - cx.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned"); + cx.tcx.sess.span_delayed_bug(DUMMY_SP, "struct cannot be packed and aligned"); return Err(cx.tcx.arena.alloc(LayoutError::Unknown(ty))); } @@ -346,7 +346,7 @@ fn layout_of_uncached<'tcx>( ty::Adt(def, args) if def.repr().simd() => { if !def.is_struct() { // Should have yielded E0517 by now. - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( DUMMY_SP, "#[repr(simd)] was applied to an ADT that is not a struct", ); @@ -376,7 +376,7 @@ fn layout_of_uncached<'tcx>( // (should be caught by typeck) for fi in fields { if fi.ty(tcx, args) != f0_ty { - tcx.sess.delay_span_bug( + tcx.sess.span_delayed_bug( DUMMY_SP, "#[repr(simd)] was applied to an ADT with heterogeneous field type", ); @@ -473,7 +473,7 @@ fn layout_of_uncached<'tcx>( if def.is_union() { if def.repr().pack.is_some() && def.repr().align.is_some() { - cx.tcx.sess.delay_span_bug( + cx.tcx.sess.span_delayed_bug( tcx.def_span(def.did()), "union cannot be packed and aligned", ); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 16f5ed09d00..db43c31ccab 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -238,7 +238,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { .instantiate(self.tcx, impl_args) .visit_with(self); } else { - self.tcx.sess.delay_span_bug( + self.tcx.sess.span_delayed_bug( self.tcx.def_span(assoc.def_id), "item had incorrect args", ); diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 02a28687676..3a4f4283562 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -3,7 +3,7 @@ use crate::ty::{ AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind, }; use crate::{Error, Opaque, Span, Symbol}; -use std::{io, slice}; +use std::io; /// The SMIR representation of a single function. #[derive(Clone, Debug)] pub struct Body { @@ -23,6 +23,8 @@ pub struct Body { pub(super) var_debug_info: Vec<VarDebugInfo>, } +pub type BasicBlockIdx = usize; + impl Body { /// Constructs a `Body`. /// @@ -114,22 +116,21 @@ pub struct Terminator { } impl Terminator { - pub fn successors(&self) -> Successors<'_> { + pub fn successors(&self) -> Successors { self.kind.successors() } } -pub type Successors<'a> = impl Iterator<Item = usize> + 'a; +pub type Successors = Vec<BasicBlockIdx>; #[derive(Clone, Debug, Eq, PartialEq)] pub enum TerminatorKind { Goto { - target: usize, + target: BasicBlockIdx, }, SwitchInt { discr: Operand, targets: SwitchTargets, - otherwise: usize, }, Resume, Abort, @@ -137,43 +138,42 @@ pub enum TerminatorKind { Unreachable, Drop { place: Place, - target: usize, + target: BasicBlockIdx, unwind: UnwindAction, }, Call { func: Operand, args: Vec<Operand>, destination: Place, - target: Option<usize>, + target: Option<BasicBlockIdx>, unwind: UnwindAction, }, Assert { cond: Operand, expected: bool, msg: AssertMessage, - target: usize, + target: BasicBlockIdx, unwind: UnwindAction, }, - CoroutineDrop, InlineAsm { template: String, operands: Vec<InlineAsmOperand>, options: String, line_spans: String, - destination: Option<usize>, + destination: Option<BasicBlockIdx>, unwind: UnwindAction, }, } impl TerminatorKind { - pub fn successors(&self) -> Successors<'_> { + pub fn successors(&self) -> Successors { use self::TerminatorKind::*; match *self { - Call { target: Some(t), unwind: UnwindAction::Cleanup(ref u), .. } - | Drop { target: t, unwind: UnwindAction::Cleanup(ref u), .. } - | Assert { target: t, unwind: UnwindAction::Cleanup(ref u), .. } - | InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(ref u), .. } => { - Some(t).into_iter().chain(slice::from_ref(u).into_iter().copied()) + Call { target: Some(t), unwind: UnwindAction::Cleanup(u), .. } + | Drop { target: t, unwind: UnwindAction::Cleanup(u), .. } + | Assert { target: t, unwind: UnwindAction::Cleanup(u), .. } + | InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(u), .. } => { + vec![t, u] } Goto { target: t } | Call { target: None, unwind: UnwindAction::Cleanup(t), .. } @@ -182,21 +182,18 @@ impl TerminatorKind { | Assert { target: t, unwind: _, .. } | InlineAsm { destination: None, unwind: UnwindAction::Cleanup(t), .. } | InlineAsm { destination: Some(t), unwind: _, .. } => { - Some(t).into_iter().chain((&[]).into_iter().copied()) + vec![t] } - CoroutineDrop - | Return + Return | Resume | Abort | Unreachable | Call { target: None, unwind: _, .. } | InlineAsm { destination: None, unwind: _, .. } => { - None.into_iter().chain((&[]).into_iter().copied()) - } - SwitchInt { ref targets, .. } => { - None.into_iter().chain(targets.targets.iter().copied()) + vec![] } + SwitchInt { ref targets, .. } => targets.all_targets(), } } @@ -205,7 +202,6 @@ impl TerminatorKind { TerminatorKind::Goto { .. } | TerminatorKind::Return | TerminatorKind::Unreachable - | TerminatorKind::CoroutineDrop | TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::SwitchInt { .. } => None, @@ -231,7 +227,7 @@ pub enum UnwindAction { Continue, Unreachable, Terminate, - Cleanup(usize), + Cleanup(BasicBlockIdx), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -662,10 +658,42 @@ pub struct Constant { pub literal: Const, } +/// The possible branch sites of a [TerminatorKind::SwitchInt]. #[derive(Clone, Debug, Eq, PartialEq)] pub struct SwitchTargets { - pub value: Vec<u128>, - pub targets: Vec<usize>, + /// The conditional branches where the first element represents the value that guards this + /// branch, and the second element is the branch target. + branches: Vec<(u128, BasicBlockIdx)>, + /// The `otherwise` branch which will be taken in case none of the conditional branches are + /// satisfied. + otherwise: BasicBlockIdx, +} + +impl SwitchTargets { + /// All possible targets including the `otherwise` target. + pub fn all_targets(&self) -> Successors { + self.branches.iter().map(|(_, target)| *target).chain(Some(self.otherwise)).collect() + } + + /// The `otherwise` branch target. + pub fn otherwise(&self) -> BasicBlockIdx { + self.otherwise + } + + /// The conditional targets which are only taken if the pattern matches the given value. + pub fn branches(&self) -> impl Iterator<Item = (u128, BasicBlockIdx)> + '_ { + self.branches.iter().copied() + } + + /// The number of targets including `otherwise`. + pub fn len(&self) -> usize { + self.branches.len() + 1 + } + + /// Create a new SwitchTargets from the given branches and `otherwise` target. + pub fn new(branches: Vec<(u128, BasicBlockIdx)>, otherwise: BasicBlockIdx) -> SwitchTargets { + SwitchTargets { branches, otherwise } + } } #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 759c3b148df..3a0eed521dc 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -76,7 +76,8 @@ pub fn pretty_statement(statement: &StatementKind) -> String { pub fn pretty_terminator<W: io::Write>(terminator: &TerminatorKind, w: &mut W) -> io::Result<()> { write!(w, "{}", pretty_terminator_head(terminator))?; - let successor_count = terminator.successors().count(); + let successors = terminator.successors(); + let successor_count = successors.len(); let labels = pretty_successor_labels(terminator); let show_unwind = !matches!(terminator.unwind(), None | Some(UnwindAction::Cleanup(_))); @@ -98,12 +99,12 @@ pub fn pretty_terminator<W: io::Write>(terminator: &TerminatorKind, w: &mut W) - Ok(()) } (1, false) => { - write!(w, " -> {:?}", terminator.successors().next().unwrap())?; + write!(w, " -> {:?}", successors[0])?; Ok(()) } _ => { write!(w, " -> [")?; - for (i, target) in terminator.successors().enumerate() { + for (i, target) in successors.iter().enumerate() { if i > 0 { write!(w, ", ")?; } @@ -157,7 +158,6 @@ pub fn pretty_terminator_head(terminator: &TerminatorKind) -> String { pretty.push_str(")"); pretty } - CoroutineDrop => format!(" coroutine_drop"), InlineAsm { .. } => todo!(), } } @@ -165,12 +165,11 @@ pub fn pretty_terminator_head(terminator: &TerminatorKind) -> String { pub fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec<String> { use self::TerminatorKind::*; match terminator { - Resume | Abort | Return | Unreachable | CoroutineDrop => vec![], + Resume | Abort | Return | Unreachable => vec![], Goto { .. } => vec!["".to_string()], SwitchInt { targets, .. } => targets - .value - .iter() - .map(|target| format!("{}", target)) + .branches() + .map(|(val, _target)| format!("{val}")) .chain(iter::once("otherwise".into())) .collect(), Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()], diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index 69bf6ca72b0..0c44781c463 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -237,8 +237,7 @@ pub trait MirVisitor { TerminatorKind::Goto { .. } | TerminatorKind::Resume | TerminatorKind::Abort - | TerminatorKind::Unreachable - | TerminatorKind::CoroutineDrop => {} + | TerminatorKind::Unreachable => {} TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.visit_operand(cond, location); self.visit_assert_msg(msg, location); @@ -268,7 +267,7 @@ pub trait MirVisitor { let local = RETURN_LOCAL; self.visit_local(&local, PlaceContext::NON_MUTATING, location); } - TerminatorKind::SwitchInt { discr, targets: _, otherwise: _ } => { + TerminatorKind::SwitchInt { discr, targets: _ } => { self.visit_operand(discr, location); } } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 547a7b7052f..3b6fbf95faf 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -74,7 +74,7 @@ macro_rules! error_contains { // tests most of the time, but at least we do if the user has the right // permissions. pub fn got_symlink_permission(tmpdir: &TempDir) -> bool { - if cfg!(unix) { + if cfg!(not(windows)) || env::var_os("CI").is_some() { return true; } let link = tmpdir.join("some_hopefully_unique_link_name"); diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index aaddf5ca09c..65af2aed6de 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -10,6 +10,7 @@ use std::io::{BufRead, BufReader}; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::process::Command; +use std::sync::OnceLock; use std::time::{Duration, Instant}; use crate::core::build_steps::llvm; @@ -25,12 +26,10 @@ use crate::EXTRA_CHECK_CFGS; use crate::{Build, CLang, DocTests, GitRepo, Mode}; pub use crate::Compiler; -// FIXME: -// - use std::lazy for `Lazy` -// - use std::cell for `OnceCell` -// Once they get stabilized and reach beta. + use clap::ValueEnum; -use once_cell::sync::{Lazy, OnceCell}; +// FIXME: replace with std::lazy after it gets stabilized and reaches beta +use once_cell::sync::Lazy; #[cfg(test)] #[path = "../tests/builder.rs"] @@ -496,7 +495,7 @@ impl<'a> ShouldRun<'a> { /// /// [`path`]: ShouldRun::path pub fn paths(mut self, paths: &[&str]) -> Self { - static SUBMODULES_PATHS: OnceCell<Vec<String>> = OnceCell::new(); + static SUBMODULES_PATHS: OnceLock<Vec<String>> = OnceLock::new(); let init_submodules_paths = |src: &PathBuf| { let file = File::open(src.join(".gitmodules")).unwrap(); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 9ef90798590..22e8ce8365b 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -17,6 +17,7 @@ use std::io::IsTerminal; use std::path::{Path, PathBuf}; use std::process::Command; use std::str::FromStr; +use std::sync::OnceLock; use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX; use crate::core::build_steps::llvm; @@ -25,7 +26,6 @@ use crate::utils::cache::{Interned, INTERNER}; use crate::utils::channel::{self, GitInfo}; use crate::utils::helpers::{exe, output, t}; use build_helper::exit; -use once_cell::sync::OnceCell; use semver::Version; use serde::{Deserialize, Deserializer}; use serde_derive::Deserialize; @@ -1907,7 +1907,7 @@ impl Config { } pub(crate) fn download_rustc_commit(&self) -> Option<&str> { - static DOWNLOAD_RUSTC: OnceCell<Option<String>> = OnceCell::new(); + static DOWNLOAD_RUSTC: OnceLock<Option<String>> = OnceLock::new(); if self.dry_run() && DOWNLOAD_RUSTC.get().is_none() { // avoid trying to actually download the commit return self.download_rustc_commit.as_deref(); diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 3327aed9600..0a5844a6859 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -5,10 +5,10 @@ use std::{ io::{BufRead, BufReader, BufWriter, ErrorKind, Write}, path::{Path, PathBuf}, process::{Command, Stdio}, + sync::OnceLock, }; use build_helper::ci::CiEnv; -use once_cell::sync::OnceCell; use xz2::bufread::XzDecoder; use crate::core::build_steps::llvm::detect_llvm_sha; @@ -16,7 +16,7 @@ use crate::core::config::RustfmtMetadata; use crate::utils::helpers::{check_run, exe, program_out_of_date}; use crate::{t, Config}; -static SHOULD_FIX_BINS_AND_DYLIBS: OnceCell<bool> = OnceCell::new(); +static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new(); /// `Config::try_run` wrapper for this module to avoid warnings on `try_run`, since we don't have access to a `builder` yet. fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> { @@ -131,7 +131,7 @@ impl Config { println!("attempting to patch {}", fname.display()); // Only build `.nix-deps` once. - static NIX_DEPS_DIR: OnceCell<PathBuf> = OnceCell::new(); + static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new(); let mut nix_build_succeeded = true; let nix_deps_dir = NIX_DEPS_DIR.get_or_init(|| { // Run `nix-build` to "build" each dependency (which will likely reuse diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 480dd757915..60a89e9bf07 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -25,12 +25,12 @@ use std::io; use std::path::{Path, PathBuf}; use std::process::{Command, Output, Stdio}; use std::str; +use std::sync::OnceLock; use build_helper::ci::{gha, CiEnv}; use build_helper::exit; use build_helper::util::fail; use filetime::FileTime; -use once_cell::sync::OnceCell; use sha2::digest::Digest; use termcolor::{ColorChoice, StandardStream, WriteColor}; use utils::channel::GitInfo; @@ -906,7 +906,7 @@ impl Build { /// Returns the sysroot of the snapshot compiler. fn rustc_snapshot_sysroot(&self) -> &Path { - static SYSROOT_CACHE: OnceCell<PathBuf> = once_cell::sync::OnceCell::new(); + static SYSROOT_CACHE: OnceLock<PathBuf> = OnceLock::new(); SYSROOT_CACHE.get_or_init(|| { let mut rustc = Command::new(&self.initial_rustc); rustc.args(&["--print", "sysroot"]); diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 89fa2b805cd..f878d634743 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -11,11 +11,11 @@ use std::io; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; +use std::sync::OnceLock; use std::time::{Instant, SystemTime, UNIX_EPOCH}; use crate::core::builder::Builder; use crate::core::config::{Config, TargetSelection}; -use crate::OnceCell; pub use crate::utils::dylib::{dylib_path, dylib_path_var}; @@ -444,7 +444,7 @@ pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf { } pub fn lld_flag_no_threads(is_windows: bool) -> &'static str { - static LLD_NO_THREADS: OnceCell<(&'static str, &'static str)> = OnceCell::new(); + static LLD_NO_THREADS: OnceLock<(&'static str, &'static str)> = OnceLock::new(); let (windows, other) = LLD_NO_THREADS.get_or_init(|| { let out = output(Command::new("lld").arg("-flavor").arg("ld").arg("--version")); let newer = match (out.find(char::is_numeric), out.find('.')) { diff --git a/src/doc/unstable-book/src/language-features/link-arg-attribute.md b/src/doc/unstable-book/src/language-features/link-arg-attribute.md new file mode 100644 index 00000000000..09915a7f274 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/link-arg-attribute.md @@ -0,0 +1,21 @@ +# `link_arg_attribute` + +The tracking issue for this feature is: [#99427] + +------ + +The `link_arg_attribute` feature allows passing arguments into the linker +from inside of the source code. Order is preserved for link attributes as +they were defined on a single extern block: + +```rust,no_run +#![feature(link_arg_attribute)] + +#[link(kind = "link-arg", name = "--start-group")] +#[link(kind = "static", name = "c")] +#[link(kind = "static", name = "gcc")] +#[link(kind = "link-arg", name = "--end-group")] +extern "C" {} +``` + +[#99427]: https://github.com/rust-lang/rust/issues/99427 diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index bed8f6ffef5..a9c0ab557cb 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -367,7 +367,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( if ending == Ending::Newline { let mut clause = " ".repeat(indent.saturating_sub(1)); - write!(clause, "<span class=\"where fmt-newline\">where{where_preds},</span>")?; + write!(clause, "<div class=\"where\">where{where_preds},</div>")?; clause } else { // insert a newline after a single space but before multiple spaces at the start diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 348d546c236..e076c1b92e6 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1145,7 +1145,7 @@ impl<'a> AssocItemLink<'a> { fn write_impl_section_heading(mut w: impl fmt::Write, title: &str, id: &str) { write!( w, - "<h2 id=\"{id}\" class=\"small-section-header\">\ + "<h2 id=\"{id}\" class=\"section-header\">\ {title}\ <a href=\"#{id}\" class=\"anchor\">§</a>\ </h2>" @@ -1441,15 +1441,10 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { ); } - //use the "where" class here to make it small - write!( - &mut out, - "<span class=\"where fmt-newline\">{}</span>", - impl_.print(false, cx) - ); + write!(&mut out, "<div class=\"where\">{}</div>", impl_.print(false, cx)); for it in &impl_.items { if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind { - out.push_str("<span class=\"where fmt-newline\"> "); + out.push_str("<div class=\"where\"> "); let empty_set = FxHashSet::default(); let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set); assoc_type( @@ -1462,7 +1457,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { 0, cx, ); - out.push_str(";</span>"); + out.push_str(";</div>"); } } } @@ -1948,7 +1943,7 @@ pub(crate) fn render_impl_summary( if show_def_docs { for it in &inner_impl.items { if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind { - w.write_str("<span class=\"where fmt-newline\"> "); + w.write_str("<div class=\"where\"> "); assoc_type( w, it, @@ -1959,7 +1954,7 @@ pub(crate) fn render_impl_summary( 0, cx, ); - w.write_str(";</span>"); + w.write_str(";</div>"); } } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 2dac943f695..e4309c782f6 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -430,7 +430,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: last_section = Some(my_section); write!( w, - "<h2 id=\"{id}\" class=\"small-section-header\">\ + "<h2 id=\"{id}\" class=\"section-header\">\ <a href=\"#{id}\">{name}</a>\ </h2>{ITEM_TABLE_OPEN}", id = cx.derive_id(my_section.id()), @@ -827,7 +827,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) { write!( w, - "<h2 id=\"{0}\" class=\"small-section-header\">\ + "<h2 id=\"{0}\" class=\"section-header\">\ {1}<a href=\"#{0}\" class=\"anchor\">§</a>\ </h2>{2}", id, title, extra_content @@ -1260,7 +1260,7 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c if let Some(inner_type) = &t.inner_type { write!( w, - "<h2 id=\"aliased-type\" class=\"small-section-header\">\ + "<h2 id=\"aliased-type\" class=\"section-header\">\ Aliased Type<a href=\"#aliased-type\" class=\"anchor\">§</a></h2>" ); @@ -1685,7 +1685,7 @@ fn item_variants( let tcx = cx.tcx(); write!( w, - "<h2 id=\"variants\" class=\"variants small-section-header\">\ + "<h2 id=\"variants\" class=\"variants section-header\">\ Variants{}<a href=\"#variants\" class=\"anchor\">§</a>\ </h2>\ {}\ @@ -1772,7 +1772,7 @@ fn item_variants( write!( w, "<div class=\"sub-variant-field\">\ - <span id=\"{id}\" class=\"small-section-header\">\ + <span id=\"{id}\" class=\"section-header\">\ <a href=\"#{id}\" class=\"anchor field\">§</a>\ <code>{f}: {t}</code>\ </span>", @@ -1929,7 +1929,7 @@ fn item_fields( if fields.peek().is_some() { write!( w, - "<h2 id=\"fields\" class=\"fields small-section-header\">\ + "<h2 id=\"fields\" class=\"fields section-header\">\ {}{}<a href=\"#fields\" class=\"anchor\">§</a>\ </h2>\ {}", @@ -1943,7 +1943,7 @@ fn item_fields( let id = cx.derive_id(format!("{typ}.{field_name}", typ = ItemType::StructField)); write!( w, - "<span id=\"{id}\" class=\"{item_type} small-section-header\">\ + "<span id=\"{id}\" class=\"{item_type} section-header\">\ <a href=\"#{id}\" class=\"anchor field\">§</a>\ <code>{field_name}: {ty}</code>\ </span>", diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 9efdcd60117..b898eb5d381 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -205,7 +205,7 @@ ul.all-items { #toggle-all-docs, a.anchor, -.small-section-header a, +.section-header a, #src-sidebar a, .rust a, .sidebar h2 a, @@ -703,11 +703,8 @@ pre, .rustdoc.src .example-wrap { background: var(--table-alt-row-background-color); } -/* Shift "where ..." part of method or fn definition down a line */ -.method .where, -.fn .where, -.where.fmt-newline { - display: block; +/* "where ..." clauses with block display are also smaller */ +div.where { white-space: pre-wrap; font-size: 0.875rem; } @@ -742,13 +739,13 @@ nav.sub { margin: 0 0 15px 0; } -.small-section-header { +.section-header { /* fields use <span> tags, but should get their own lines */ display: block; position: relative; } -.small-section-header:hover > .anchor, .impl:hover > .anchor, +.section-header:hover > .anchor, .impl:hover > .anchor, .trait-impl:hover > .anchor, .variant:hover > .anchor { display: initial; } @@ -761,11 +758,11 @@ nav.sub { .anchor.field { left: -5px; } -.small-section-header > .anchor { +.section-header > .anchor { left: -15px; padding-right: 8px; } -h2.small-section-header > .anchor { +h2.section-header > .anchor { padding-right: 6px; } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 979aebdb7be..8f68796ad26 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -287,10 +287,6 @@ function initSearch(rawSearchIndex) { } } - function isWhitespace(c) { - return " \t\n\r".indexOf(c) !== -1; - } - function isSpecialStartCharacter(c) { return "<\"".indexOf(c) !== -1; } @@ -408,7 +404,7 @@ function initSearch(rawSearchIndex) { * @return {boolean} */ function isPathSeparator(c) { - return c === ":" || isWhitespace(c); + return c === ":" || c === " "; } /** @@ -425,7 +421,7 @@ function initSearch(rawSearchIndex) { const c = parserState.userQuery[pos - 1]; if (c === lookingFor) { return true; - } else if (!isWhitespace(c)) { + } else if (c !== " ") { break; } pos -= 1; @@ -454,7 +450,7 @@ function initSearch(rawSearchIndex) { function skipWhitespace(parserState) { while (parserState.pos < parserState.userQuery.length) { const c = parserState.userQuery[parserState.pos]; - if (!isWhitespace(c)) { + if (c !== " ") { break; } parserState.pos += 1; @@ -473,8 +469,6 @@ function initSearch(rawSearchIndex) { const path = name.trim(); if (path.length === 0 && generics.length === 0) { throw ["Unexpected ", parserState.userQuery[parserState.pos]]; - } else if (path === "*") { - throw ["Unexpected ", "*"]; } if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) { throw ["Cannot have more than one element if you use quotes"]; @@ -512,18 +506,15 @@ function initSearch(rawSearchIndex) { bindingName, }; } + const quadcolon = /::\s*::/.exec(path); if (path.startsWith("::")) { throw ["Paths cannot start with ", "::"]; } else if (path.endsWith("::")) { throw ["Paths cannot end with ", "::"]; - } else if (path.includes("::::")) { - throw ["Unexpected ", "::::"]; - } else if (path.includes(" ::")) { - throw ["Unexpected ", " ::"]; - } else if (path.includes(":: ")) { - throw ["Unexpected ", ":: "]; - } - const pathSegments = path.split(/::|\s+/); + } else if (quadcolon !== null) { + throw ["Unexpected ", quadcolon[0]]; + } + const pathSegments = path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/); // In case we only have something like `<p>`, there is no name. if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) { if (generics.length > 0 || prevIs(parserState, ">")) { @@ -604,7 +595,7 @@ function initSearch(rawSearchIndex) { } else { while (parserState.pos + 1 < parserState.length) { const next_c = parserState.userQuery[parserState.pos + 1]; - if (!isWhitespace(next_c)) { + if (next_c !== " ") { break; } parserState.pos += 1; @@ -958,7 +949,7 @@ function initSearch(rawSearchIndex) { query.literalSearch = false; foundStopChar = true; continue; - } else if (isWhitespace(c)) { + } else if (c === " ") { skipWhitespace(parserState); continue; } @@ -1118,7 +1109,7 @@ function initSearch(rawSearchIndex) { } } } - userQuery = userQuery.trim(); + userQuery = userQuery.trim().replace(/\r|\n|\t/g, " "); const parserState = { length: userQuery.length, pos: 0, diff --git a/src/librustdoc/html/templates/item_union.html b/src/librustdoc/html/templates/item_union.html index f6d2fa34890..8db7986fa75 100644 --- a/src/librustdoc/html/templates/item_union.html +++ b/src/librustdoc/html/templates/item_union.html @@ -4,13 +4,13 @@ </code></pre> {{ self.document() | safe }} {% if self.fields_iter().peek().is_some() %} - <h2 id="fields" class="fields small-section-header"> {# #} + <h2 id="fields" class="fields section-header"> {# #} Fields<a href="#fields" class="anchor">§</a> {# #} </h2> {% for (field, ty) in self.fields_iter() %} {% let name = field.name.expect("union field name") %} <span id="structfield.{{ name }}" {#+ #} - class="{{ ItemType::StructField +}} small-section-header"> {# #} + class="{{ ItemType::StructField +}} section-header"> {# #} <a href="#structfield.{{ name }}" class="anchor field">§</a> {# #} <code>{{ name }}: {{+ self.print_ty(ty) | safe }}</code> {# #} </span> diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html index c75fc34a9df..e0516bb42fe 100644 --- a/src/librustdoc/html/templates/type_layout.html +++ b/src/librustdoc/html/templates/type_layout.html @@ -1,4 +1,4 @@ -<h2 id="layout" class="small-section-header"> {# #} +<h2 id="layout" class="section-header"> {# #} Layout<a href="#layout" class="anchor">§</a> {# #} </h2> {# #} <div class="docblock"> {# #} diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 1ae8ac81695..49f0cad08e0 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -183,7 +183,7 @@ pub fn main() { // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't // accept a generic closure. let version_info = rustc_tools_util::get_version_info!(); - handler.note_without_error(format!("Clippy version: {version_info}")); + handler.note(format!("Clippy version: {version_info}")); }); exit(rustc_driver::catch_with_exit_code(move || { diff --git a/src/tools/clippy/tests/integration.rs b/src/tools/clippy/tests/integration.rs index 031982edbe9..267f095f9c2 100644 --- a/src/tools/clippy/tests/integration.rs +++ b/src/tools/clippy/tests/integration.rs @@ -69,15 +69,15 @@ fn integration_test() { // debug: eprintln!("{stderr}"); - // this is an internal test to make sure we would correctly panic on a delay_span_bug + // this is an internal test to make sure we would correctly panic on a span_delayed_bug if repo_name == "matthiaskrgr/clippy_ci_panic_test" { // we need to kind of switch around our logic here: // if we find a panic, everything is fine, if we don't panic, SOMETHING is broken about our testing - // the repo basically just contains a delay_span_bug that forces rustc/clippy to panic: + // the repo basically just contains a span_delayed_bug that forces rustc/clippy to panic: /* #![feature(rustc_attrs)] - #[rustc_error(delay_span_bug_from_inside_query)] + #[rustc_error(span_delayed_bug_from_inside_query)] fn main() {} */ @@ -86,7 +86,7 @@ fn integration_test() { return; } - panic!("panic caused by delay_span_bug was NOT detected! Something is broken!"); + panic!("panic caused by span_delayed_bug was NOT detected! Something is broken!"); } if let Some(backtrace_start) = stderr.find("error: internal compiler error") { diff --git a/src/tools/clippy/tests/ui/needless_raw_string.fixed b/src/tools/clippy/tests/ui/needless_raw_string.fixed index 4ea711fd67a..1a9c601c462 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.fixed +++ b/src/tools/clippy/tests/ui/needless_raw_string.fixed @@ -1,6 +1,5 @@ #![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)] #![warn(clippy::needless_raw_strings)] -#![feature(c_str_literals)] fn main() { "aaa"; diff --git a/src/tools/clippy/tests/ui/needless_raw_string.rs b/src/tools/clippy/tests/ui/needless_raw_string.rs index b6239f9b1f0..1126ea5aa30 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.rs +++ b/src/tools/clippy/tests/ui/needless_raw_string.rs @@ -1,6 +1,5 @@ #![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)] #![warn(clippy::needless_raw_strings)] -#![feature(c_str_literals)] fn main() { r#"aaa"#; diff --git a/src/tools/clippy/tests/ui/needless_raw_string.stderr b/src/tools/clippy/tests/ui/needless_raw_string.stderr index 276bc84c6c3..b2188698564 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string.stderr +++ b/src/tools/clippy/tests/ui/needless_raw_string.stderr @@ -1,5 +1,5 @@ error: unnecessary raw string literal - --> $DIR/needless_raw_string.rs:6:5 + --> $DIR/needless_raw_string.rs:5:5 | LL | r#"aaa"#; | ^^^^^^^^ @@ -13,7 +13,7 @@ LL + "aaa"; | error: unnecessary raw string literal - --> $DIR/needless_raw_string.rs:9:5 + --> $DIR/needless_raw_string.rs:8:5 | LL | br#"aaa"#; | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL + b"aaa"; | error: unnecessary raw string literal - --> $DIR/needless_raw_string.rs:12:5 + --> $DIR/needless_raw_string.rs:11:5 | LL | cr#"aaa"#; | ^^^^^^^^^ @@ -37,7 +37,7 @@ LL + c"aaa"; | error: unnecessary raw string literal - --> $DIR/needless_raw_string.rs:16:5 + --> $DIR/needless_raw_string.rs:15:5 | LL | / r#" LL | | a @@ -56,7 +56,7 @@ LL ~ "; | error: unnecessary raw string literal - --> $DIR/needless_raw_string.rs:22:5 + --> $DIR/needless_raw_string.rs:21:5 | LL | r"no hashes"; | ^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + "no hashes"; | error: unnecessary raw string literal - --> $DIR/needless_raw_string.rs:23:5 + --> $DIR/needless_raw_string.rs:22:5 | LL | br"no hashes"; | ^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL + b"no hashes"; | error: unnecessary raw string literal - --> $DIR/needless_raw_string.rs:24:5 + --> $DIR/needless_raw_string.rs:23:5 | LL | cr"no hashes"; | ^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed index c99c2f46532..b2ad657d6b2 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed +++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed @@ -1,6 +1,5 @@ #![allow(clippy::no_effect, unused)] #![warn(clippy::needless_raw_string_hashes)] -#![feature(c_str_literals)] fn main() { r"\aaa"; diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs index dcc2af69f4e..54d8ed76d47 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs +++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs @@ -1,6 +1,5 @@ #![allow(clippy::no_effect, unused)] #![warn(clippy::needless_raw_string_hashes)] -#![feature(c_str_literals)] fn main() { r#"\aaa"#; diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr index 017160b1a42..c74eff8161e 100644 --- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr +++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr @@ -1,5 +1,5 @@ error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:6:5 + --> $DIR/needless_raw_string_hashes.rs:5:5 | LL | r#"\aaa"#; | ^^^^^^^^^ @@ -13,7 +13,7 @@ LL + r"\aaa"; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:7:5 + --> $DIR/needless_raw_string_hashes.rs:6:5 | LL | r##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + r#"Hello "world"!"#; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:8:5 + --> $DIR/needless_raw_string_hashes.rs:7:5 | LL | r######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + r####" "### "## "# "####; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:9:5 + --> $DIR/needless_raw_string_hashes.rs:8:5 | LL | r######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + r###" "aa" "# "## "###; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:10:5 + --> $DIR/needless_raw_string_hashes.rs:9:5 | LL | br#"\aaa"#; | ^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + br"\aaa"; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:11:5 + --> $DIR/needless_raw_string_hashes.rs:10:5 | LL | br##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + br#"Hello "world"!"#; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:12:5 + --> $DIR/needless_raw_string_hashes.rs:11:5 | LL | br######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + br####" "### "## "# "####; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:13:5 + --> $DIR/needless_raw_string_hashes.rs:12:5 | LL | br######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL + br###" "aa" "# "## "###; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:14:5 + --> $DIR/needless_raw_string_hashes.rs:13:5 | LL | cr#"\aaa"#; | ^^^^^^^^^^ @@ -109,7 +109,7 @@ LL + cr"\aaa"; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:15:5 + --> $DIR/needless_raw_string_hashes.rs:14:5 | LL | cr##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL + cr#"Hello "world"!"#; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:16:5 + --> $DIR/needless_raw_string_hashes.rs:15:5 | LL | cr######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL + cr####" "### "## "# "####; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:17:5 + --> $DIR/needless_raw_string_hashes.rs:16:5 | LL | cr######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL + cr###" "aa" "# "## "###; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:19:5 + --> $DIR/needless_raw_string_hashes.rs:18:5 | LL | / r#" LL | | \a @@ -164,7 +164,7 @@ LL ~ "; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:25:5 + --> $DIR/needless_raw_string_hashes.rs:24:5 | LL | r###"rust"###; | ^^^^^^^^^^^^^ @@ -176,7 +176,7 @@ LL + r"rust"; | error: unnecessary hashes around raw string literal - --> $DIR/needless_raw_string_hashes.rs:26:5 + --> $DIR/needless_raw_string_hashes.rs:25:5 | LL | r#"hello world"#; | ^^^^^^^^^^^^^^^^ diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 10a11e8e291..af224360319 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -474,14 +474,12 @@ impl<'test> TestCx<'test> { self.fatal("missing --coverage-dump"); }; - let proc_res = self.compile_test_and_save_ir(); + let (proc_res, llvm_ir_path) = self.compile_test_and_save_ir(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); } drop(proc_res); - let llvm_ir_path = self.output_base_name().with_extension("ll"); - let mut dump_command = Command::new(coverage_dump_path); dump_command.arg(llvm_ir_path); let proc_res = self.run_command_to_procres(&mut dump_command); @@ -2785,10 +2783,54 @@ impl<'test> TestCx<'test> { proc_res.fatal(None, || on_failure(*self)); } + fn get_output_file(&self, extension: &str) -> TargetLocation { + let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin")); + if thin_lto { + TargetLocation::ThisDirectory(self.output_base_dir()) + } else { + // This works with both `--emit asm` (as default output name for the assembly) + // and `ptx-linker` because the latter can write output at requested location. + let output_path = self.output_base_name().with_extension(extension); + let output_file = TargetLocation::ThisFile(output_path.clone()); + output_file + } + } + + fn get_filecheck_file(&self, extension: &str) -> PathBuf { + let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin")); + if thin_lto { + let name = self.testpaths.file.file_stem().unwrap().to_str().unwrap(); + let canonical_name = name.replace('-', "_"); + let mut output_file = None; + for entry in self.output_base_dir().read_dir().unwrap() { + if let Ok(entry) = entry { + let entry_path = entry.path(); + let entry_file = entry_path.file_name().unwrap().to_str().unwrap(); + if entry_file.starts_with(&format!("{}.{}", name, canonical_name)) + && entry_file.ends_with(extension) + { + assert!( + output_file.is_none(), + "thinlto doesn't support multiple cgu tests" + ); + output_file = Some(entry_file.to_string()); + } + } + } + if let Some(output_file) = output_file { + self.output_base_dir().join(output_file) + } else { + self.output_base_name().with_extension(extension) + } + } else { + self.output_base_name().with_extension(extension) + } + } + // codegen tests (using FileCheck) - fn compile_test_and_save_ir(&self) -> ProcRes { - let output_file = TargetLocation::ThisDirectory(self.output_base_dir()); + fn compile_test_and_save_ir(&self) -> (ProcRes, PathBuf) { + let output_file = self.get_output_file("ll"); let input_file = &self.testpaths.file; let rustc = self.make_compile_args( input_file, @@ -2799,15 +2841,13 @@ impl<'test> TestCx<'test> { Vec::new(), ); - self.compose_and_run_compiler(rustc, None) + let proc_res = self.compose_and_run_compiler(rustc, None); + let output_path = self.get_filecheck_file("ll"); + (proc_res, output_path) } fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) { - // This works with both `--emit asm` (as default output name for the assembly) - // and `ptx-linker` because the latter can write output at requested location. - let output_path = self.output_base_name().with_extension("s"); - - let output_file = TargetLocation::ThisFile(output_path.clone()); + let output_file = self.get_output_file("s"); let input_file = &self.testpaths.file; let mut emit = Emit::None; @@ -2837,7 +2877,9 @@ impl<'test> TestCx<'test> { Vec::new(), ); - (self.compose_and_run_compiler(rustc, None), output_path) + let proc_res = self.compose_and_run_compiler(rustc, None); + let output_path = self.get_filecheck_file("s"); + (proc_res, output_path) } fn verify_with_filecheck(&self, output: &Path) -> ProcRes { @@ -2870,7 +2912,7 @@ impl<'test> TestCx<'test> { self.fatal("missing --llvm-filecheck"); } - let proc_res = self.compile_test_and_save_ir(); + let (proc_res, output_path) = self.compile_test_and_save_ir(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); } @@ -2878,8 +2920,6 @@ impl<'test> TestCx<'test> { if let Some(PassMode::Build) = self.pass_mode() { return; } - - let output_path = self.output_base_name().with_extension("ll"); let proc_res = self.verify_with_filecheck(&output_path); if !proc_res.status.success() { self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res); diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 542c0c6cee9..d538a0c9ff5 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c52b8763bf36027f24baabe1f97cab3d3571c9e5 +0919ad18381f6f4fcaddc809e786553e028bbde0 diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index c2ef7710011..fb90559f3d1 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -384,7 +384,7 @@ pub fn report_error<'tcx, 'mir>( // Include a note like `std` does when we omit frames from a backtrace if was_pruned { - ecx.tcx.sess.diagnostic().note_without_error( + ecx.tcx.sess.diagnostic().note( "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace", ); } @@ -431,7 +431,7 @@ pub fn report_leaks<'mir, 'tcx>( ); } if any_pruned { - ecx.tcx.sess.diagnostic().note_without_error( + ecx.tcx.sess.diagnostic().note( "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace", ); } @@ -456,7 +456,7 @@ pub fn report_msg<'tcx>( let mut err = match diag_level { DiagLevel::Error => sess.struct_span_err(span, title).forget_guarantee(), DiagLevel::Warning => sess.struct_span_warn(span, title), - DiagLevel::Note => sess.diagnostic().span_note_diag(span, title), + DiagLevel::Note => sess.diagnostic().struct_span_note(span, title), }; // Show main message. diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 1345b22a34a..875a78974fa 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -464,7 +464,7 @@ pub fn eval_entry<'tcx>( // Check for thread leaks. if !ecx.have_all_terminated() { tcx.sess.err("the main thread terminated without waiting for all remaining threads"); - tcx.sess.note_without_error("pass `-Zmiri-ignore-leaks` to disable this check"); + tcx.sess.note("pass `-Zmiri-ignore-leaks` to disable this check"); return None; } // Check for memory leaks. @@ -475,7 +475,7 @@ pub fn eval_entry<'tcx>( let leak_message = "the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check"; if ecx.machine.collect_leak_backtraces { // If we are collecting leak backtraces, each leak is a distinct error diagnostic. - tcx.sess.note_without_error(leak_message); + tcx.sess.note(leak_message); } else { // If we do not have backtraces, we just report an error without any span. tcx.sess.err(leak_message); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs index 2ae3cd2a939..15dceeb8af2 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs @@ -629,7 +629,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing), rustc_attr!( TEST, rustc_error, Normal, - template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly + template!(Word, List: "span_delayed_bug_from_inside_query"), WarnFollowingWordOnly ), rustc_attr!(TEST, rustc_dump_user_substs, Normal, template!(Word), WarnFollowing), rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index b2591f016d4..27c79499868 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -110,7 +110,7 @@ struct LayoutCx<'a> { impl<'a> LayoutCalculator for LayoutCx<'a> { type TargetDataLayoutRef = &'a TargetDataLayout; - fn delay_bug(&self, txt: String) { + fn delayed_bug(&self, txt: String) { never!("{}", txt); } diff --git a/tests/assembly/thin-lto.rs b/tests/assembly/thin-lto.rs new file mode 100644 index 00000000000..deb8fd21d14 --- /dev/null +++ b/tests/assembly/thin-lto.rs @@ -0,0 +1,8 @@ +// compile-flags: -O -C lto=thin -C prefer-dynamic=no +// only-x86_64-unknown-linux-gnu +// assembly-output: emit-asm + +// CHECK: main + +pub fn main() { +} diff --git a/tests/codegen/thin-lto.rs b/tests/codegen/thin-lto.rs new file mode 100644 index 00000000000..7991cad7a0c --- /dev/null +++ b/tests/codegen/thin-lto.rs @@ -0,0 +1,7 @@ +// compile-flags: -O -C lto=thin -C prefer-dynamic=no +// only-x86_64-unknown-linux-gnu + +// CHECK: main + +pub fn main() { +} diff --git a/tests/coverage/thin-lto.cov-map b/tests/coverage/thin-lto.cov-map new file mode 100644 index 00000000000..7e84e398f84 --- /dev/null +++ b/tests/coverage/thin-lto.cov-map @@ -0,0 +1,8 @@ +Function name: thin_lto::main +Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 2) + diff --git a/tests/coverage/thin-lto.coverage b/tests/coverage/thin-lto.coverage new file mode 100644 index 00000000000..21abb5dce04 --- /dev/null +++ b/tests/coverage/thin-lto.coverage @@ -0,0 +1,5 @@ + LL| |// compile-flags: -O -C lto=thin -C prefer-dynamic=no + LL| | + LL| 1|pub fn main() { + LL| 1|} + diff --git a/tests/coverage/thin-lto.rs b/tests/coverage/thin-lto.rs new file mode 100644 index 00000000000..050aac26319 --- /dev/null +++ b/tests/coverage/thin-lto.rs @@ -0,0 +1,4 @@ +// compile-flags: -O -C lto=thin -C prefer-dynamic=no + +pub fn main() { +} diff --git a/tests/incremental/delayed_span_bug.rs b/tests/incremental/delayed_span_bug.rs index 2529e531e30..cc9831fff96 100644 --- a/tests/incremental/delayed_span_bug.rs +++ b/tests/incremental/delayed_span_bug.rs @@ -1,8 +1,8 @@ // revisions: cfail1 cfail2 // should-ice -// error-pattern: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)] +// error-pattern: delayed span bug triggered by #[rustc_error(span_delayed_bug_from_inside_query)] #![feature(rustc_attrs)] -#[rustc_error(delay_span_bug_from_inside_query)] +#[rustc_error(span_delayed_bug_from_inside_query)] fn main() {} diff --git a/tests/run-make/no-builtins-lto/Makefile b/tests/run-make/no-builtins-lto/Makefile index c8f05d9918b..c7be4836466 100644 --- a/tests/run-make/no-builtins-lto/Makefile +++ b/tests/run-make/no-builtins-lto/Makefile @@ -1,9 +1,15 @@ include ../tools.mk +# only-x86_64 + +# We want to check that `no_builtins` is correctly participating in LTO. +# First, verify that the `foo::foo` symbol can be found when linking. +# Next, verify that `memcpy` can be customized using `no_builtins` under LTO. +# Others will use the built-in memcpy. + all: - # Compile a `#![no_builtins]` rlib crate - $(RUSTC) no_builtins.rs - # Build an executable that depends on that crate using LTO. The no_builtins crate doesn't - # participate in LTO, so its rlib must be explicitly linked into the final binary. Verify this by - # grepping the linker arguments. - $(RUSTC) main.rs -C lto --print link-args | $(CGREP) 'libno_builtins.rlib' + $(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 foo.rs + $(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 no_builtins.rs + $(RUSTC) main.rs -C lto -C opt-level=2 -C debuginfo=0 -C save-temps -C metadata=1 -C codegen-units=1 + "$(LLVM_BIN_DIR)"/llvm-dis $(TMPDIR)/main.main.*-cgu.0.rcgu.lto.input.bc -o $(TMPDIR)/lto.ll + cat "$(TMPDIR)"/lto.ll | "$(LLVM_FILECHECK)" filecheck.lto.txt diff --git a/tests/run-make/no-builtins-lto/filecheck.lto.txt b/tests/run-make/no-builtins-lto/filecheck.lto.txt new file mode 100644 index 00000000000..79dc3a51501 --- /dev/null +++ b/tests/run-make/no-builtins-lto/filecheck.lto.txt @@ -0,0 +1,17 @@ +CHECK: define{{.*}} void @bar +CHECK-NEXT: call void @no_builtins +CHECK-NEXT: call void @llvm.memcpy + +CHECK: define{{.*}} i32 @main +CHECK: call void @bar + +CHECK: define{{.*}} void @foo +CHECK-NEXT: call void @llvm.memcpy + +CHECK: define{{.*}} void @no_builtins +CHECK-SAME: #[[ATTR:[0-9]+]] { +CHECK: call void @foo +CHECK-NEXT: call{{.*}} @memcpy + +CHECK: attributes #[[ATTR]] +CHECK-SAME: no-builtins diff --git a/tests/run-make/no-builtins-lto/foo.rs b/tests/run-make/no-builtins-lto/foo.rs new file mode 100644 index 00000000000..f09ac40b152 --- /dev/null +++ b/tests/run-make/no-builtins-lto/foo.rs @@ -0,0 +1,33 @@ +#![feature(lang_items, no_core)] +#![no_std] +#![no_core] +#![crate_type = "lib"] + +#[inline(never)] +#[no_mangle] +pub unsafe fn foo(dest: *mut u8, src: *const u8) { + // should call `@llvm.memcpy`. + memcpy(dest, src, 1024); +} + +#[no_mangle] +#[inline(never)] +pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, _n: usize) -> *mut u8 { + *dest = 0; + return src as *mut u8; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} +impl Copy for *mut u8 {} +impl Copy for *const u8 {} + +#[lang = "drop_in_place"] +#[allow(unconditional_recursion)] +pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { + // Code here does not matter - this is replaced by the + // real drop glue by the compiler. + drop_in_place(to_drop); +} diff --git a/tests/run-make/no-builtins-lto/main.rs b/tests/run-make/no-builtins-lto/main.rs index 890c999c8cc..4421a2afbce 100644 --- a/tests/run-make/no-builtins-lto/main.rs +++ b/tests/run-make/no-builtins-lto/main.rs @@ -1,3 +1,29 @@ +#![feature(no_core, start, lang_items)] +#![no_std] +// We use `no_core` to reduce the LTO products is small enough. +#![no_core] + extern crate no_builtins; +extern crate foo; + +#[cfg_attr(unix, link(name = "c"))] +#[cfg_attr(target_env = "msvc", link(name = "msvcrt"))] +extern "C" {} + +#[start] +fn main(_: isize, p: *const *const u8) -> isize { + // Make sure the symbols are retained. + unsafe { bar(*p as *mut u8, *p); } + 0 +} + +#[no_mangle] +#[inline(never)] +pub unsafe extern "C" fn bar(dest: *mut u8, src: *const u8) { + no_builtins::no_builtins(dest, src); + // should call `@llvm.memcpy` + foo::memcpy(dest, src, 1024); +} -fn main() {} +#[lang = "eh_personality"] +fn eh_personality() {} diff --git a/tests/run-make/no-builtins-lto/no_builtins.rs b/tests/run-make/no-builtins-lto/no_builtins.rs index 5d001031a57..33ed68e3aee 100644 --- a/tests/run-make/no-builtins-lto/no_builtins.rs +++ b/tests/run-make/no-builtins-lto/no_builtins.rs @@ -1,2 +1,15 @@ +#![feature(lang_items, no_core)] +#![no_std] +#![no_core] #![crate_type = "lib"] #![no_builtins] + +extern crate foo; + +#[no_mangle] +pub unsafe fn no_builtins(dest: *mut u8, src: *const u8) { + // There should be no "undefined reference to `foo::foo'". + foo::foo(dest, src); + // should call `@memcpy` instead of `@llvm.memcpy`. + foo::memcpy(dest, src, 1024); +} diff --git a/tests/run-make/pass-linker-flags-flavor/Makefile b/tests/run-make/pass-linker-flags-flavor/Makefile index bd3d3ed882f..1bb05d0f974 100644 --- a/tests/run-make/pass-linker-flags-flavor/Makefile +++ b/tests/run-make/pass-linker-flags-flavor/Makefile @@ -3,6 +3,9 @@ include ../tools.mk all: - $(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3' - $(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3' - $(RUSTC) rs.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"' + $(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3' + $(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3' + $(RUSTC) empty.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"' + $(RUSTC) attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3' + $(RUSTC) --cfg 'feature="verbatim"' attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3' + $(RUSTC) attribute.rs -C linker-flavor=ld --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"' diff --git a/tests/run-make/pass-linker-flags-flavor/attribute.rs b/tests/run-make/pass-linker-flags-flavor/attribute.rs new file mode 100644 index 00000000000..d099165301b --- /dev/null +++ b/tests/run-make/pass-linker-flags-flavor/attribute.rs @@ -0,0 +1,12 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "static", name = "l1")] +#[cfg_attr(feature = "verbatim", link(kind = "link-arg", name = "a1", modifiers = "+verbatim"))] +#[cfg_attr(not(feature = "verbatim"), link(kind = "link-arg", name = "a1"))] +#[link(kind = "static", name = "l2")] +#[link(kind = "link-arg", name = "a2")] +#[link(kind = "dylib", name = "d1")] +#[link(kind = "link-arg", name = "a3")] +extern "C" {} + +fn main() {} diff --git a/tests/run-make/pass-linker-flags-flavor/rs.rs b/tests/run-make/pass-linker-flags-flavor/empty.rs index f328e4d9d04..f328e4d9d04 100644 --- a/tests/run-make/pass-linker-flags-flavor/rs.rs +++ b/tests/run-make/pass-linker-flags-flavor/empty.rs diff --git a/tests/run-make/pass-linker-flags-from-dep/Makefile b/tests/run-make/pass-linker-flags-from-dep/Makefile index b57389bb7d4..48b3b26ce81 100644 --- a/tests/run-make/pass-linker-flags-from-dep/Makefile +++ b/tests/run-make/pass-linker-flags-from-dep/Makefile @@ -4,7 +4,9 @@ all: # Build deps $(RUSTC) native_dep_1.rs --crate-type=staticlib $(RUSTC) native_dep_2.rs --crate-type=staticlib - $(RUSTC) rust_dep.rs -l static:-bundle=native_dep_1 -l link-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options + $(RUSTC) rust_dep_flag.rs -l static:-bundle=native_dep_1 -l link-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options + $(RUSTC) rust_dep_attr.rs --crate-type=lib # Check sequence of linker args - $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2' + $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_flag.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2' + $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_attr.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2' diff --git a/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs b/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs new file mode 100644 index 00000000000..ac5888ce610 --- /dev/null +++ b/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs @@ -0,0 +1,14 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "static", name = "native_dep_1", modifiers = "-bundle")] +#[link(kind = "link-arg", name = "some_flag")] +#[link(kind = "static", name = "native_dep_2", modifiers = "-bundle")] +extern "C" { + pub fn foo(); +} + +pub fn f() { + unsafe { + foo(); + } +} diff --git a/tests/run-make/pass-linker-flags-from-dep/rust_dep.rs b/tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs index 7f5df113934..7f5df113934 100644 --- a/tests/run-make/pass-linker-flags-from-dep/rust_dep.rs +++ b/tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs diff --git a/tests/run-make/pass-linker-flags/Makefile b/tests/run-make/pass-linker-flags/Makefile index 6ddbcbb1b08..226943e93bd 100644 --- a/tests/run-make/pass-linker-flags/Makefile +++ b/tests/run-make/pass-linker-flags/Makefile @@ -1,4 +1,5 @@ include ../tools.mk all: - $(RUSTC) rs.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3' + $(RUSTC) empty.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3' + $(RUSTC) attribute.rs --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3' diff --git a/tests/run-make/pass-linker-flags/attribute.rs b/tests/run-make/pass-linker-flags/attribute.rs new file mode 100644 index 00000000000..6f784c01ff2 --- /dev/null +++ b/tests/run-make/pass-linker-flags/attribute.rs @@ -0,0 +1,11 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "static", name = "l1")] +#[link(kind = "link-arg", name = "a1")] +#[link(kind = "static", name = "l2")] +#[link(kind = "link-arg", name = "a2")] +#[link(kind = "dylib", name = "d1")] +#[link(kind = "link-arg", name = "a3")] +extern "C" {} + +fn main() {} diff --git a/tests/run-make/pass-linker-flags/rs.rs b/tests/run-make/pass-linker-flags/empty.rs index f328e4d9d04..f328e4d9d04 100644 --- a/tests/run-make/pass-linker-flags/rs.rs +++ b/tests/run-make/pass-linker-flags/empty.rs diff --git a/tests/run-make/valid-print-requests/valid-print-requests.stderr b/tests/run-make/valid-print-requests/valid-print-requests.stderr index 4f57550c29a..22bb102f9c9 100644 --- a/tests/run-make/valid-print-requests/valid-print-requests.stderr +++ b/tests/run-make/valid-print-requests/valid-print-requests.stderr @@ -1,2 +1,2 @@ -error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `all-target-specs-json`, `link-args`, `split-debuginfo`, `deployment-target` +error: unknown print request `uwu`. Valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` diff --git a/tests/run-make/wasm-spurious-import/Makefile b/tests/run-make/wasm-builtins-import/Makefile index ff9dfeac6d0..ff9dfeac6d0 100644 --- a/tests/run-make/wasm-spurious-import/Makefile +++ b/tests/run-make/wasm-builtins-import/Makefile diff --git a/tests/run-make/wasm-spurious-import/main.rs b/tests/run-make/wasm-builtins-import/main.rs index fcbead5e28b..5eb99df6ff7 100644 --- a/tests/run-make/wasm-spurious-import/main.rs +++ b/tests/run-make/wasm-builtins-import/main.rs @@ -8,7 +8,8 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! { #[no_mangle] pub fn multer(a: i128, b: i128) -> i128 { - // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported - // panic function in case of a bug. We verify that no imports exist in our verifier. + // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported function + // such as panic or __multi3 (externally defined) in case of a bug. We verify that + // no imports exist in our verifier. a * b } diff --git a/tests/run-make/wasm-spurious-import/verify.js b/tests/run-make/wasm-builtins-import/verify.js index d3b2101b662..d3b2101b662 100644 --- a/tests/run-make/wasm-spurious-import/verify.js +++ b/tests/run-make/wasm-builtins-import/verify.js diff --git a/tests/rustdoc-gui/font-weight.goml b/tests/rustdoc-gui/font-weight.goml index 6fad128dab8..602b8d6f5b3 100644 --- a/tests/rustdoc-gui/font-weight.goml +++ b/tests/rustdoc-gui/font-weight.goml @@ -2,7 +2,7 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html" assert-css: ("//*[@class='rust item-decl']//a[text()='Alias']", {"font-weight": "400"}) assert-css: ( - "//*[@class='structfield small-section-header']//a[text()='Alias']", + "//*[@class='structfield section-header']//a[text()='Alias']", {"font-weight": "400"}, ) assert-css: ("#method\.a_method > .code-header", {"font-weight": "600"}) diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml index a7ac94c4943..19185818f40 100644 --- a/tests/rustdoc-gui/headers-color.goml +++ b/tests/rustdoc-gui/headers-color.goml @@ -31,7 +31,7 @@ define-function: ( ALL, ) go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" - assert-css: (".small-section-header a", {"color": |color|}, ALL) + assert-css: (".section-header a", {"color": |color|}, ALL) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" // We select headings (h2, h3, h...). assert-css: (".docblock > :not(p) > a", {"color": |headings_color|}, ALL) diff --git a/tests/rustdoc-gui/where-whitespace.goml b/tests/rustdoc-gui/where-whitespace.goml index 69e6c3356a4..da104fa4011 100644 --- a/tests/rustdoc-gui/where-whitespace.goml +++ b/tests/rustdoc-gui/where-whitespace.goml @@ -3,15 +3,15 @@ go-to: "file://" + |DOC_PATH| + "/lib2/trait.Whitespace.html" show-text: true // First, we check in the trait definition if the where clause is "on its own" (not on the same // line than "pub trait Whitespace<Idx>"). -compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y")) +compare-elements-position-false: (".item-decl code", "div.where", ("y")) // And that the code following it isn't on the same line either. -compare-elements-position-false: (".item-decl .fn", ".where.fmt-newline", ("y")) +compare-elements-position-false: (".item-decl .fn", "div.where", ("y")) go-to: "file://" + |DOC_PATH| + "/lib2/struct.WhereWhitespace.html" // We make the screen a bit wider to ensure that the trait impl is on one line. set-window-size: (915, 915) -compare-elements-position-false: ("#method\.new .fn", "#method\.new .where.fmt-newline", ("y")) +compare-elements-position-false: ("#method\.new .fn", "#method\.new div.where", ("y")) // We ensure that both the trait name and the struct name are on the same line in // "impl<K, T> Whitespace<&K> for WhereWhitespace<T>". compare-elements-position: ( @@ -22,6 +22,6 @@ compare-elements-position: ( // And we now check that the where condition isn't on the same line. compare-elements-position-false: ( "#trait-implementations-list .impl h3 .trait", - "#trait-implementations-list .impl h3 .where.fmt-newline", + "#trait-implementations-list .impl h3 div.where", ("y"), ) diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index ab8d72bf71b..f9f9c4f4de8 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -18,6 +18,15 @@ const PARSED = [ error: "Found generics without a path", }, { + query: '-> *', + elems: [], + foundElems: 0, + original: "-> *", + returned: [], + userQuery: "-> *", + error: "Unexpected `*`", + }, + { query: 'a<"P">', elems: [], foundElems: 0, @@ -144,6 +153,24 @@ const PARSED = [ error: "Unexpected `::::`", }, { + query: "a:: ::b", + elems: [], + foundElems: 0, + original: "a:: ::b", + returned: [], + userQuery: "a:: ::b", + error: "Unexpected `:: ::`", + }, + { + query: "a::\t::b", + elems: [], + foundElems: 0, + original: "a:: ::b", + returned: [], + userQuery: "a:: ::b", + error: "Unexpected `:: ::`", + }, + { query: "a::b::", elems: [], foundElems: 0, @@ -315,24 +342,6 @@ const PARSED = [ error: 'Unexpected `-` after `<`', }, { - query: "a:: a", - elems: [], - foundElems: 0, - original: 'a:: a', - returned: [], - userQuery: 'a:: a', - error: 'Unexpected `:: `', - }, - { - query: "a ::a", - elems: [], - foundElems: 0, - original: 'a ::a', - returned: [], - userQuery: 'a ::a', - error: 'Unexpected ` ::`', - }, - { query: "a<a>:", elems: [], foundElems: 0, diff --git a/tests/rustdoc-js-std/parser-paths.js b/tests/rustdoc-js-std/parser-paths.js index 8d4dedf3f46..774e5d028cc 100644 --- a/tests/rustdoc-js-std/parser-paths.js +++ b/tests/rustdoc-js-std/parser-paths.js @@ -16,6 +16,54 @@ const PARSED = [ error: null, }, { + query: "a:: a", + elems: [{ + name: "a:: a", + fullPath: ["a", "a"], + pathWithoutLast: ["a"], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + foundElems: 1, + original: 'a:: a', + returned: [], + userQuery: 'a:: a', + error: null, + }, + { + query: "a ::a", + elems: [{ + name: "a ::a", + fullPath: ["a", "a"], + pathWithoutLast: ["a"], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + foundElems: 1, + original: 'a ::a', + returned: [], + userQuery: 'a ::a', + error: null, + }, + { + query: "a :: a", + elems: [{ + name: "a :: a", + fullPath: ["a", "a"], + pathWithoutLast: ["a"], + pathLast: "a", + generics: [], + typeFilter: -1, + }], + foundElems: 1, + original: 'a :: a', + returned: [], + userQuery: 'a :: a', + error: null, + }, + { query: 'A::B,C', elems: [ { diff --git a/tests/rustdoc-js-std/parser-separators.js b/tests/rustdoc-js-std/parser-separators.js index 00c489b51a6..7f95f61b006 100644 --- a/tests/rustdoc-js-std/parser-separators.js +++ b/tests/rustdoc-js-std/parser-separators.js @@ -5,7 +5,7 @@ const PARSED = [ query: 'aaaaaa b', elems: [ { - name: 'aaaaaa\tb', + name: 'aaaaaa b', fullPath: ['aaaaaa', 'b'], pathWithoutLast: ['aaaaaa'], pathLast: 'b', @@ -14,9 +14,9 @@ const PARSED = [ }, ], foundElems: 1, - original: "aaaaaa b", + original: "aaaaaa b", returned: [], - userQuery: "aaaaaa b", + userQuery: "aaaaaa b", error: null, }, { @@ -40,9 +40,9 @@ const PARSED = [ }, ], foundElems: 2, - original: "aaaaaa, b", + original: "aaaaaa, b", returned: [], - userQuery: "aaaaaa, b", + userQuery: "aaaaaa, b", error: null, }, { @@ -93,7 +93,7 @@ const PARSED = [ query: 'a\tb', elems: [ { - name: 'a\tb', + name: 'a b', fullPath: ['a', 'b'], pathWithoutLast: ['a'], pathLast: 'b', @@ -102,9 +102,9 @@ const PARSED = [ }, ], foundElems: 1, - original: "a\tb", + original: "a b", returned: [], - userQuery: "a\tb", + userQuery: "a b", error: null, }, { @@ -176,7 +176,7 @@ const PARSED = [ pathLast: 'a', generics: [ { - name: 'b\tc', + name: 'b c', fullPath: ['b', 'c'], pathWithoutLast: ['b'], pathLast: 'c', @@ -187,9 +187,9 @@ const PARSED = [ }, ], foundElems: 1, - original: "a<b\tc>", + original: "a<b c>", returned: [], - userQuery: "a<b\tc>", + userQuery: "a<b c>", error: null, }, ]; diff --git a/tests/rustdoc-js-std/parser-weird-queries.js b/tests/rustdoc-js-std/parser-weird-queries.js index 720ef66c165..ba68c9717c5 100644 --- a/tests/rustdoc-js-std/parser-weird-queries.js +++ b/tests/rustdoc-js-std/parser-weird-queries.js @@ -92,9 +92,9 @@ const PARSED = [ query: 'mod\t:', elems: [], foundElems: 0, - original: 'mod\t:', + original: 'mod :', returned: [], - userQuery: 'mod\t:', + userQuery: 'mod :', error: "Unexpected `:` (expected path after type filter `mod:`)", }, ]; diff --git a/tests/rustdoc-ui/error-in-impl-trait/README.md b/tests/rustdoc-ui/error-in-impl-trait/README.md index 1176a4a8c4c..d969ab10ef5 100644 --- a/tests/rustdoc-ui/error-in-impl-trait/README.md +++ b/tests/rustdoc-ui/error-in-impl-trait/README.md @@ -1,5 +1,5 @@ Each of these needs to be in a separate file, -because the `delay_span_bug` ICE in rustdoc won't be triggerred +because the `span_delayed_bug` ICE in rustdoc won't be triggerred if even a single other error was emitted. However, conceptually they are all testing basically the same thing. diff --git a/tests/rustdoc-ui/unescaped_backticks.rs b/tests/rustdoc-ui/unescaped_backticks.rs index e960e9f59e9..e813fba4717 100644 --- a/tests/rustdoc-ui/unescaped_backticks.rs +++ b/tests/rustdoc-ui/unescaped_backticks.rs @@ -190,7 +190,7 @@ pub fn complicated_markdown() {} pub mod mir {} pub mod rustc { - /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to + /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to //~^ ERROR unescaped backtick /// ensure it gets used. pub fn ty_error_with_message() {} diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr index 2b4e491b1fe..bd21dcb6e1a 100644 --- a/tests/rustdoc-ui/unescaped_backticks.stderr +++ b/tests/rustdoc-ui/unescaped_backticks.stderr @@ -64,19 +64,19 @@ LL | /// `cfg=... and not `#[cfg_attr]\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:193:91 + --> $DIR/unescaped_backticks.rs:193:93 | -LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to - | ^ +LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to + | ^ | help: the closing backtick of an inline code may be missing | -LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to - | + +LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to + | + help: if you meant to use a literal backtick, escape it | -LL | /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given \`msg to - | + +LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given \`msg to + | + error: unescaped backtick --> $DIR/unescaped_backticks.rs:202:34 diff --git a/tests/rustdoc/async-fn-opaque-item.rs b/tests/rustdoc/async-fn-opaque-item.rs index a73e84f3fdc..2c030824fe7 100644 --- a/tests/rustdoc/async-fn-opaque-item.rs +++ b/tests/rustdoc/async-fn-opaque-item.rs @@ -9,7 +9,7 @@ // Checking there is only a "Functions" header and no "Opaque types". // @has async_fn_opaque_item/index.html -// @count - '//*[@class="small-section-header"]' 1 -// @has - '//*[@class="small-section-header"]' 'Functions' +// @count - '//*[@class="section-header"]' 1 +// @has - '//*[@class="section-header"]' 'Functions' pub async fn test() {} diff --git a/tests/rustdoc/compiler-derive-proc-macro.rs b/tests/rustdoc/compiler-derive-proc-macro.rs index 489ec924c1f..1c3867ced9b 100644 --- a/tests/rustdoc/compiler-derive-proc-macro.rs +++ b/tests/rustdoc/compiler-derive-proc-macro.rs @@ -5,9 +5,9 @@ // @has 'foo/index.html' // Each compiler builtin proc-macro has a trait equivalent so we should have // a trait section as well. -// @count - '//*[@id="main-content"]//*[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Traits' -// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Derive Macros' +// @count - '//*[@id="main-content"]//*[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]//*[@class="section-header"]' 'Traits' +// @has - '//*[@id="main-content"]//*[@class="section-header"]' 'Derive Macros' // Now checking the correct file is generated as well. // @has 'foo/derive.Clone.html' diff --git a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs index e382940a47e..ae830c03ea3 100644 --- a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs +++ b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs @@ -6,8 +6,8 @@ // @has 'foo/index.html' // There should only be one struct displayed. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' // @has - '//*[@id="main-content"]//a[@href="struct.Reexport.html"]' 'Reexport' // @has - '//*[@id="main-content"]//*[@class="desc docblock-short"]' 'Visible. Original.' diff --git a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs index 5d2c553d8a5..2905e7d44bc 100644 --- a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs +++ b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs @@ -7,9 +7,9 @@ // @has - '//*[@class="item-name"]/a[@class="type"]' 'AtomicU8' // @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' // We also ensure we don't have another item displayed. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Type Aliases' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' mod other { pub type AtomicU8 = (); diff --git a/tests/rustdoc/issue-105735-overlapping-reexport.rs b/tests/rustdoc/issue-105735-overlapping-reexport.rs index 50f2450b90a..7fa7df7701a 100644 --- a/tests/rustdoc/issue-105735-overlapping-reexport.rs +++ b/tests/rustdoc/issue-105735-overlapping-reexport.rs @@ -7,9 +7,9 @@ // @has - '//*[@class="item-name"]/a[@class="struct"]' 'AtomicU8' // @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' // We also ensure we don't have another item displayed. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' mod thing { pub use core::sync::atomic::AtomicU8; diff --git a/tests/rustdoc/issue-109258-missing-private-inlining.rs b/tests/rustdoc/issue-109258-missing-private-inlining.rs index 96f606368b2..12c5556f132 100644 --- a/tests/rustdoc/issue-109258-missing-private-inlining.rs +++ b/tests/rustdoc/issue-109258-missing-private-inlining.rs @@ -4,9 +4,9 @@ // @has 'foo/index.html' // We should only have a "Re-exports" and a "Modules" headers. -// @count - '//*[@id="main-content"]/h2[@class="small-section-header"]' 2 -// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Re-exports' -// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Modules' +// @count - '//*[@id="main-content"]/h2[@class="section-header"]' 2 +// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Re-exports' +// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Modules' // @has - '//*[@id="reexport.Foo"]' 'pub use crate::issue_109258::Foo;' // @has - '//*[@id="reexport.Foo"]//a[@href="issue_109258/struct.Foo.html"]' 'Foo' @@ -15,8 +15,8 @@ pub use crate::issue_109258::Foo; // @has 'foo/issue_109258/index.html' // We should only have a "Structs" header. -// @count - '//*[@id="main-content"]/h2[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Structs' +// @count - '//*[@id="main-content"]/h2[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Structs' // @has - '//*[@id="main-content"]//a[@href="struct.Foo.html"]' 'Foo' // @has 'foo/issue_109258/struct.Foo.html' pub mod issue_109258 { diff --git a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs index 3b836a21931..9fb2f7c7c05 100644 --- a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs +++ b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs @@ -66,8 +66,8 @@ pub mod single_reexport_inherit_hidden { pub mod single_reexport_no_inline { // First we ensure that we only have re-exports and no inlined items. // @has 'foo/single_reexport_no_inline/index.html' - // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' + // @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' // Now we check that we don't have links to the items, just `pub use`. // @has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;' @@ -101,10 +101,10 @@ pub mod glob_reexport { // With glob re-exports, we don't inline `#[doc(hidden)]` items so only `module` items // should be inlined. // @has 'foo/glob_reexport/index.html' - // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases' + // @count - '//*[@id="main-content"]/*[@class="section-header"]' 3 + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Type Aliases' // Now we check we have 1 re-export and 2 inlined items. // If not item from a glob re-export is visible, we don't show the re-export. diff --git a/tests/rustdoc/issue-110422-inner-private.rs b/tests/rustdoc/issue-110422-inner-private.rs index ee8ed5cc6e1..43dc929ab07 100644 --- a/tests/rustdoc/issue-110422-inner-private.rs +++ b/tests/rustdoc/issue-110422-inner-private.rs @@ -8,11 +8,11 @@ // @has 'foo/index.html' // Checking there is no "trait" entry. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 4 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Macros' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 4 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Macros' // @has - '//a[@href="fn.foo.html"]' 'foo' fn foo() { @@ -50,11 +50,11 @@ const BAR: i32 = { // @has 'foo/struct.Bar.html' // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub(crate) fn foo()' - // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 + // @count - '//*[@id="main-content"]/*[@class="section-header"]' 3 // We now check that the `Foo` trait is not documented nor visible on `Bar` page. - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Implementations' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Auto Trait Implementations' - // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Blanket Implementations' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Implementations' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Auto Trait Implementations' + // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Blanket Implementations' // @!has - '//*[@href="trait.Foo.html#method.babar"]/*[@class="code-header"]' 'fn babar()' impl Bar { fn foo() {} diff --git a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs index 1429b5e4741..50def2c3cd9 100644 --- a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs +++ b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs @@ -5,8 +5,8 @@ #![crate_name = "foo"] // @has 'foo/index.html' -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Modules' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Modules' // @count - '//*[@id="main-content"]/*[@class="item-table"]//*[@class="mod"]' 2 // @has - '//*[@id="main-content"]//*[@class="mod"]' 'banana' // @has - '//*[@id="main-content"]//*[@href="banana/index.html"]' 'banana' diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc/nested-items-issue-111415.rs index 9b7688c332c..c117569d9b4 100644 --- a/tests/rustdoc/nested-items-issue-111415.rs +++ b/tests/rustdoc/nested-items-issue-111415.rs @@ -5,10 +5,10 @@ // @has 'foo/index.html' // Checking there are only three sections. -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 3 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Traits' // Checking that there are only three items. // @count - '//*[@id="main-content"]//*[@class="item-name"]' 3 // @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar' diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html b/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html index 46be00a0804..7d2a2589133 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html +++ b/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"&'static [SomeStruct]":"<h3>Notable traits for <code>&amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</code></h3><pre><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\">SomeTrait</a> for &amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"&'static [SomeStruct]":"<h3>Notable traits for <code>&amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</code></h3><pre><code><div class=\"where\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\">SomeTrait</a> for &amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</div>"}</script> \ No newline at end of file diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html b/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html index f592e3b375c..9f71677cf4f 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html +++ b/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre><code><div class=\"where\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></div>"}</script> \ No newline at end of file diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html b/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html index e8f4f600045..38689c79f1a 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html +++ b/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>","Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre><code><span class=\"where fmt-newline\">impl&lt;T: <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre><code><div class=\"where\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></div>","Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre><code><div class=\"where\">impl&lt;T: <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</div>"}</script> \ No newline at end of file diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html b/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html index e7909669b15..c137be9e3a5 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html +++ b/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre><code><span class=\"where fmt-newline\">impl&lt;T: <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre><code><div class=\"where\">impl&lt;T: <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</div>"}</script> \ No newline at end of file diff --git a/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html b/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html index 5f54b7522ae..cce8739df16 100644 --- a/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html +++ b/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"Odd":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></code></h3><pre><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\">Iterator</a> for <a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></span><span class=\"where fmt-newline\"> type <a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\">Item</a> = <a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\">usize</a>;</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"Odd":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></code></h3><pre><code><div class=\"where\">impl <a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\">Iterator</a> for <a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></div><div class=\"where\"> type <a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\">Item</a> = <a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\">usize</a>;</div>"}</script> \ No newline at end of file diff --git a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs b/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs index d8953eaf597..ae0aead244b 100644 --- a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs +++ b/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs @@ -4,8 +4,8 @@ #![crate_name = "foo"] // @has 'foo/associations/index.html' -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Traits' // @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy' // @has 'foo/associations/trait.GroupedBy.html' pub mod associations { @@ -16,8 +16,8 @@ pub mod associations { } // @has 'foo/prelude/index.html' -// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 -// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' +// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports' // @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;' pub mod prelude { pub use associations::GroupedBy; diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/rfc-2632-const-trait-impl.rs index 7f56b2ffeb8..6f264969e54 100644 --- a/tests/rustdoc/rfc-2632-const-trait-impl.rs +++ b/tests/rustdoc/rfc-2632-const-trait-impl.rs @@ -23,7 +23,7 @@ pub trait Tr<T> { // @!has - '//section[@id="method.a"]/h4[@class="code-header"]' '~const' // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const' - // @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' + // @has - '//section[@id="method.a"]/h4[@class="code-header"]/div[@class="where"]' ': Fn' fn a<A: /* ~const */ Fn() + ~const Destruct>() where Option<A>: /* ~const */ Fn() + ~const Destruct, @@ -35,7 +35,7 @@ pub trait Tr<T> { // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]' '~const' // @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where"]' '~const' -// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' +// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/div[@class="where"]' ': Fn' impl<T: /* ~const */ Fn() + ~const Destruct> const Tr<T> for T where Option<T>: /* ~const */ Fn() + ~const Destruct, @@ -49,8 +49,8 @@ where // @!has foo/fn.foo.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const' // @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn' -// @!has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' ': Fn' +// @!has - '//pre[@class="rust item-decl"]/code/div[@class="where"]' '~const' +// @has - '//pre[@class="rust item-decl"]/code/div[@class="where"]' ': Fn' pub const fn foo<F: /* ~const */ Fn() + ~const Destruct>() where Option<F>: /* ~const */ Fn() + ~const Destruct, @@ -62,7 +62,7 @@ impl<T> S<T> { // @!has foo/struct.S.html '//section[@id="method.foo"]/h4[@class="code-header"]' '~const' // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const' - // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' + // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/div[@class="where"]' ': Fn' pub const fn foo<B, C: /* ~const */ Fn() + ~const Destruct>() where B: /* ~const */ Fn() + ~const Destruct, diff --git a/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs b/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs index ff84352d716..bea25c75aa4 100644 --- a/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs +++ b/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs @@ -13,14 +13,14 @@ pub struct Pair<A, B> { // @count - '//*[@id="aliased-type"]' 1 // @count - '//*[@id="variants"]' 0 // @count - '//*[@id="fields"]' 1 -// @count - '//span[@class="where fmt-newline"]' 0 +// @count - '//div[@class="where"]' 0 pub type ReversedTypesPair<Q, R> = Pair<R, Q>; // @has 'inner_types_lazy/type.ReadWrite.html' // @count - '//*[@id="aliased-type"]' 1 // @count - '//*[@id="variants"]' 0 // @count - '//*[@id="fields"]' 1 -// @count - '//span[@class="where fmt-newline"]' 2 +// @count - '//div[@class="where"]' 2 pub type ReadWrite<R, W> = Pair<R, W> where R: std::io::Read, @@ -30,5 +30,5 @@ where // @count - '//*[@id="aliased-type"]' 1 // @count - '//*[@id="variants"]' 0 // @count - '//*[@id="fields"]' 1 -// @count - '//span[@class="where fmt-newline"]' 0 +// @count - '//div[@class="where"]' 0 pub type VecPair<U, V> = Pair<Vec<U>, Vec<V>>; diff --git a/tests/rustdoc/typedef-inner-variants.rs b/tests/rustdoc/typedef-inner-variants.rs index b734714fd64..4d0ff85551c 100644 --- a/tests/rustdoc/typedef-inner-variants.rs +++ b/tests/rustdoc/typedef-inner-variants.rs @@ -65,7 +65,7 @@ pub union OneOr<A: Copy> { // @count - '//*[@id="aliased-type"]' 1 // @count - '//*[@id="variants"]' 0 // @count - '//*[@id="fields"]' 1 -// @count - '//*[@class="structfield small-section-header"]' 2 +// @count - '//*[@class="structfield section-header"]' 2 // @matches - '//pre[@class="rust item-decl"]//code' "union OneOrF64" pub type OneOrF64 = OneOr<f64>; @@ -81,7 +81,7 @@ pub struct One<T> { // @count - '//*[@id="aliased-type"]' 1 // @count - '//*[@id="variants"]' 0 // @count - '//*[@id="fields"]' 1 -// @count - '//*[@class="structfield small-section-header"]' 1 +// @count - '//*[@class="structfield section-header"]' 1 // @matches - '//pre[@class="rust item-decl"]//code' "struct OneU64" // @matches - '//pre[@class="rust item-decl"]//code' "pub val" pub type OneU64 = One<u64>; diff --git a/tests/rustdoc/where.SWhere_Echo_impl.html b/tests/rustdoc/where.SWhere_Echo_impl.html index 7517eb090f4..726196281a5 100644 --- a/tests/rustdoc/where.SWhere_Echo_impl.html +++ b/tests/rustdoc/where.SWhere_Echo_impl.html @@ -1,2 +1,2 @@ -<h3 class="code-header">impl<D> <a class="struct" href="struct.Delta.html" title="struct foo::Delta">Delta</a><D><span class="where fmt-newline">where - D: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></h3> \ No newline at end of file +<h3 class="code-header">impl<D> <a class="struct" href="struct.Delta.html" title="struct foo::Delta">Delta</a><D><div class="where">where + D: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</div></h3> \ No newline at end of file diff --git a/tests/rustdoc/where.bravo_trait_decl.html b/tests/rustdoc/where.bravo_trait_decl.html index 00524201a8a..3f1c994b0b2 100644 --- a/tests/rustdoc/where.bravo_trait_decl.html +++ b/tests/rustdoc/where.bravo_trait_decl.html @@ -1,5 +1,5 @@ -<code>pub trait Bravo<B><span class="where fmt-newline">where - B: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span>{ +<code>pub trait Bravo<B><div class="where">where + B: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</div>{ // Required method fn <a href="#tymethod.get" class="fn">get</a>(&self, B: B); }</code> \ No newline at end of file diff --git a/tests/rustdoc/where.charlie_fn_decl.html b/tests/rustdoc/where.charlie_fn_decl.html index 8e3bc8b01ec..4dd410435c1 100644 --- a/tests/rustdoc/where.charlie_fn_decl.html +++ b/tests/rustdoc/where.charlie_fn_decl.html @@ -1,2 +1,2 @@ -<code>pub fn charlie<C>()<span class="where fmt-newline">where - C: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></code> \ No newline at end of file +<code>pub fn charlie<C>()<div class="where">where + C: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</div></code> \ No newline at end of file diff --git a/tests/rustdoc/where.golf_type_alias_decl.html b/tests/rustdoc/where.golf_type_alias_decl.html index 8da5402f900..ab60bb262da 100644 --- a/tests/rustdoc/where.golf_type_alias_decl.html +++ b/tests/rustdoc/where.golf_type_alias_decl.html @@ -1,2 +1,2 @@ -<code>pub type Golf<T><span class="where fmt-newline">where - T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span> = <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a>;</code> \ No newline at end of file +<code>pub type Golf<T><div class="where">where + T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</div> = <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a>;</code> \ No newline at end of file diff --git a/tests/rustdoc/whitespace-after-where-clause.enum.html b/tests/rustdoc/whitespace-after-where-clause.enum.html index ff4971f33cd..25e02145323 100644 --- a/tests/rustdoc/whitespace-after-where-clause.enum.html +++ b/tests/rustdoc/whitespace-after-where-clause.enum.html @@ -1,5 +1,5 @@ -<pre class="rust item-decl"><code>pub enum Cow<'a, B><span class="where fmt-newline">where - B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{ +<pre class="rust item-decl"><code>pub enum Cow<'a, B><div class="where">where + B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</div>{ Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&'a B</a>), Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>), }</code></pre> \ No newline at end of file diff --git a/tests/rustdoc/whitespace-after-where-clause.struct.html b/tests/rustdoc/whitespace-after-where-clause.struct.html index ca685358633..bc62a3a0015 100644 --- a/tests/rustdoc/whitespace-after-where-clause.struct.html +++ b/tests/rustdoc/whitespace-after-where-clause.struct.html @@ -1,5 +1,5 @@ -<pre class="rust item-decl"><code>pub struct Struct<'a, B><span class="where fmt-newline">where - B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{ +<pre class="rust item-decl"><code>pub struct Struct<'a, B><div class="where">where + B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</div>{ pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&'a B</a>, pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>, }</code></pre> \ No newline at end of file diff --git a/tests/rustdoc/whitespace-after-where-clause.trait.html b/tests/rustdoc/whitespace-after-where-clause.trait.html index 0928b48e6b6..0e25ed86a7c 100644 --- a/tests/rustdoc/whitespace-after-where-clause.trait.html +++ b/tests/rustdoc/whitespace-after-where-clause.trait.html @@ -1,5 +1,5 @@ -<pre class="rust item-decl"><code>pub trait ToOwned<T><span class="where fmt-newline">where - T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span>{ +<pre class="rust item-decl"><code>pub trait ToOwned<T><div class="where">where + T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</div>{ type <a href="#associatedtype.Owned" class="associatedtype">Owned</a>; // Required methods diff --git a/tests/rustdoc/whitespace-after-where-clause.union.html b/tests/rustdoc/whitespace-after-where-clause.union.html index 40b0c671284..7e0d5f8717a 100644 --- a/tests/rustdoc/whitespace-after-where-clause.union.html +++ b/tests/rustdoc/whitespace-after-where-clause.union.html @@ -1,4 +1,4 @@ -<pre class="rust item-decl"><code>pub union Union<'a, B><span class="where fmt-newline">where - B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{ +<pre class="rust item-decl"><code>pub union Union<'a, B><div class="where">where + B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a><<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>> + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</div>{ /* private fields */ }</code></pre> \ No newline at end of file diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr index 3234945e0df..7f9324035e4 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr +++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr @@ -5,7 +5,7 @@ LL | let _array: [u32; <A as Foo>::Y]; | ^ cannot perform const operation using `A` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr index 0c8dc9d7fd6..8898880586c 100644 --- a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr +++ b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr @@ -5,7 +5,7 @@ LL | links: [u32; A::LINKS], // Shouldn't suggest bounds already there. | ^^^^^^^^ cannot perform const operation using `A` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index f1f22e2342d..ce7fce25993 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -5,7 +5,7 @@ LL | let _: [u8; foo::<T>()]; | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:16:23 @@ -14,7 +14,7 @@ LL | let _: [u8; bar::<N>()]; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:18:23 @@ -23,7 +23,7 @@ LL | let _: [u8; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:20:23 @@ -32,7 +32,7 @@ LL | let _: [u8; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:21:23 @@ -41,7 +41,7 @@ LL | let _: [u8; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:23:23 @@ -50,7 +50,7 @@ LL | let _: [u8; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:26:23 @@ -59,7 +59,7 @@ LL | let _ = [0; bar::<N>()]; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:28:23 @@ -68,7 +68,7 @@ LL | let _ = [0; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:30:23 @@ -77,7 +77,7 @@ LL | let _ = [0; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:31:23 @@ -86,7 +86,7 @@ LL | let _ = [0; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:33:23 @@ -95,7 +95,7 @@ LL | let _ = [0; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:34:24 @@ -104,7 +104,7 @@ LL | let _: Foo<{ foo::<T>() }>; | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:35:24 @@ -113,7 +113,7 @@ LL | let _: Foo<{ bar::<N>() }>; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:37:24 @@ -122,7 +122,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:39:24 @@ -131,7 +131,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:40:24 @@ -140,7 +140,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:42:24 @@ -149,7 +149,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:43:27 @@ -158,7 +158,7 @@ LL | let _ = Foo::<{ foo::<T>() }>; | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:44:27 @@ -167,7 +167,7 @@ LL | let _ = Foo::<{ bar::<N>() }>; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:46:27 @@ -176,7 +176,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:48:27 @@ -185,7 +185,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:49:27 @@ -194,7 +194,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:51:27 @@ -203,7 +203,7 @@ LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0747]: unresolved item provided when a constant was expected --> $DIR/const-arg-in-const-arg.rs:16:23 diff --git a/tests/ui/const-generics/const-argument-if-length.min.stderr b/tests/ui/const-generics/const-argument-if-length.min.stderr index 3ba9ffebd4d..b9d9bcc9270 100644 --- a/tests/ui/const-generics/const-argument-if-length.min.stderr +++ b/tests/ui/const-generics/const-argument-if-length.min.stderr @@ -5,7 +5,7 @@ LL | pad: [u8; is_zst::<T>()], | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/const-argument-if-length.rs:15:12 diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr index 52b7f2a37de..a1254672c9d 100644 --- a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr +++ b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr @@ -5,7 +5,7 @@ LL | let _: &'a (); | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr b/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr index b836cfeaedb..199546c0883 100644 --- a/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr +++ b/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr @@ -5,7 +5,7 @@ LL | struct Foo<const N: usize, const M: usize = { N + 1 }>; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/complex-generic-default-expr.rs:9:62 @@ -14,7 +14,7 @@ LL | struct Bar<T, const TYPE_SIZE: usize = { std::mem::size_of::<T>() }>(T); | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/early/macro_rules-braces.stderr b/tests/ui/const-generics/early/macro_rules-braces.stderr index 49382dbf0bd..32695066801 100644 --- a/tests/ui/const-generics/early/macro_rules-braces.stderr +++ b/tests/ui/const-generics/early/macro_rules-braces.stderr @@ -27,7 +27,7 @@ LL | let _: foo!({{ N }}); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/macro_rules-braces.rs:36:19 @@ -36,7 +36,7 @@ LL | let _: bar!({ N }); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/macro_rules-braces.rs:41:20 @@ -45,7 +45,7 @@ LL | let _: baz!({{ N }}); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/macro_rules-braces.rs:46:19 @@ -54,7 +54,7 @@ LL | let _: biz!({ N }); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr index 64d1e0bcff4..1f4b892e20f 100644 --- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr @@ -5,7 +5,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/array-size-in-generic-struct-param.rs:23:15 @@ -14,7 +14,7 @@ LL | arr: [u8; CFG.arr_size], | ^^^ cannot perform const operation using `CFG` | = help: const parameters may only be used as standalone arguments, i.e. `CFG` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: `Config` is forbidden as the type of a const generic parameter --> $DIR/array-size-in-generic-struct-param.rs:21:21 diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr index d674e3acdff..f454ff4e6c0 100644 --- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr @@ -5,7 +5,7 @@ LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/dependence_lint.rs:21:37 @@ -14,7 +14,7 @@ LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions warning: cannot use constants which depend on generic parameters in types --> $DIR/dependence_lint.rs:10:9 diff --git a/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr index 3b456324819..9c4e3d8583c 100644 --- a/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr +++ b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr @@ -5,7 +5,7 @@ LL | type Arr<const N: usize> = [u8; N - 1]; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index ea6f5f69276..2454b311921 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -5,7 +5,7 @@ LL | Condition<{ LHS <= RHS }>: True | ^^^ cannot perform const operation using `LHS` | = help: const parameters may only be used as standalone arguments, i.e. `LHS` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/issue-72787.rs:11:24 @@ -14,7 +14,7 @@ LL | Condition<{ LHS <= RHS }>: True | ^^^ cannot perform const operation using `RHS` | = help: const parameters may only be used as standalone arguments, i.e. `RHS` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/issue-72787.rs:23:25 @@ -23,7 +23,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | ^ cannot perform const operation using `I` | = help: const parameters may only be used as standalone arguments, i.e. `I` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/issue-72787.rs:23:36 @@ -32,7 +32,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | ^ cannot perform const operation using `J` | = help: const parameters may only be used as standalone arguments, i.e. `J` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr index ef9ee6d7cfc..c504464127a 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr @@ -5,7 +5,7 @@ LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr index f0e0a4b9711..78717028f65 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr @@ -5,7 +5,7 @@ LL | let _: &'a (); | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0308]: mismatched types --> $DIR/issue-74713.rs:3:10 diff --git a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr index 4c45339b93b..95f75c32186 100644 --- a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr +++ b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr @@ -5,7 +5,7 @@ LL | T: Trait<{std::intrinsics::type_name::<T>()}> | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/intrinsics-type_name-as-const-argument.rs:10:22 diff --git a/tests/ui/const-generics/issue-46511.stderr b/tests/ui/const-generics/issue-46511.stderr index 58c93a1fab4..d57295fa2fa 100644 --- a/tests/ui/const-generics/issue-46511.stderr +++ b/tests/ui/const-generics/issue-46511.stderr @@ -5,7 +5,7 @@ LL | _a: [u8; std::mem::size_of::<&'a mut u8>()] | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0392]: parameter `'a` is never used --> $DIR/issue-46511.rs:3:12 diff --git a/tests/ui/const-generics/issues/issue-67375.min.stderr b/tests/ui/const-generics/issues/issue-67375.min.stderr index 5256d96c876..7671e3c4688 100644 --- a/tests/ui/const-generics/issues/issue-67375.min.stderr +++ b/tests/ui/const-generics/issues/issue-67375.min.stderr @@ -5,7 +5,7 @@ LL | inner: [(); { [|_: &T| {}; 0].len() }], | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0392]: parameter `T` is never used --> $DIR/issue-67375.rs:5:12 diff --git a/tests/ui/const-generics/issues/issue-67945-1.min.stderr b/tests/ui/const-generics/issues/issue-67945-1.min.stderr index eee04eb75a2..1d071da903f 100644 --- a/tests/ui/const-generics/issues/issue-67945-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-1.min.stderr @@ -5,7 +5,7 @@ LL | let x: S = MaybeUninit::uninit(); | ^ cannot perform const operation using `S` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/issue-67945-1.rs:13:45 @@ -14,7 +14,7 @@ LL | let b = &*(&x as *const _ as *const S); | ^ cannot perform const operation using `S` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0392]: parameter `S` is never used --> $DIR/issue-67945-1.rs:7:12 diff --git a/tests/ui/const-generics/issues/issue-67945-3.min.stderr b/tests/ui/const-generics/issues/issue-67945-3.min.stderr index 8e6b4b20409..e34869c7938 100644 --- a/tests/ui/const-generics/issues/issue-67945-3.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-3.min.stderr @@ -5,7 +5,7 @@ LL | let x: Option<S> = None; | ^ cannot perform const operation using `S` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0392]: parameter `S` is never used --> $DIR/issue-67945-3.rs:9:12 diff --git a/tests/ui/const-generics/issues/issue-67945-4.min.stderr b/tests/ui/const-generics/issues/issue-67945-4.min.stderr index f9520872ddd..280c6f4f2cd 100644 --- a/tests/ui/const-generics/issues/issue-67945-4.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-4.min.stderr @@ -5,7 +5,7 @@ LL | let x: Option<Box<S>> = None; | ^ cannot perform const operation using `S` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0392]: parameter `S` is never used --> $DIR/issue-67945-4.rs:8:12 diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index 3740ced90b1..ecf24a356de 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -5,7 +5,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {} | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates --> $DIR/issue-68366.rs:11:7 diff --git a/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr b/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr index 3b53e18e6f5..da2fbc52a6c 100644 --- a/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr +++ b/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr @@ -5,7 +5,7 @@ LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] { | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/issue-76701-ty-param-in-const.rs:6:42 @@ -14,7 +14,7 @@ LL | fn const_param<const N: usize>() -> [u8; N + 1] { | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-80062.stderr b/tests/ui/const-generics/issues/issue-80062.stderr index 5f53dca4bed..5da8e45fac8 100644 --- a/tests/ui/const-generics/issues/issue-80062.stderr +++ b/tests/ui/const-generics/issues/issue-80062.stderr @@ -5,7 +5,7 @@ LL | let _: [u8; sof::<T>()]; | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-80375.stderr b/tests/ui/const-generics/issues/issue-80375.stderr index 6abbf1c0f75..015196f8605 100644 --- a/tests/ui/const-generics/issues/issue-80375.stderr +++ b/tests/ui/const-generics/issues/issue-80375.stderr @@ -5,7 +5,7 @@ LL | struct MyArray<const COUNT: usize>([u8; COUNT + 1]); | ^^^^^ cannot perform const operation using `COUNT` | = help: const parameters may only be used as standalone arguments, i.e. `COUNT` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/legacy-const-generics-bad.stderr b/tests/ui/const-generics/legacy-const-generics-bad.stderr index 3c78dd6c780..83c71e07253 100644 --- a/tests/ui/const-generics/legacy-const-generics-bad.stderr +++ b/tests/ui/const-generics/legacy-const-generics-bad.stderr @@ -13,7 +13,7 @@ LL | legacy_const_generics::foo(0, N + 1, 2); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/min_const_generics/complex-expression.stderr b/tests/ui/const-generics/min_const_generics/complex-expression.stderr index deabd05a6d5..3affdcf9b03 100644 --- a/tests/ui/const-generics/min_const_generics/complex-expression.stderr +++ b/tests/ui/const-generics/min_const_generics/complex-expression.stderr @@ -5,7 +5,7 @@ LL | struct Break0<const N: usize>([u8; { N + 1 }]); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:13:40 @@ -14,7 +14,7 @@ LL | struct Break1<const N: usize>([u8; { { N } }]); | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:17:17 @@ -23,7 +23,7 @@ LL | let _: [u8; N + 1]; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:22:17 @@ -32,7 +32,7 @@ LL | let _ = [0; N + 1]; | ^ cannot perform const operation using `N` | = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:26:45 @@ -41,7 +41,7 @@ LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]); | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:29:47 @@ -50,7 +50,7 @@ LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]); | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:33:32 @@ -59,7 +59,7 @@ LL | let _: [u8; size_of::<*mut T>() + 1]; | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions warning: cannot use constants which depend on generic parameters in types --> $DIR/complex-expression.rs:38:17 diff --git a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr index 7726016eb83..909b0476999 100644 --- a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr +++ b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr @@ -5,7 +5,7 @@ LL | test::<{ let _: &'a (); 3 },>(); | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations --> $DIR/forbid-non-static-lifetimes.rs:21:16 @@ -14,7 +14,7 @@ LL | [(); (|_: &'a u8| (), 0).1]; | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr index 16a7687c00b..e9216fc12a2 100644 --- a/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr +++ b/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr @@ -5,7 +5,7 @@ LL | fn t1() -> [u8; std::mem::size_of::<Self>()]; | ^^^^ cannot perform const operation using `Self` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic `Self` types are currently not permitted in anonymous constants --> $DIR/self-ty-in-const-1.rs:12:41 diff --git a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr index 5a947677678..38b25445f61 100644 --- a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr +++ b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr @@ -5,7 +5,7 @@ LL | let x: &'a (); | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr index a5e70f6b9e6..320c9c1c84d 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr @@ -11,7 +11,7 @@ LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U); | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0128]: generic parameters with a default cannot use forward declared identifiers --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 diff --git a/tests/ui/consts/const-eval/size-of-t.stderr b/tests/ui/consts/const-eval/size-of-t.stderr index ff09f5aee1c..418ac6f612c 100644 --- a/tests/ui/consts/const-eval/size-of-t.stderr +++ b/tests/ui/consts/const-eval/size-of-t.stderr @@ -5,7 +5,7 @@ LL | let _arr: [u8; size_of::<T>()]; | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/consts/raw-ptr-const.rs b/tests/ui/consts/raw-ptr-const.rs index fc774be54df..541c5fd1ab1 100644 --- a/tests/ui/consts/raw-ptr-const.rs +++ b/tests/ui/consts/raw-ptr-const.rs @@ -1,4 +1,4 @@ -// This is a regression test for a `delay_span_bug` during interning when a constant +// This is a regression test for a `span_delayed_bug` during interning when a constant // evaluates to a (non-dangling) raw pointer. For now this errors; potentially it // could also be allowed. diff --git a/tests/ui/error-codes/E0458.stderr b/tests/ui/error-codes/E0458.stderr index e641bba541e..c13ae4e7862 100644 --- a/tests/ui/error-codes/E0458.stderr +++ b/tests/ui/error-codes/E0458.stderr @@ -1,4 +1,4 @@ -error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib +error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib, link-arg --> $DIR/E0458.rs:1:15 | LL | #[link(kind = "wonderful_unicorn")] extern "C" {} diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs b/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs new file mode 100644 index 00000000000..9036095fbc4 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs @@ -0,0 +1,5 @@ +#[link(kind = "link-arg", name = "foo")] +//~^ ERROR link kind `link-arg` is unstable +extern "C" {} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr b/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr new file mode 100644 index 00000000000..673835b8b9e --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr @@ -0,0 +1,12 @@ +error[E0658]: link kind `link-arg` is unstable + --> $DIR/feature-gate-link-arg-attribute.rs:1:15 + | +LL | #[link(kind = "link-arg", name = "foo")] + | ^^^^^^^^^^ + | + = note: see issue #99427 <https://github.com/rust-lang/rust/issues/99427> for more information + = help: add `#![feature(link_arg_attribute)]` to the crate attributes to enable + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/generic-associated-types/bugs/issue-88382.stderr b/tests/ui/generic-associated-types/bugs/issue-88382.stderr index 624fe2799e0..9b061528e3b 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88382.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88382.stderr @@ -16,6 +16,10 @@ note: required by a bound in `do_something` | LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something` +help: consider wrapping the function in a closure + | +LL | do_something(SomeImplementation(), |arg0: &mut std::iter::Empty<usize>| test(/* &mut <_ as Iterable>::Iterator<'_> */)); + | ++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/generics/param-in-ct-in-ty-param-default.stderr b/tests/ui/generics/param-in-ct-in-ty-param-default.stderr index 3d2a26e33c3..03dbb3eb9fc 100644 --- a/tests/ui/generics/param-in-ct-in-ty-param-default.stderr +++ b/tests/ui/generics/param-in-ct-in-ty-param-default.stderr @@ -5,7 +5,7 @@ LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U); | ^ cannot perform const operation using `T` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr index 83791f0d3af..046d35e4e4a 100644 --- a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr +++ b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: no errors encountered even though `delay_span_bug` issued +error: internal compiler error: no errors encountered even though `span_delayed_bug` issued error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }) } }} | diff --git a/tests/ui/imports/no-pub-reexports-but-used.rs b/tests/ui/imports/no-pub-reexports-but-used.rs new file mode 100644 index 00000000000..28991bde829 --- /dev/null +++ b/tests/ui/imports/no-pub-reexports-but-used.rs @@ -0,0 +1,15 @@ +// check-pass +// https://github.com/rust-lang/rust/issues/115966 + +mod m { + pub(crate) type A = u8; +} + +#[warn(unused_imports)] //~ NOTE: the lint level is defined here +pub use m::*; +//~^ WARNING: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough +//~| NOTE: the most public imported item is `pub(crate)` + +fn main() { + let _: A; +} diff --git a/tests/ui/imports/no-pub-reexports-but-used.stderr b/tests/ui/imports/no-pub-reexports-but-used.stderr new file mode 100644 index 00000000000..b693dea1935 --- /dev/null +++ b/tests/ui/imports/no-pub-reexports-but-used.stderr @@ -0,0 +1,20 @@ +warning: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough + --> $DIR/no-pub-reexports-but-used.rs:9:9 + | +LL | pub use m::*; + | ^^^^ + | +note: the most public imported item is `pub(crate)` + --> $DIR/no-pub-reexports-but-used.rs:9:9 + | +LL | pub use m::*; + | ^^^^ + = help: reduce the glob import's visibility or increase visibility of imported items +note: the lint level is defined here + --> $DIR/no-pub-reexports-but-used.rs:8:8 + | +LL | #[warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/imports/reexports.rs b/tests/ui/imports/reexports.rs index cb1a3ebe180..2a1a62834ce 100644 --- a/tests/ui/imports/reexports.rs +++ b/tests/ui/imports/reexports.rs @@ -9,7 +9,7 @@ mod a { //~^ ERROR cannot be re-exported //~| WARNING unused import: `super::foo` pub use super::*; - //~^ WARNING glob import doesn't reexport anything because no candidate is public enough + //~^ WARNING glob import doesn't reexport anything with visibility `pub` because no imported item is public enough //~| WARNING unused import: `super::*` } } diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr index 401e422af0f..bf4ba474875 100644 --- a/tests/ui/imports/reexports.stderr +++ b/tests/ui/imports/reexports.stderr @@ -56,11 +56,18 @@ note: the lint level is defined here LL | #![warn(unused_imports)] | ^^^^^^^^^^^^^^ -warning: glob import doesn't reexport anything because no candidate is public enough +warning: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough --> $DIR/reexports.rs:11:17 | LL | pub use super::*; | ^^^^^^^^ + | +note: the most public imported item is `pub(a)` + --> $DIR/reexports.rs:11:17 + | +LL | pub use super::*; + | ^^^^^^^^ + = help: reduce the glob import's visibility or increase visibility of imported items warning: unused import: `super::*` --> $DIR/reexports.rs:11:17 diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr index e6ff9d5a0df..bf91dc72cc1 100644 --- a/tests/ui/intrinsics/const-eval-select-bad.stderr +++ b/tests/ui/intrinsics/const-eval-select-bad.stderr @@ -86,6 +86,10 @@ LL | const_eval_select((true,), foo, baz); found function signature `fn(i32) -> _` note: required by a bound in `const_eval_select` --> $SRC_DIR/core/src/intrinsics.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | const_eval_select((true,), |arg0: bool| foo(/* i32 */), baz); + | ++++++++++++ +++++++++++ error: this argument must be a `const fn` --> $DIR/const-eval-select-bad.rs:42:29 diff --git a/tests/ui/issues/issue-76077.stderr b/tests/ui/issues/issue-76077.stderr index 4c510e91ada..3fef5ffce30 100644 --- a/tests/ui/issues/issue-76077.stderr +++ b/tests/ui/issues/issue-76077.stderr @@ -4,7 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields LL | foo::Foo {}; | ^^^^^^^^ | - = note: ... and other private field `you_cant_use_this_field` that was not provided + = note: private field `you_cant_use_this_field` that was not provided error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr index 02ca10b2eb6..ec4aea62391 100644 --- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr +++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr @@ -5,7 +5,7 @@ LL | beta: [(); foo::<&'a ()>()], | ^^ cannot perform const operation using `'a` | = note: lifetime parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic `Self` types are currently not permitted in anonymous constants --> $DIR/issue-64173-unused-lifetimes.rs:4:28 diff --git a/tests/ui/mismatched_types/E0631.stderr b/tests/ui/mismatched_types/E0631.stderr index 410ea4b0b34..9ba8f5035c5 100644 --- a/tests/ui/mismatched_types/E0631.stderr +++ b/tests/ui/mismatched_types/E0631.stderr @@ -48,6 +48,10 @@ note: required by a bound in `foo` | LL | fn foo<F: Fn(usize)>(_: F) {} | ^^^^^^^^^ required by this bound in `foo` +help: consider wrapping the function in a closure + | +LL | foo(|arg0: usize| f(/* u64 */)); + | +++++++++++++ +++++++++++ error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:10:9 @@ -67,6 +71,10 @@ note: required by a bound in `bar` | LL | fn bar<F: Fn<(usize,)>>(_: F) {} | ^^^^^^^^^^^^ required by this bound in `bar` +help: consider wrapping the function in a closure + | +LL | bar(|arg0: usize| f(/* u64 */)); + | +++++++++++++ +++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/mismatched_types/closure-ref-114180.stderr b/tests/ui/mismatched_types/closure-ref-114180.stderr index 798c4e00aa7..27649822e69 100644 --- a/tests/ui/mismatched_types/closure-ref-114180.stderr +++ b/tests/ui/mismatched_types/closure-ref-114180.stderr @@ -12,6 +12,10 @@ LL | v.sort_by(compare); found closure signature `fn((_,), (_,)) -> _` note: required by a bound in `slice::<impl [T]>::sort_by` --> $SRC_DIR/alloc/src/slice.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | v.sort_by(|arg0, arg1| compare(*arg0, *arg1)); + | ++++++++++++ ++++++++++++++ help: consider adjusting the signature so it borrows its arguments | LL | let compare = |&(a,), &(e,)| todo!(); diff --git a/tests/ui/mismatched_types/fn-variance-1.stderr b/tests/ui/mismatched_types/fn-variance-1.stderr index 5794e606eeb..fdb2e6f0097 100644 --- a/tests/ui/mismatched_types/fn-variance-1.stderr +++ b/tests/ui/mismatched_types/fn-variance-1.stderr @@ -16,6 +16,10 @@ note: required by a bound in `apply` | LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) { | ^^^^^^^^^ required by this bound in `apply` +help: consider wrapping the function in a closure + | +LL | apply(&3, |x| takes_mut(&mut *x)); + | +++ +++++++++ error[E0631]: type mismatch in function arguments --> $DIR/fn-variance-1.rs:15:19 @@ -35,6 +39,10 @@ note: required by a bound in `apply` | LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) { | ^^^^^^^^^ required by this bound in `apply` +help: consider wrapping the function in a closure + | +LL | apply(&mut 3, |x| takes_imm(&*x)); + | +++ +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr b/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr index 3db9803d58f..0ed57466e9c 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr @@ -13,6 +13,10 @@ LL | let _has_inference_vars: Option<i32> = Some(0).map(deref_int); found function signature `for<'a> fn(&'a i32) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | let _has_inference_vars: Option<i32> = Some(0).map(|a| deref_int(&a)); + | +++ ++++ help: consider adjusting the signature so it does not borrow its argument | LL - fn deref_int(a: &i32) -> i32 { diff --git a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr index 3175a258906..1ac057a5f38 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr @@ -13,6 +13,10 @@ LL | let _ = produces_string().and_then(takes_str_but_too_many_refs); found function signature `for<'a, 'b> fn(&'a &'b str) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | let _ = produces_string().and_then(|arg0: String| takes_str_but_too_many_refs(/* &&str */)); + | ++++++++++++++ +++++++++++++ error[E0277]: expected a `FnOnce(String)` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}` --> $DIR/suggest-option-asderef-unfixable.rs:26:40 @@ -68,6 +72,10 @@ LL | let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs); found function signature `for<'a, 'b> fn(&'a &'b str) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | let _ = Some(TypeWithoutDeref).and_then(|arg0: TypeWithoutDeref| takes_str_but_too_many_refs(/* &&str */)); + | ++++++++++++++++++++++++ +++++++++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/mismatched_types/suggest-option-asderef.fixed b/tests/ui/mismatched_types/suggest-option-asderef.fixed deleted file mode 100644 index fc488b790b3..00000000000 --- a/tests/ui/mismatched_types/suggest-option-asderef.fixed +++ /dev/null @@ -1,39 +0,0 @@ -// run-rustfix - -fn produces_string() -> Option<String> { - Some("my cool string".to_owned()) -} - -fn takes_str(_: &str) -> Option<()> { - Some(()) -} - -fn takes_str_mut(_: &mut str) -> Option<()> { - Some(()) -} - -fn generic<T>(_: T) -> Option<()> { - Some(()) -} - -fn generic_ref<T>(_: T) -> Option<()> { - //~^ HELP consider adjusting the signature so it does not borrow its argument - Some(()) -} - -fn main() { - let _: Option<()> = produces_string().as_deref().and_then(takes_str); - //~^ ERROR type mismatch in function arguments - //~| HELP call `Option::as_deref()` first - let _: Option<Option<()>> = produces_string().as_deref().map(takes_str); - //~^ ERROR type mismatch in function arguments - //~| HELP call `Option::as_deref()` first - let _: Option<Option<()>> = produces_string().as_deref_mut().map(takes_str_mut); - //~^ ERROR type mismatch in function arguments - //~| HELP call `Option::as_deref_mut()` first - let _ = produces_string().and_then(generic); - - let _ = produces_string().as_deref().and_then(generic_ref); - //~^ ERROR type mismatch in function arguments - //~| HELP call `Option::as_deref()` first -} diff --git a/tests/ui/mismatched_types/suggest-option-asderef.rs b/tests/ui/mismatched_types/suggest-option-asderef.rs index 28f46808a39..5f5617e1741 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef.rs +++ b/tests/ui/mismatched_types/suggest-option-asderef.rs @@ -1,4 +1,4 @@ -// run-rustfix +// this isn't auto-fixable now because we produce two similar suggestions fn produces_string() -> Option<String> { Some("my cool string".to_owned()) @@ -25,15 +25,19 @@ fn main() { let _: Option<()> = produces_string().and_then(takes_str); //~^ ERROR type mismatch in function arguments //~| HELP call `Option::as_deref()` first + //~| HELP consider wrapping the function in a closure let _: Option<Option<()>> = produces_string().map(takes_str); //~^ ERROR type mismatch in function arguments //~| HELP call `Option::as_deref()` first + //~| HELP consider wrapping the function in a closure let _: Option<Option<()>> = produces_string().map(takes_str_mut); //~^ ERROR type mismatch in function arguments //~| HELP call `Option::as_deref_mut()` first + //~| HELP consider wrapping the function in a closure let _ = produces_string().and_then(generic); let _ = produces_string().and_then(generic_ref); //~^ ERROR type mismatch in function arguments //~| HELP call `Option::as_deref()` first + //~| HELP consider wrapping the function in a closure } diff --git a/tests/ui/mismatched_types/suggest-option-asderef.stderr b/tests/ui/mismatched_types/suggest-option-asderef.stderr index bfea0867350..1702a7f1dec 100644 --- a/tests/ui/mismatched_types/suggest-option-asderef.stderr +++ b/tests/ui/mismatched_types/suggest-option-asderef.stderr @@ -13,13 +13,17 @@ LL | let _: Option<()> = produces_string().and_then(takes_str); found function signature `for<'a> fn(&'a str) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | let _: Option<()> = produces_string().and_then(|arg0: String| takes_str(/* &str */)); + | ++++++++++++++ ++++++++++++ help: call `Option::as_deref()` first | LL | let _: Option<()> = produces_string().as_deref().and_then(takes_str); | +++++++++++ error[E0631]: type mismatch in function arguments - --> $DIR/suggest-option-asderef.rs:28:55 + --> $DIR/suggest-option-asderef.rs:29:55 | LL | fn takes_str(_: &str) -> Option<()> { | ----------------------------------- found signature defined here @@ -33,13 +37,17 @@ LL | let _: Option<Option<()>> = produces_string().map(takes_str); found function signature `for<'a> fn(&'a str) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | let _: Option<Option<()>> = produces_string().map(|arg0: String| takes_str(/* &str */)); + | ++++++++++++++ ++++++++++++ help: call `Option::as_deref()` first | LL | let _: Option<Option<()>> = produces_string().as_deref().map(takes_str); | +++++++++++ error[E0631]: type mismatch in function arguments - --> $DIR/suggest-option-asderef.rs:31:55 + --> $DIR/suggest-option-asderef.rs:33:55 | LL | fn takes_str_mut(_: &mut str) -> Option<()> { | ------------------------------------------- found signature defined here @@ -53,13 +61,17 @@ LL | let _: Option<Option<()>> = produces_string().map(takes_str_mut); found function signature `for<'a> fn(&'a mut str) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | let _: Option<Option<()>> = produces_string().map(|arg0: String| takes_str_mut(/* &mut str */)); + | ++++++++++++++ ++++++++++++++++ help: call `Option::as_deref_mut()` first | LL | let _: Option<Option<()>> = produces_string().as_deref_mut().map(takes_str_mut); | +++++++++++++++ error[E0631]: type mismatch in function arguments - --> $DIR/suggest-option-asderef.rs:36:40 + --> $DIR/suggest-option-asderef.rs:39:40 | LL | fn generic_ref<T>(_: &T) -> Option<()> { | -------------------------------------- found signature defined here @@ -73,6 +85,10 @@ LL | let _ = produces_string().and_then(generic_ref); found function signature `for<'a> fn(&'a _) -> _` note: required by a bound in `Option::<T>::and_then` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | let _ = produces_string().and_then(|arg0: String| generic_ref(&arg0)); + | ++++++++++++++ +++++++ help: consider adjusting the signature so it does not borrow its argument | LL - fn generic_ref<T>(_: &T) -> Option<()> { diff --git a/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index a900a49c710..d92d5dbd16f 100644 --- a/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -16,6 +16,10 @@ note: required by a bound in `call_it` | LL | fn call_it<F: FnMut(isize, isize) -> isize>(y: isize, mut f: F) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call_it` +help: consider wrapping the function in a closure + | +LL | let z = call_it(3, |arg0: isize, arg1: isize| f(/* usize */, arg1)); + | ++++++++++++++++++++++++++ +++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/native-library-link-flags/link-arg-from-rs.rs b/tests/ui/native-library-link-flags/link-arg-from-rs.rs index 075e4d9e79e..4a6017fea33 100644 --- a/tests/ui/native-library-link-flags/link-arg-from-rs.rs +++ b/tests/ui/native-library-link-flags/link-arg-from-rs.rs @@ -1,8 +1,7 @@ -// link-arg is not supposed to be usable in #[link] attributes +#![feature(link_arg_attribute)] -// compile-flags: -// error-pattern: error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib - -#[link(kind = "link-arg")] +#[link(kind = "link-arg", name = "arg", modifiers = "+bundle")] +//~^ ERROR linking modifier `bundle` is only compatible with `static` linking kind extern "C" {} + pub fn main() {} diff --git a/tests/ui/native-library-link-flags/link-arg-from-rs.stderr b/tests/ui/native-library-link-flags/link-arg-from-rs.stderr index 69a7825c0b1..f31e15f1da6 100644 --- a/tests/ui/native-library-link-flags/link-arg-from-rs.stderr +++ b/tests/ui/native-library-link-flags/link-arg-from-rs.stderr @@ -1,16 +1,8 @@ -error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib - --> $DIR/link-arg-from-rs.rs:6:15 +error: linking modifier `bundle` is only compatible with `static` linking kind + --> $DIR/link-arg-from-rs.rs:3:53 | -LL | #[link(kind = "link-arg")] - | ^^^^^^^^^^ unknown link kind +LL | #[link(kind = "link-arg", name = "arg", modifiers = "+bundle")] + | ^^^^^^^^^ -error[E0459]: `#[link]` attribute requires a `name = "string"` argument - --> $DIR/link-arg-from-rs.rs:6:1 - | -LL | #[link(kind = "link-arg")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0458, E0459. -For more information about an error, try `rustc --explain E0458`. diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs b/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs new file mode 100644 index 00000000000..5fabf31cecd --- /dev/null +++ b/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs @@ -0,0 +1,46 @@ +// This is a non-regression test about differences in scopes computed by NLLs and `-Zpolonius=next` +// found during the crater run for PR #117593. +// +// Live loans were computed too early compared to some of the liveness data coming from later passes +// than `liveness::trace`, on some specific CFGs shapes: a variable was dead during tracing but its +// regions were marked live later, and live loans were not recomputed at this point. + +// check-pass +// revisions: nll polonius +// [polonius] compile-flags: -Zpolonius=next + +// minimized from wavefc-cli-3.0.0 +fn repro1() { + let a = 0; + let closure = || { + let _b = a; + }; + + let callback = if true { Some(closure) } else { None }; + do_it(callback); +} +fn do_it<F>(_: Option<F>) +where + F: Fn(), +{ +} + +// minimized from simple-server-0.4.0 +fn repro2() { + let mut a = &(); + let s = S(&mut a); + let _ = if true { Some(s) } else { None }; +} +struct S<'a>(&'a mut &'a ()); + +// minimized from https://github.com/SHaaD94/AICup2022 +fn repro3() { + let runner = (); + let writer = debug_interface(&runner); + let _ = if true { Some(writer) } else { None }; +} +fn debug_interface(_: &()) -> &mut dyn std::io::Write { + unimplemented!() +} + +fn main() {} diff --git a/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr b/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr index df5968ba323..93a39edbb82 100644 --- a/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr +++ b/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr @@ -22,12 +22,18 @@ note: consider marking `Full` as `pub` in the imported module LL | pub use self::Lieutenant::{JuniorGrade, Full}; | ^^^^ -error: glob import doesn't reexport anything because no candidate is public enough +error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13 | LL | pub use self::Professor::*; | ^^^^^^^^^^^^^^^^^^ | +note: the most public imported item is `pub(self)` + --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13 + | +LL | pub use self::Professor::*; + | ^^^^^^^^^^^^^^^^^^ + = help: reduce the glob import's visibility or increase visibility of imported items note: the lint level is defined here --> $DIR/issue-46209-private-enum-variant-reexport.rs:1:8 | @@ -46,11 +52,18 @@ error: unused imports: `Full`, `JuniorGrade` LL | pub use self::Lieutenant::{JuniorGrade, Full}; | ^^^^^^^^^^^ ^^^^ -error: glob import doesn't reexport anything because no candidate is public enough +error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough + --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13 + | +LL | pub use self::PettyOfficer::*; + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: the most public imported item is `pub(self)` --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13 | LL | pub use self::PettyOfficer::*; | ^^^^^^^^^^^^^^^^^^^^^ + = help: reduce the glob import's visibility or increase visibility of imported items error: unused import: `self::PettyOfficer::*` --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13 @@ -58,11 +71,18 @@ error: unused import: `self::PettyOfficer::*` LL | pub use self::PettyOfficer::*; | ^^^^^^^^^^^^^^^^^^^^^ -error: glob import doesn't reexport anything because no candidate is public enough +error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough + --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13 + | +LL | pub use self::Crewman::*; + | ^^^^^^^^^^^^^^^^ + | +note: the most public imported item is `pub(crate)` --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13 | LL | pub use self::Crewman::*; | ^^^^^^^^^^^^^^^^ + = help: reduce the glob import's visibility or increase visibility of imported items error: unused import: `self::Crewman::*` --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13 diff --git a/tests/ui/privacy/issue-79593.stderr b/tests/ui/privacy/issue-79593.stderr index 21ba760ad0b..5bb69836f60 100644 --- a/tests/ui/privacy/issue-79593.stderr +++ b/tests/ui/privacy/issue-79593.stderr @@ -16,7 +16,7 @@ error: cannot construct `Pub` with struct literal syntax due to private fields LL | foo::Pub {}; | ^^^^^^^^ | - = note: ... and other private field `private` that was not provided + = note: private field `private` that was not provided error[E0063]: missing field `y` in initializer of `Enum` --> $DIR/issue-79593.rs:23:5 diff --git a/tests/ui/privacy/private-variant-reexport.stderr b/tests/ui/privacy/private-variant-reexport.stderr index 2f041934a81..d73bd1a8cc2 100644 --- a/tests/ui/privacy/private-variant-reexport.stderr +++ b/tests/ui/privacy/private-variant-reexport.stderr @@ -30,12 +30,18 @@ LL | pub use ::E::V::{self}; | = note: consider declaring type or module `V` with `pub` -error: glob import doesn't reexport anything because no candidate is public enough +error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough --> $DIR/private-variant-reexport.rs:15:13 | LL | pub use ::E::*; | ^^^^^^ | +note: the most public imported item is `pub(crate)` + --> $DIR/private-variant-reexport.rs:15:13 + | +LL | pub use ::E::*; + | ^^^^^^ + = help: reduce the glob import's visibility or increase visibility of imported items note: the lint level is defined here --> $DIR/private-variant-reexport.rs:13:8 | diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index 2224f1c60d6..8b01e8c3c10 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -56,7 +56,7 @@ error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to pri LL | let _ = std::collections::HashMap {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: ... and other private field `base` that was not provided + = note: private field `base` that was not provided help: you might have meant to use an associated function to build this type | LL | let _ = std::collections::HashMap::new(); @@ -78,7 +78,7 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi LL | let _ = Box {}; | ^^^ | - = note: ... and other private fields `0` and `1` that were not provided + = note: private fields `0` and `1` that were not provided help: you might have meant to use an associated function to build this type | LL | let _ = Box::new(_); diff --git a/tests/ui/proc-macro/literal-to-string.rs b/tests/ui/proc-macro/literal-to-string.rs index 494d17cbeea..eb009036a9a 100644 --- a/tests/ui/proc-macro/literal-to-string.rs +++ b/tests/ui/proc-macro/literal-to-string.rs @@ -1,6 +1,5 @@ // check-pass // edition: 2021 -#![feature(c_str_literals)] // aux-build: print-tokens.rs extern crate print_tokens; diff --git a/tests/ui/proc-macro/literal-to-string.stdout b/tests/ui/proc-macro/literal-to-string.stdout index 7b27fcf798b..ec6427545f4 100644 --- a/tests/ui/proc-macro/literal-to-string.stdout +++ b/tests/ui/proc-macro/literal-to-string.stdout @@ -3,91 +3,91 @@ TokenStream [ kind: Integer, symbol: "1", suffix: None, - span: #0 bytes(172..173), + span: #0 bytes(144..145), }, Literal { kind: Integer, symbol: "17", suffix: Some("u8"), - span: #0 bytes(182..186), + span: #0 bytes(154..158), }, Literal { kind: Float, symbol: "42.", suffix: None, - span: #0 bytes(195..198), + span: #0 bytes(167..170), }, Literal { kind: Float, symbol: "3.14", suffix: Some("f32"), - span: #0 bytes(207..214), + span: #0 bytes(179..186), }, Literal { kind: Byte, symbol: "a", suffix: None, - span: #0 bytes(223..227), + span: #0 bytes(195..199), }, Literal { kind: Byte, symbol: "\xFF", suffix: None, - span: #0 bytes(236..243), + span: #0 bytes(208..215), }, Literal { kind: Char, symbol: "c", suffix: None, - span: #0 bytes(252..255), + span: #0 bytes(224..227), }, Literal { kind: Char, symbol: "\x32", suffix: None, - span: #0 bytes(264..270), + span: #0 bytes(236..242), }, Literal { kind: Str, symbol: "\\"str\\"", suffix: None, - span: #0 bytes(279..288), + span: #0 bytes(251..260), }, Literal { kind: StrRaw(1), symbol: "\"raw\" str", suffix: None, - span: #0 bytes(297..311), + span: #0 bytes(269..283), }, Literal { kind: StrRaw(3), symbol: "very ##\"raw\"## str", suffix: None, - span: #0 bytes(320..347), + span: #0 bytes(292..319), }, Literal { kind: ByteStr, symbol: "\\"byte\\" str", suffix: None, - span: #0 bytes(356..371), + span: #0 bytes(328..343), }, Literal { kind: ByteStrRaw(1), symbol: "\"raw\" \"byte\" str", suffix: None, - span: #0 bytes(380..402), + span: #0 bytes(352..374), }, Literal { kind: CStr, symbol: "\\"c\\" str", suffix: None, - span: #0 bytes(411..423), + span: #0 bytes(383..395), }, Literal { kind: CStrRaw(1), symbol: "\"raw\" \"c\" str", suffix: None, - span: #0 bytes(432..451), + span: #0 bytes(404..423), }, ] 1 diff --git a/tests/ui/resolve/issue-39559.stderr b/tests/ui/resolve/issue-39559.stderr index e7d26d63be3..0aab54fe59d 100644 --- a/tests/ui/resolve/issue-39559.stderr +++ b/tests/ui/resolve/issue-39559.stderr @@ -5,7 +5,7 @@ LL | entries: [T; D::dim()], | ^^^^^^ cannot perform const operation using `D` | = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs index 5037396000b..5609dc51a67 100644 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs @@ -1,8 +1,6 @@ // run-pass // edition: 2021 -#![feature(c_str_literals)] - fn main() { assert_eq!(b"test\0", c"test".to_bytes_with_nul()); } diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs deleted file mode 100644 index ddd6d9a25da..00000000000 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs +++ /dev/null @@ -1,15 +0,0 @@ -// gate-test-c_str_literals -// known-bug: #113333 -// edition: 2021 - -macro_rules! m { - ($t:tt) => {} -} - -fn main() { - c"foo"; - // FIXME(c_str_literals): This should be ``c".."` literals are experimental` - - m!(c"test"); - // FIXME(c_str_literals): This should be ``c".."` literals are experimental` -} diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr deleted file mode 100644 index ea666e43308..00000000000 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: `c".."` literals are experimental - --> $DIR/gate.rs:10:5 - | -LL | c"foo"; - | ^^^^^^ - | - = note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information - = help: add `#![feature(c_str_literals)]` to the crate attributes to enable - -error[E0658]: `c".."` literals are experimental - --> $DIR/gate.rs:13:8 - | -LL | m!(c"test"); - | ^^^^^^^ - | - = note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information - = help: add `#![feature(c_str_literals)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs index 369173e2318..a7e36b2233e 100644 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs Binary files differdiff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr index 82d9f9cb320..ff9006f6f97 100644 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr Binary files differdiff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs index 380445d7a7f..8a5f514db7f 100644 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs @@ -1,8 +1,6 @@ // run-pass // edition: 2021 -#![feature(c_str_literals)] - fn main() { assert_eq!( c"\xEF\x80🦀\u{1F980}".to_bytes_with_nul(), diff --git a/tests/ui/suggestions/enum-variant-arg-mismatch.stderr b/tests/ui/suggestions/enum-variant-arg-mismatch.stderr index 6d72dabf70e..16f03d16d8c 100644 --- a/tests/ui/suggestions/enum-variant-arg-mismatch.stderr +++ b/tests/ui/suggestions/enum-variant-arg-mismatch.stderr @@ -16,6 +16,10 @@ note: required by a bound in `map` | LL | fn map<'a, F: Fn(String) -> Sexpr<'a>>(f: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` +help: consider wrapping the function in a closure + | +LL | map(|arg0: String| Sexpr::Ident(/* &str */)); + | ++++++++++++++ ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr b/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr index d78de6a460c..ee924522564 100644 --- a/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr +++ b/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr @@ -16,6 +16,10 @@ note: required by a bound in `Trader::<'a>::set_closure` | LL | pub fn set_closure(&mut self, function: impl Fn(&mut Trader) + 'a) { | ^^^^^^^^^^^^^^^ required by this bound in `Trader::<'a>::set_closure` +help: consider wrapping the function in a closure + | +LL | trader.set_closure(|arg0: &mut Trader<'_>| closure(*arg0)); + | +++++++++++++++++++++++ +++++++ help: consider adjusting the signature so it borrows its argument | LL | let closure = |trader : &mut Trader| { diff --git a/tests/ui/traits/subtype-recursion-limit.rs b/tests/ui/traits/subtype-recursion-limit.rs new file mode 100644 index 00000000000..5804748844e --- /dev/null +++ b/tests/ui/traits/subtype-recursion-limit.rs @@ -0,0 +1,17 @@ +// Variant of #117151 when the overflow comes entirely from subtype predicates. + +#![allow(unreachable_code)] + +use std::ptr; + +fn main() { + // Give x and y completely unconstrained types. Using a function call + // or `as` cast would create a well-formed predicate. + let x = return; + let y = return; + let mut w = (x, y); + //~^ ERROR overflow evaluating the requirement + // Avoid creating lifetimes, `Sized` bounds or function calls. + let a = (ptr::addr_of!(y), ptr::addr_of!(x)); + w = a; +} diff --git a/tests/ui/traits/subtype-recursion-limit.stderr b/tests/ui/traits/subtype-recursion-limit.stderr new file mode 100644 index 00000000000..5310f822cc3 --- /dev/null +++ b/tests/ui/traits/subtype-recursion-limit.stderr @@ -0,0 +1,9 @@ +error[E0275]: overflow evaluating the requirement `_ <: *const _` + --> $DIR/subtype-recursion-limit.rs:12:17 + | +LL | let mut w = (x, y); + | ^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/well-formed-recursion-limit.rs b/tests/ui/traits/well-formed-recursion-limit.rs new file mode 100644 index 00000000000..056cf947d4b --- /dev/null +++ b/tests/ui/traits/well-formed-recursion-limit.rs @@ -0,0 +1,27 @@ +// Regression test for #117151, this used to hang the compiler + +pub type ISO<A: 'static, B: 'static> = (Box<dyn Fn(A) -> B>, Box<dyn Fn(B) -> A>); +pub fn iso<A: 'static, B: 'static, F1, F2>(a: F1, b: F2) -> ISO<A, B> +where + F1: 'static + Fn(A) -> B, + F2: 'static + Fn(B) -> A, +{ + (Box::new(a), Box::new(b)) +} +pub fn iso_un_option<A: 'static, B: 'static>(i: ISO<Option<A>, Option<B>>) -> ISO<A, B> { + let (ab, ba) = (i.ab, i.ba); + //~^ ERROR no field `ab` on type + //~| ERROR no field `ba` on type + let left = move |o_a| match o_a { + //~^ ERROR overflow evaluating the requirement + None => panic!("absured"), + Some(a) => a, + }; + let right = move |o_b| match o_b { + None => panic!("absurd"), + Some(b) => b, + }; + iso(left, right) +} + +fn main() {} diff --git a/tests/ui/traits/well-formed-recursion-limit.stderr b/tests/ui/traits/well-formed-recursion-limit.stderr new file mode 100644 index 00000000000..6f5fda02315 --- /dev/null +++ b/tests/ui/traits/well-formed-recursion-limit.stderr @@ -0,0 +1,22 @@ +error[E0609]: no field `ab` on type `(Box<(dyn Fn(Option<A>) -> Option<B> + 'static)>, Box<(dyn Fn(Option<B>) -> Option<A> + 'static)>)` + --> $DIR/well-formed-recursion-limit.rs:12:23 + | +LL | let (ab, ba) = (i.ab, i.ba); + | ^^ unknown field + +error[E0609]: no field `ba` on type `(Box<(dyn Fn(Option<A>) -> Option<B> + 'static)>, Box<(dyn Fn(Option<B>) -> Option<A> + 'static)>)` + --> $DIR/well-formed-recursion-limit.rs:12:29 + | +LL | let (ab, ba) = (i.ab, i.ba); + | ^^ unknown field + +error[E0275]: overflow evaluating the requirement `_ <: Option<_>` + --> $DIR/well-formed-recursion-limit.rs:15:33 + | +LL | let left = move |o_a| match o_a { + | ^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0275, E0609. +For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/treat-err-as-bug/delay_span_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs index f667f8eb996..dda35b9b92a 100644 --- a/tests/ui/treat-err-as-bug/delay_span_bug.rs +++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs @@ -1,12 +1,12 @@ // compile-flags: -Ztreat-err-as-bug // failure-status: 101 // error-pattern: aborting due to `-Z treat-err-as-bug=1` -// error-pattern: [trigger_delay_span_bug] triggering a delay span bug for testing incremental +// error-pattern: [trigger_span_delayed_bug] triggering a span delayed bug for testing incremental // normalize-stderr-test "note: .*\n\n" -> "" // normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" // rustc-env:RUST_BACKTRACE=0 #![feature(rustc_attrs)] -#[rustc_error(delay_span_bug_from_inside_query)] +#[rustc_error(span_delayed_bug_from_inside_query)] fn main() {} diff --git a/tests/ui/treat-err-as-bug/delay_span_bug.stderr b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr index 06a31ae86b2..a61ffaea8c2 100644 --- a/tests/ui/treat-err-as-bug/delay_span_bug.stderr +++ b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr @@ -1,5 +1,5 @@ -error: internal compiler error: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)] - --> $DIR/delay_span_bug.rs:12:1 +error: internal compiler error: delayed span bug triggered by #[rustc_error(span_delayed_bug_from_inside_query)] + --> $DIR/span_delayed_bug.rs:12:1 | LL | fn main() {} | ^^^^^^^^^ @@ -7,5 +7,5 @@ LL | fn main() {} error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [trigger_delay_span_bug] triggering a delay span bug for testing incremental +#0 [trigger_span_delayed_bug] triggering a span delayed bug for testing incremental end of query stack diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr index 844103d77a8..d4e2f953533 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: no errors encountered even though `delay_span_bug` issued +error: internal compiler error: no errors encountered even though `span_delayed_bug` issued error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }) } }} | diff --git a/tests/ui/type-inference/generalize-subtyped-variables.rs b/tests/ui/type-inference/generalize-subtyped-variables.rs new file mode 100644 index 00000000000..f93408a43db --- /dev/null +++ b/tests/ui/type-inference/generalize-subtyped-variables.rs @@ -0,0 +1,25 @@ +// Test for specific details of how we handle higher-ranked subtyping to make +// sure that any changes are made deliberately. +// +// - `let y = x` creates a `Subtype` obligation that is deferred for later. +// - `w = a` sets the type of `x` to `Option<for<'a> fn(&'a ())>` and generalizes +// `z` first to `Option<_>` and then to `Option<fn(&'0 ())>`. +// - The various subtyping obligations are then processed. +// +// This requires that +// 1. the `Subtype` obligation from `y = x` isn't processed while the types of +// `w` and `a` are being unified. +// 2. the pending subtype obligation isn't considered when determining the type +// to generalize `z` to first (when related to the type of `y`). +// +// Found when considering fixes to #117151 +// check-pass + +fn main() { + let mut x = None; + let y = x; + let z = Default::default(); + let mut w = (&mut x, z, z); + let a = (&mut None::<fn(&())>, y, None::<fn(&'static ())>); + w = a; +} diff --git a/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr b/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr index eab494ffbdf..899dd02583a 100644 --- a/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr +++ b/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr @@ -4,7 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields LL | foo::Foo {}; | ^^^^^^^^ | - = note: ... and other private field `you_cant_use_this_field` that was not provided + = note: private field `you_cant_use_this_field` that was not provided error: aborting due to 1 previous error diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr index 51491407c49..41391720a28 100644 --- a/tests/ui/typeck/mismatched-map-under-self.stderr +++ b/tests/ui/typeck/mismatched-map-under-self.stderr @@ -30,6 +30,10 @@ LL | self.map(Insertable::values).unwrap_or_default() found function signature `for<'a> fn(&'a _) -> _` note: required by a bound in `Option::<T>::map` --> $SRC_DIR/core/src/option.rs:LL:COL +help: consider wrapping the function in a closure + | +LL | self.map(|arg0: T| Insertable::values(&arg0)).unwrap_or_default() + | +++++++++ +++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr b/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr index 96998ca244d..003eaa40592 100644 --- a/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr +++ b/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr @@ -9,7 +9,7 @@ LL | a: (), LL | b: (), | ----- private field | - = note: ... and other private fields `c`, `d` and `e` that were not provided + = note: ...and other private fields `c`, `d` and `e` that were not provided error: aborting due to 1 previous error diff --git a/triagebot.toml b/triagebot.toml index ed9d59b1bb9..24926690cfe 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -627,7 +627,7 @@ cc = ["@nnethercote"] [assign] warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" -users_on_vacation = ["jyn514", "oli-obk"] +users_on_vacation = ["jyn514", "oli-obk", "wesleywiser"] [assign.adhoc_groups] compiler-team = [ |
