diff options
839 files changed, 7684 insertions, 5252 deletions
diff --git a/.gitmodules b/.gitmodules index f5025097a18..9bb68b37081 100644 --- a/.gitmodules +++ b/.gitmodules @@ -33,7 +33,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/17.0-2023-09-19 + branch = rustc/17.0-2023-12-14 shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book diff --git a/Cargo.lock b/Cargo.lock index 9f82b2e1640..98c030b3996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -548,7 +548,7 @@ dependencies = [ "futures", "if_chain", "itertools", - "parking_lot 0.12.1", + "parking_lot", "quote", "regex", "rustc_tools_util", @@ -867,16 +867,6 @@ dependencies = [ ] [[package]] -name = "cstr" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] name = "ctrlc" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2366,13 +2356,13 @@ dependencies = [ [[package]] name = "measureme" -version = "10.1.1" +version = "10.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1930d162935fecd56fc4e0f6729eb3483bac1264542eb4ea31570b86a434b6bc" +checksum = "45e381dcdad44c3c435f8052b08c5c4a1449c48ab56f312345eae12d7a693dbe" dependencies = [ "log", "memmap2", - "parking_lot 0.11.2", + "parking_lot", "perf-event-open-sys", "rustc-hash", "smallvec", @@ -2792,37 +2782,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - -[[package]] -name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -3582,7 +3547,6 @@ name = "rustc_codegen_llvm" version = "0.0.0" dependencies = [ "bitflags 1.3.2", - "cstr", "itertools", "libc", "measureme", @@ -3693,7 +3657,7 @@ dependencies = [ "libc", "measureme", "memmap2", - "parking_lot 0.12.1", + "parking_lot", "portable-atomic", "rustc-hash", "rustc-rayon", @@ -4428,7 +4392,7 @@ dependencies = [ name = "rustc_query_system" version = "0.0.0" dependencies = [ - "parking_lot 0.12.1", + "parking_lot", "rustc-rayon-core", "rustc_ast", "rustc_data_structures", @@ -5145,7 +5109,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "phf_shared", "precomputed-hash", "serde", @@ -5670,7 +5634,7 @@ dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "regex", "sharded-slab", "smallvec", diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 050366b081f..5252472261f 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -382,7 +382,7 @@ pub trait LayoutCalculator { *offset += this_offset; } } - _ => { + FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => { panic!("Layout of fields should be Arbitrary for variants") } } @@ -600,7 +600,9 @@ pub trait LayoutCalculator { variant.size = new_ity_size; } } - _ => panic!(), + FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => { + panic!("encountered a non-arbitrary layout during enum layout") + } } } } @@ -628,7 +630,7 @@ pub trait LayoutCalculator { let mut common_prim_initialized_in_all_variants = true; for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) { let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else { - panic!(); + panic!("encountered a non-arbitrary layout during enum layout"); }; // We skip *all* ZST here and later check if we are good in terms of alignment. // This lets us handle some cases involving aligned ZST. @@ -681,7 +683,7 @@ pub trait LayoutCalculator { assert_eq!(memory_index.raw, [0, 1]); offsets } - _ => panic!(), + _ => panic!("encountered a non-arbitrary layout during enum layout"), }; if pair_offsets[FieldIdx::new(0)] == Size::ZERO && pair_offsets[FieldIdx::new(1)] == *offset @@ -758,7 +760,9 @@ pub trait LayoutCalculator { Variants::Multiple { tag, tag_encoding, tag_field, .. } => { Variants::Multiple { tag, tag_encoding, tag_field, variants: best_layout.variants } } - _ => panic!(), + Variants::Single { .. } => { + panic!("encountered a single-variant enum during multi-variant layout") + } }; Some(best_layout.layout) } @@ -1154,7 +1158,11 @@ fn univariant< assert_eq!(memory_index.raw, [0, 1]); offsets } - _ => panic!(), + FieldsShape::Primitive + | FieldsShape::Array { .. } + | FieldsShape::Union(..) => { + panic!("encountered a non-arbitrary layout during enum layout") + } }; if offsets[i] == pair_offsets[FieldIdx::new(0)] && offsets[j] == pair_offsets[FieldIdx::new(1)] diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5755ae8a8bc..9d543563c0f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2845,6 +2845,28 @@ impl Item { pub fn span_with_attributes(&self) -> Span { self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span)) } + + pub fn opt_generics(&self) -> Option<&Generics> { + match &self.kind { + ItemKind::ExternCrate(_) + | ItemKind::Use(_) + | ItemKind::Mod(_, _) + | ItemKind::ForeignMod(_) + | ItemKind::GlobalAsm(_) + | ItemKind::MacCall(_) + | ItemKind::MacroDef(_) => None, + ItemKind::Static(_) => None, + ItemKind::Const(i) => Some(&i.generics), + ItemKind::Fn(i) => Some(&i.generics), + ItemKind::TyAlias(i) => Some(&i.generics), + ItemKind::TraitAlias(generics, _) + | ItemKind::Enum(_, generics) + | ItemKind::Struct(_, generics) + | ItemKind::Union(_, generics) => Some(&generics), + ItemKind::Trait(i) => Some(&i.generics), + ItemKind::Impl(i) => Some(&i.generics), + } + } } /// `extern` qualifier on a function item or function type. diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 7111daa2ea9..4c81983c242 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -336,7 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymFn { .. } | hir::InlineAsmOperand::SymStatic { .. } => { - unreachable!() + unreachable!("{op:?} is not a register operand"); } }; @@ -380,7 +380,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { { reg_sym.as_str() } else { - unreachable!(); + unreachable!("{op:?} is not a register operand"); } }; diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index a44b408feec..11b5131b8d7 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1222,6 +1222,8 @@ impl<'hir> LoweringContext<'_, 'hir> { | ExprKind::Struct(..) | ExprKind::Tup(..) | ExprKind::Underscore => false, + // Check for unit struct constructor. + ExprKind::Path(..) => lower_ctx.extract_unit_struct_path(lhs).is_none(), // Check for tuple struct constructor. ExprKind::Call(callee, ..) => lower_ctx.extract_tuple_struct_path(callee).is_none(), ExprKind::Paren(e) => { @@ -1258,9 +1260,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ); // `a = lhs1; b = lhs2;`. - let stmts = self - .arena - .alloc_from_iter(std::iter::once(destructure_let).chain(assignments.into_iter())); + let stmts = self.arena.alloc_from_iter(std::iter::once(destructure_let).chain(assignments)); // Wrap everything in a block. hir::ExprKind::Block(self.block_all(whole_span, stmts, None), None) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7c05724f64c..83452c22280 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -421,8 +421,13 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::MacroDef(MacroDef { body, macro_rules }) => { let body = P(self.lower_delim_args(body)); - let DefKind::Macro(macro_kind) = self.tcx.def_kind(self.local_def_id(id)) else { - unreachable!() + let def_id = self.local_def_id(id); + let def_kind = self.tcx.def_kind(def_id); + let DefKind::Macro(macro_kind) = def_kind else { + unreachable!( + "expected DefKind::Macro for macro item, found {}", + def_kind.descr(def_id.to_def_id()) + ); }; let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); hir::ItemKind::Macro(macro_def, macro_kind) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d9663d50c59..5c9e43f1e06 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -453,6 +453,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { tcx.ensure_with_value().output_filenames(()); tcx.ensure_with_value().early_lint_checks(()); tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE); + tcx.ensure_with_value().get_lang_items(()); let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal(); let ast_index = index_crate(&resolver.node_id_to_def_id, &krate); @@ -765,6 +766,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.resolver.get_import_res(id).present_items() } + fn make_lang_item_path( + &mut self, + lang_item: hir::LangItem, + span: Span, + args: Option<&'hir hir::GenericArgs<'hir>>, + ) -> &'hir hir::Path<'hir> { + let def_id = self.tcx.require_lang_item(lang_item, Some(span)); + let def_kind = self.tcx.def_kind(def_id); + let res = Res::Def(def_kind, def_id); + self.arena.alloc(hir::Path { + span, + res, + segments: self.arena.alloc_from_iter([hir::PathSegment { + ident: Ident::new(lang_item.name(), span), + hir_id: self.next_id(), + res, + args, + infer_args: false, + }]), + }) + } + /// 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( @@ -1976,18 +1999,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator), }; - let future_args = self.arena.alloc(hir::GenericArgs { + let bound_args = self.arena.alloc(hir::GenericArgs { args: &[], bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)], parenthesized: hir::GenericArgsParentheses::No, span_ext: DUMMY_SP, }); - hir::GenericBound::LangItemTrait( - trait_lang_item, - opaque_ty_span, - self.next_id(), - future_args, + hir::GenericBound::Trait( + hir::PolyTraitRef { + bound_generic_params: &[], + trait_ref: hir::TraitRef { + path: self.make_lang_item_path( + trait_lang_item, + opaque_ty_span, + Some(bound_args), + ), + hir_ref_id: self.next_id(), + }, + span: opaque_ty_span, + }, + hir::TraitBoundModifier::None, ) } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7e62bb9793d..2f366001d4b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::{ PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, }; -use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty}; +use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty, TyCtxt}; use rustc_middle::util::CallKind; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::def_id::LocalDefId; @@ -398,7 +398,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } let typeck = self.infcx.tcx.typeck(self.mir_def_id()); let hir_id = hir.parent_id(expr.hir_id); - if let Some(parent) = hir.find(hir_id) { + if let Some(parent) = self.infcx.tcx.opt_hir_node(hir_id) { let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id) @@ -413,7 +413,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (None, &[][..], 0) }; if let Some(def_id) = def_id - && let Some(node) = hir.find(self.infcx.tcx.local_def_id_to_hir_id(def_id)) + && let Some(node) = self + .infcx + .tcx + .opt_hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id)) && let Some(fn_sig) = node.fn_sig() && let Some(ident) = node.ident() && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id) @@ -1317,7 +1320,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let hir = tcx.hir(); - let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return }; + let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; let typeck_results = tcx.typeck(self.mir_def_id()); struct ExprFinder<'hir> { @@ -1509,7 +1512,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let local_ty = self.body.local_decls[local].ty; // Get the body the error happens in - let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return }; + let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; let body_expr = hir.body(body_id).value; @@ -1558,7 +1561,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Check that the parent of the closure is a method call, // with receiver matching with local's type (modulo refs) let parent = hir.parent_id(closure_expr.hir_id); - if let hir::Node::Expr(parent) = hir.get(parent) { + if let hir::Node::Expr(parent) = tcx.hir_node(parent) { if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind { let recv_ty = typeck_results.expr_ty(recv); @@ -1635,15 +1638,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { issued_spans: &UseSpans<'tcx>, ) { let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; - let hir = self.infcx.tcx.hir(); - struct ExpressionFinder<'hir> { + struct ExpressionFinder<'tcx> { capture_span: Span, closure_change_spans: Vec<Span>, closure_arg_span: Option<Span>, in_closure: bool, suggest_arg: String, - hir: rustc_middle::hir::map::Map<'hir>, + tcx: TyCtxt<'tcx>, closure_local_id: Option<hir::HirId>, closure_call_changes: Vec<(Span, String)>, } @@ -1657,7 +1659,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn_decl: hir::FnDecl { inputs, .. }, .. }) = e.kind - && let Some(hir::Node::Expr(body)) = self.hir.find(body.hir_id) + && let Some(hir::Node::Expr(body)) = self.tcx.opt_hir_node(body.hir_id) { self.suggest_arg = "this: &Self".to_string(); if inputs.len() > 0 { @@ -1722,8 +1724,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some(hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(_fn_sig, body_id), .. - })) = hir.find(self.mir_hir_id()) - && let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id) + })) = self.infcx.tcx.opt_hir_node(self.mir_hir_id()) + && let Some(hir::Node::Expr(expr)) = self.infcx.tcx.opt_hir_node(body_id.hir_id) { let mut finder = ExpressionFinder { capture_span: *capture_kind_span, @@ -1733,7 +1735,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { suggest_arg: String::new(), closure_local_id: None, closure_call_changes: vec![], - hir, + tcx: self.infcx.tcx, }; finder.visit_expr(expr); @@ -2294,7 +2296,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let proper_span = proper_span.source_callsite(); if let Some(scope) = self.body.source_scopes.get(source_info.scope) && let ClearCrossCrate::Set(scope_data) = &scope.local_data - && let Some(node) = self.infcx.tcx.hir().find(scope_data.lint_root) + && let Some(node) = self.infcx.tcx.opt_hir_node(scope_data.lint_root) && let Some(id) = node.body_id() && let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir().body(id).value.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index bed3df4809d..f1e712d814a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -87,7 +87,7 @@ impl<'tcx> BorrowExplanation<'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind && let [hir::PathSegment { ident, args: None, .. }] = p.segments && let hir::def::Res::Local(hir_id) = p.res - && let Some(hir::Node::Pat(pat)) = tcx.hir().find(hir_id) + && let Some(hir::Node::Pat(pat)) = tcx.opt_hir_node(hir_id) { err.span_label(pat.span, format!("binding `{ident}` declared here")); } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 8fe552708ed..c3c1f1293d2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -396,7 +396,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvar_hir_id = captured_place.get_root_variable(); - if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id) + if let Some(Node::Pat(pat)) = self.infcx.tcx.opt_hir_node(upvar_hir_id) && let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) = pat.kind { @@ -661,7 +661,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if self.body.local_kind(local) != LocalKind::Arg { return (false, None); } - let hir_map = self.infcx.tcx.hir(); let my_def = self.body.source.def_id(); let my_hir = self.infcx.tcx.local_def_id_to_hir_id(my_def.as_local().unwrap()); let Some(td) = @@ -671,7 +670,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; ( true, - td.as_local().and_then(|tld| match hir_map.find_by_def_id(tld) { + td.as_local().and_then(|tld| match self.infcx.tcx.opt_hir_node_by_def_id(tld) { Some(Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, _, _, _, items), .. @@ -682,25 +681,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if !matches!(k, hir::AssocItemKind::Fn { .. }) { continue; } - if hir_map.name(hi) != hir_map.name(my_hir) { + if self.infcx.tcx.hir().name(hi) != self.infcx.tcx.hir().name(my_hir) { continue; } f_in_trait_opt = Some(hi); break; } - f_in_trait_opt.and_then(|f_in_trait| match hir_map.find(f_in_trait) { - Some(Node::TraitItem(hir::TraitItem { - kind: - hir::TraitItemKind::Fn( - hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. }, - _, - ), - .. - })) => { - let hir::Ty { span, .. } = inputs[local.index() - 1]; - Some(span) + f_in_trait_opt.and_then(|f_in_trait| { + match self.infcx.tcx.opt_hir_node(f_in_trait) { + Some(Node::TraitItem(hir::TraitItem { + kind: + hir::TraitItemKind::Fn( + hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. }, + _, + ), + .. + })) => { + let hir::Ty { span, .. } = inputs[local.index() - 1]; + Some(span) + } + _ => None, } - _ => None, }) } _ => None, @@ -741,12 +742,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); let hir_id = if let Some(local_def_id) = def_id.as_local() - && let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) + && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) { - let body = hir_map.body(body_id); + let body = self.infcx.tcx.hir().body(body_id); let mut v = BindingFinder { span: pat_span, hir_id: None }; v.visit_body(body); v.hir_id @@ -762,7 +762,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { && let Some(hir::Node::Local(hir::Local { pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, .. - })) = hir_map.find(hir_id) + })) = self.infcx.tcx.opt_hir_node(hir_id) && let Ok(name) = self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span) { @@ -942,7 +942,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let closure_id = self.mir_hir_id(); let closure_span = self.infcx.tcx.def_span(self.mir_def_id()); let fn_call_id = hir.parent_id(closure_id); - let node = hir.get(fn_call_id); + let node = self.infcx.tcx.hir_node(fn_call_id); let def_id = hir.enclosing_body_owner(fn_call_id); let mut look_at_return = true; // If we can detect the expression to be an `fn` call where the closure was an argument, @@ -1001,7 +1001,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if look_at_return && hir.get_return_block(closure_id).is_some() { // ...otherwise we are probably in the tail expression of the function, point at the // return type. - match hir.get_by_def_id(hir.get_parent_item(fn_call_id).def_id) { + match self.infcx.tcx.hir_node_by_def_id(hir.get_parent_item(fn_call_id).def_id) { hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. }) | hir::Node::TraitItem(hir::TraitItem { ident, @@ -1199,12 +1199,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { hir::intravisit::walk_stmt(self, s); } } - let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); let hir_id = if let Some(local_def_id) = def_id.as_local() - && let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) + && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) { - let body = hir_map.body(body_id); + let body = self.infcx.tcx.hir().body(body_id); let mut v = BindingFinder { span: err_label_span, hir_id: None }; v.visit_body(body); v.hir_id @@ -1213,7 +1212,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; if let Some(hir_id) = hir_id - && let Some(hir::Node::Local(local)) = hir_map.find(hir_id) + && let Some(hir::Node::Local(local)) = self.infcx.tcx.opt_hir_node(hir_id) { let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap()); if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait() @@ -1496,7 +1495,7 @@ fn get_mut_span_in_struct_field<'tcx>( && let ty::Adt(def, _) = ty.kind() && let field = def.all_fields().nth(field.index())? // Use the HIR types to construct the diagnostic message. - && let node = tcx.hir().find_by_def_id(field.did.as_local()?)? + && let node = tcx.opt_hir_node_by_def_id(field.did.as_local()?)? // Now we're dealing with the actual struct that we're going to suggest a change to, // we can expect a field that is an immutable reference to a type. && let hir::Node::Field(field) = node diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index a17c3bc3a78..8441dfaa7df 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -672,7 +672,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let mir_hir_id = self.mir_hir_id(); - let (return_span, mir_description, hir_ty) = match hir.get(mir_hir_id) { + let (return_span, mir_description, hir_ty) = match tcx.hir_node(mir_hir_id) { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl, body, fn_decl_span, .. }), .. @@ -689,7 +689,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { hir::CoroutineSource::Closure => " of async closure", hir::CoroutineSource::Fn => { let parent_item = - hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from async fn should be in fn") @@ -706,7 +706,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { hir::CoroutineSource::Closure => " of gen closure", hir::CoroutineSource::Fn => { let parent_item = - hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from gen fn should be in fn") @@ -721,7 +721,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { hir::CoroutineSource::Closure => " of async gen closure", hir::CoroutineSource::Fn => { let parent_item = - hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from async gen fn should be in fn") @@ -788,28 +788,18 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }; let opaque_ty = hir.item(id); if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { - bounds: - [ - hir::GenericBound::LangItemTrait( - hir::LangItem::Future, - _, - _, - hir::GenericArgs { - bindings: - [ - hir::TypeBinding { - ident: Ident { name: sym::Output, .. }, - kind: - hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) }, - .. - }, - ], - .. - }, - ), - ], + bounds: [hir::GenericBound::Trait(trait_ref, _)], .. }) = opaque_ty.kind + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(args) = segment.args + && let [ + hir::TypeBinding { + ident: Ident { name: sym::Output, .. }, + kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) }, + .. + }, + ] = args.bindings { ty } else { @@ -841,7 +831,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let type_name = self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).name; - let yield_span = match tcx.hir().get(self.mir_hir_id()) { + let yield_span = match tcx.hir_node(self.mir_hir_id()) { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 3d3fd412ae0..7e0e598cd9f 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2502,8 +2502,8 @@ mod error { if !self.errors.buffered.is_empty() { self.errors.buffered.sort_by_key(|diag| diag.sort_span); - for mut diag in self.errors.buffered.drain(..) { - self.infcx.tcx.sess.diagnostic().emit_diagnostic(&mut diag); + for diag in self.errors.buffered.drain(..) { + self.infcx.tcx.sess.diagnostic().emit_diagnostic(diag); } } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index c93cfa78832..3764e4c4008 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -315,7 +315,7 @@ fn check_opaque_type_well_formed<'tcx>( parent_def_id = tcx.local_parent(parent_def_id); } - // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error` + // FIXME(-Znext-solver): We probably should use `DefiningAnchor::Error` // and prepopulate this `InferCtxt` with known opaque values, rather than // using the `Bind` anchor here. For now it's fine. let infcx = tcx diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index e782221a4c2..98c21693cf0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1003,16 +1003,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { reported_errors: Default::default(), }; - // FIXME(-Ztrait-solver=next): A bit dubious that we're only registering + // FIXME(-Znext-solver): A bit dubious that we're only registering // predefined opaques in the typeck root. if infcx.next_trait_solver() && !infcx.tcx.is_typeck_child(body.source.def_id()) { - checker.register_predefined_opaques_in_new_solver(); + checker.register_predefined_opaques_for_next_solver(); } checker } - pub(super) fn register_predefined_opaques_in_new_solver(&mut self) { + pub(super) fn register_predefined_opaques_for_next_solver(&mut self) { // OK to use the identity arguments for each opaque type key, since // we remap opaques from HIR typeck back to their definition params. let opaques: Vec<_> = self diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 0a3af2c2e13..3d02cd72e54 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -453,7 +453,7 @@ impl<'a> IntoDiagnostic<'a> for EnvNotDefinedWithUserMessage { rustc::untranslatable_diagnostic, reason = "cannot translate user-provided messages" )] - let mut diag = handler.struct_diagnostic(self.msg_from_user.to_string()); + let mut diag = handler.struct_err(self.msg_from_user.to_string()); diag.set_span(self.span); diag } @@ -804,7 +804,7 @@ pub(crate) struct AsmClobberNoReg { impl<'a> IntoDiagnostic<'a> for AsmClobberNoReg { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut diag = - handler.struct_diagnostic(crate::fluent_generated::builtin_macros_asm_clobber_no_reg); + handler.struct_err(crate::fluent_generated::builtin_macros_asm_clobber_no_reg); diag.set_span(self.spans.clone()); // eager translation as `span_labels` takes `AsRef<str>` let lbl1 = handler.eagerly_translate_to_string( diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index 3309a0a6abd..1a38d5967f4 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs @@ -75,11 +75,6 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ "example/arbitrary_self_types_pointers_and_wrappers.rs", &[], ), - TestCase::build_bin_and_run( - "aot.issue_91827_extern_types", - "example/issue-91827-extern-types.rs", - &[], - ), TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"), TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]), TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""), diff --git a/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs b/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs index 14bd23e77ea..25bfe542d22 100644 --- a/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs +++ b/compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs @@ -1,7 +1,7 @@ // Copied from https://github.com/rust-lang/rust/blob/46455dc65069387f2dc46612f13fd45452ab301a/tests/ui/coroutine/gen_block_iterate.rs // revisions: next old //compile-flags: --edition 2024 -Zunstable-options -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // run-pass #![feature(gen_blocks)] diff --git a/compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs b/compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs deleted file mode 100644 index 6f39c5edcad..00000000000 --- a/compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copied from rustc ui test suite - -// run-pass -// -// Test that we can handle unsized types with an extern type tail part. -// Regression test for issue #91827. - -#![feature(extern_types)] - -use std::ptr::addr_of; - -extern "C" { - type Opaque; -} - -unsafe impl Sync for Opaque {} - -#[repr(C)] -pub struct List<T> { - len: usize, - data: [T; 0], - tail: Opaque, -} - -#[repr(C)] -pub struct ListImpl<T, const N: usize> { - len: usize, - data: [T; N], -} - -impl<T> List<T> { - const fn as_slice(&self) -> &[T] { - unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) } - } -} - -impl<T, const N: usize> ListImpl<T, N> { - const fn as_list(&self) -> &List<T> { - unsafe { std::mem::transmute(self) } - } -} - -pub static A: ListImpl<u128, 3> = ListImpl { len: 3, data: [5, 6, 7] }; -pub static A_REF: &'static List<u128> = A.as_list(); -pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list()); - -const fn tail_offset<T>(list: &List<T>) -> isize { - unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) } -} - -fn main() { - assert_eq!(A_REF.as_slice(), &[5, 6, 7]); - // Check that interpreter and code generation agree about the position of the tail field. - assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF)); -} diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index c8c098e2973..7c7044830f3 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -90,7 +90,7 @@ fn create_wrapper_function( .collect(); let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, from_name, false); - if tcx.sess.target.options.default_hidden_visibility { + if tcx.sess.default_hidden_visibility() { #[cfg(feature="master")] func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); } diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 1248fdcd259..2aa84f26797 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -2,12 +2,10 @@ use gccjit::Context; use smallvec::{smallvec, SmallVec}; -use rustc_codegen_ssa::target_features::{ - supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES, -}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::bug; use rustc_session::Session; +use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; use crate::errors::{PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature, UnknownCTargetFeaturePrefix}; @@ -44,7 +42,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri ); // -Ctarget-features - let supported_features = supported_target_features(sess); + let supported_features = sess.target.supported_target_features(); let mut featsmap = FxHashMap::default(); let feats = sess.opts.cg.target_feature .split(',') @@ -187,7 +185,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> // Given a map from target_features to whether they are enabled or disabled, // ensure only valid combinations are allowed. pub fn check_tied_features(sess: &Session, features: &FxHashMap<&str, bool>) -> Option<&'static [&'static str]> { - for tied in tied_target_features(sess) { + for tied in sess.target.tied_target_features() { // Tied features must be set to the same value, or not set at all let mut tied_iter = tied.iter(); let enabled = features.get(tied_iter.next().unwrap()); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index d54057615d2..0ececc5dda0 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -97,7 +97,6 @@ use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn}; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; -use rustc_codegen_ssa::target_features::supported_target_features; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods}; @@ -397,7 +396,9 @@ fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel { } pub fn target_features(sess: &Session, allow_unstable: bool, target_info: &LockedTargetInfo) -> Vec<Symbol> { - supported_target_features(sess) + sess + .target + .supported_target_features() .iter() .filter_map( |&(feature, gate)| { diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 580ef9b06e7..7122c055e7e 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -9,7 +9,6 @@ test = false [dependencies] # tidy-alphabetical-start bitflags = "1.0" -cstr = "0.2" itertools = "0.11" libc = "0.2" measureme = "10.0.0" diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 798014d668e..58b3aa438c5 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -76,7 +76,7 @@ pub(crate) unsafe fn codegen( // __rust_alloc_error_handler_should_panic let name = OomStrategy::SYMBOL; let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); - if tcx.sess.target.default_hidden_visibility { + if tcx.sess.default_hidden_visibility() { llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); } let val = tcx.sess.opts.unstable_opts.oom.should_panic(); @@ -85,7 +85,7 @@ pub(crate) unsafe fn codegen( let name = NO_ALLOC_SHIM_IS_UNSTABLE; let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); - if tcx.sess.target.default_hidden_visibility { + if tcx.sess.default_hidden_visibility() { llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden); } let llval = llvm::LLVMConstInt(i8, 0, False); @@ -130,7 +130,7 @@ fn create_wrapper_function( None }; - if tcx.sess.target.default_hidden_visibility { + if tcx.sess.default_hidden_visibility() { llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); } if tcx.sess.must_emit_unwind_tables() { @@ -146,7 +146,7 @@ fn create_wrapper_function( } llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden); - let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast()); + let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr().cast()); let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 97444f1a5bd..c9e109a5d23 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -631,7 +631,7 @@ pub(crate) fn run_pass_manager( llvm::LLVMRustAddModuleFlag( module.module_llvm.llmod(), llvm::LLVMModFlagBehavior::Error, - "LTOPostLink\0".as_ptr().cast(), + c"LTOPostLink".as_ptr().cast(), 1, ); } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bdabb9129a7..048f66ad148 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -916,6 +916,7 @@ fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool { cgcx.opts.target_triple.triple().contains("-aix") } +//FIXME use c string literals here too pub(crate) fn bitcode_section_name(cgcx: &CodegenContext<LlvmCodegenBackend>) -> &'static str { if target_is_apple(cgcx) { "__LLVM,__bitcode\0" @@ -994,7 +995,7 @@ unsafe fn embed_bitcode( let llglobal = llvm::LLVMAddGlobal( llmod, common::val_ty(llconst), - "rustc.embedded.module\0".as_ptr().cast(), + c"rustc.embedded.module".as_ptr().cast(), ); llvm::LLVMSetInitializer(llglobal, llconst); @@ -1007,15 +1008,15 @@ unsafe fn embed_bitcode( let llglobal = llvm::LLVMAddGlobal( llmod, common::val_ty(llconst), - "rustc.embedded.cmdline\0".as_ptr().cast(), + c"rustc.embedded.cmdline".as_ptr().cast(), ); llvm::LLVMSetInitializer(llglobal, llconst); let section = if is_apple { - "__LLVM,__cmdline\0" + c"__LLVM,__cmdline" } else if is_aix { - ".info\0" + c".info" } else { - ".llvmcmd\0" + c".llvmcmd" }; llvm::LLVMSetSection(llglobal, section.as_ptr().cast()); llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index b659fd02eec..5dc271ccddb 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -19,8 +19,6 @@ use crate::context::CodegenCx; use crate::llvm; use crate::value::Value; -use cstr::cstr; - use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::*; @@ -110,11 +108,11 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen // Create the llvm.used and llvm.compiler.used variables. if !cx.used_statics.borrow().is_empty() { - cx.create_used_variable_impl(cstr!("llvm.used"), &*cx.used_statics.borrow()); + cx.create_used_variable_impl(c"llvm.used", &*cx.used_statics.borrow()); } if !cx.compiler_used_statics.borrow().is_empty() { cx.create_used_variable_impl( - cstr!("llvm.compiler.used"), + c"llvm.compiler.used", &*cx.compiler_used_statics.borrow(), ); } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index acd85dd9a2d..8f60175a603 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -7,7 +7,6 @@ use crate::llvm_util; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use cstr::cstr; use libc::{c_char, c_uint}; use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; @@ -27,7 +26,6 @@ use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange}; use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target}; use smallvec::SmallVec; use std::borrow::Cow; -use std::ffi::CStr; use std::iter; use std::ops::Deref; use std::ptr; @@ -47,13 +45,10 @@ impl Drop for Builder<'_, '_, '_> { } } -// FIXME(eddyb) use a checked constructor when they become `const fn`. -const EMPTY_C_STR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"\0") }; - /// Empty string, to be used where LLVM expects an instruction name, indicating /// that the instruction is to be left unnamed (i.e. numbered, in textual IR). // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer. -const UNNAMED: *const c_char = EMPTY_C_STR.as_ptr(); +const UNNAMED: *const c_char = c"".as_ptr(); impl<'ll, 'tcx> BackendTypes for Builder<'_, 'll, 'tcx> { type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value; @@ -358,7 +353,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let new_kind = match ty.kind() { Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)), Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)), - t @ (Uint(_) | Int(_)) => t.clone(), + t @ (Uint(_) | Int(_)) => *t, _ => panic!("tried to get overflow intrinsic for op applied to non-int type"), }; @@ -1012,14 +1007,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> { - let name = cstr!("cleanuppad"); let ret = unsafe { llvm::LLVMBuildCleanupPad( self.llbuilder, parent, args.as_ptr(), args.len() as c_uint, - name.as_ptr(), + c"cleanuppad".as_ptr(), ) }; Funclet::new(ret.expect("LLVM does not have support for cleanuppad")) @@ -1033,14 +1027,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> { - let name = cstr!("catchpad"); let ret = unsafe { llvm::LLVMBuildCatchPad( self.llbuilder, parent, args.as_ptr(), args.len() as c_uint, - name.as_ptr(), + c"catchpad".as_ptr(), ) }; Funclet::new(ret.expect("LLVM does not have support for catchpad")) @@ -1052,14 +1045,13 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { unwind: Option<&'ll BasicBlock>, handlers: &[&'ll BasicBlock], ) -> &'ll Value { - let name = cstr!("catchswitch"); let ret = unsafe { llvm::LLVMBuildCatchSwitch( self.llbuilder, parent, unwind, handlers.len() as c_uint, - name.as_ptr(), + c"catchswitch".as_ptr(), ) }; let ret = ret.expect("LLVM does not have support for catchswitch"); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 21ff267ca67..77e893c815f 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -8,7 +8,6 @@ use crate::llvm::{self, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use cstr::cstr; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; @@ -473,9 +472,9 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { .all(|&byte| byte == 0); let sect_name = if all_bytes_are_zero { - cstr!("__DATA,__thread_bss") + c"__DATA,__thread_bss" } else { - cstr!("__DATA,__thread_data") + c"__DATA,__thread_data" }; llvm::LLVMSetSection(g, sect_name.as_ptr()); } @@ -504,7 +503,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { let val = llvm::LLVMMetadataAsValue(self.llcx, meta); llvm::LLVMAddNamedMetadataOperand( self.llmod, - "wasm.custom_sections\0".as_ptr().cast(), + c"wasm.custom_sections".as_ptr().cast(), val, ); } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index ed0d5e68cbf..3053c4e0daa 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -8,7 +8,6 @@ use crate::llvm_util; use crate::type_::Type; use crate::value::Value; -use cstr::cstr; use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::traits::*; @@ -215,13 +214,13 @@ pub unsafe fn create_module<'ll>( // If skipping the PLT is enabled, we need to add some module metadata // to ensure intrinsic calls don't use it. if !sess.needs_plt() { - let avoid_plt = "RtLibUseGOT\0".as_ptr().cast(); + let avoid_plt = c"RtLibUseGOT".as_ptr().cast(); llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1); } // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.) if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() { - let canonical_jump_tables = "CFI Canonical Jump Tables\0".as_ptr().cast(); + let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast(); llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Override, @@ -232,7 +231,7 @@ pub unsafe fn create_module<'ll>( // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.) if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() { - let enable_split_lto_unit = "EnableSplitLTOUnit\0".as_ptr().cast(); + let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast(); llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Override, @@ -243,7 +242,7 @@ pub unsafe fn create_module<'ll>( // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.) if sess.is_sanitizer_kcfi_enabled() { - let kcfi = "kcfi\0".as_ptr().cast(); + let kcfi = c"kcfi".as_ptr().cast(); llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1); } @@ -256,7 +255,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Warning, - "cfguard\0".as_ptr() as *const _, + c"cfguard".as_ptr() as *const _, 1, ) } @@ -265,7 +264,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Warning, - "cfguard\0".as_ptr() as *const _, + c"cfguard".as_ptr() as *const _, 2, ) } @@ -283,26 +282,26 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag( llmod, behavior, - "branch-target-enforcement\0".as_ptr().cast(), + c"branch-target-enforcement".as_ptr().cast(), bti.into(), ); llvm::LLVMRustAddModuleFlag( llmod, behavior, - "sign-return-address\0".as_ptr().cast(), + c"sign-return-address".as_ptr().cast(), pac_ret.is_some().into(), ); let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A }); llvm::LLVMRustAddModuleFlag( llmod, behavior, - "sign-return-address-all\0".as_ptr().cast(), + c"sign-return-address-all".as_ptr().cast(), pac_opts.leaf.into(), ); llvm::LLVMRustAddModuleFlag( llmod, behavior, - "sign-return-address-with-bkey\0".as_ptr().cast(), + c"sign-return-address-with-bkey".as_ptr().cast(), u32::from(pac_opts.key == PAuthKey::B), ); } else { @@ -318,7 +317,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Override, - "cf-protection-branch\0".as_ptr().cast(), + c"cf-protection-branch".as_ptr().cast(), 1, ) } @@ -326,7 +325,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Override, - "cf-protection-return\0".as_ptr().cast(), + c"cf-protection-return".as_ptr().cast(), 1, ) } @@ -335,7 +334,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Error, - "Virtual Function Elim\0".as_ptr().cast(), + c"Virtual Function Elim".as_ptr().cast(), 1, ); } @@ -345,7 +344,7 @@ pub unsafe fn create_module<'ll>( llvm::LLVMRustAddModuleFlag( llmod, llvm::LLVMModFlagBehavior::Warning, - "ehcontguard\0".as_ptr() as *const _, + c"ehcontguard".as_ptr() as *const _, 1, ) } @@ -363,7 +362,7 @@ pub unsafe fn create_module<'ll>( ); llvm::LLVMAddNamedMetadataOperand( llmod, - cstr!("llvm.ident").as_ptr(), + c"llvm.ident".as_ptr(), llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1), ); @@ -511,14 +510,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { } pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) { - let section = cstr!("llvm.metadata"); let array = self.const_array(self.type_ptr(), values); unsafe { let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr()); llvm::LLVMSetInitializer(g, array); llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage); - llvm::LLVMSetSection(g, section.as_ptr()); + llvm::LLVMSetSection(g, c"llvm.metadata".as_ptr()); } } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 425e935bc9f..d82b1e1e721 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -30,14 +30,13 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, /// Allocates the global variable responsible for the .debug_gdb_scripts binary /// section. pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Value { - let c_section_var_name = "__rustc_debug_gdb_scripts_section__\0"; - let section_var_name = &c_section_var_name[..c_section_var_name.len() - 1]; + let c_section_var_name = c"__rustc_debug_gdb_scripts_section__"; + let section_var_name = c_section_var_name.to_str().unwrap(); let section_var = unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr().cast()) }; section_var.unwrap_or_else(|| { - let section_name = b".debug_gdb_scripts\0"; let mut section_contents = Vec::new(); // Add the pretty printers for the standard library first. @@ -70,7 +69,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, ' let section_var = cx .define_global(section_var_name, llvm_type) .unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name)); - llvm::LLVMSetSection(section_var, section_name.as_ptr().cast()); + llvm::LLVMSetSection(section_var, c".debug_gdb_scripts".as_ptr().cast()); llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents)); llvm::LLVMSetGlobalConstant(section_var, llvm::True); llvm::LLVMSetUnnamedAddress(section_var, llvm::UnnamedAddr::Global); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index acd5a1ff5c6..883f82caa80 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -21,7 +21,6 @@ use crate::llvm::debuginfo::{ }; use crate::value::Value; -use cstr::cstr; use rustc_codegen_ssa::debuginfo::type_names::cpp_like_debuginfo; use rustc_codegen_ssa::debuginfo::type_names::VTableNameKind; use rustc_codegen_ssa::traits::*; @@ -608,7 +607,7 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> if let Ok(rel_path) = abs_path.strip_prefix(working_directory) { ( - working_directory.to_string_lossy().into(), + working_directory.to_string_lossy(), rel_path.to_string_lossy().into_owned(), ) } else { @@ -856,7 +855,6 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( use rustc_session::RemapFileNameExt; let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); let work_dir = tcx.sess.opts.working_dir.for_codegen(tcx.sess).to_string_lossy(); - let flags = "\0"; let output_filenames = tcx.output_filenames(()); let split_name = if tcx.sess.target_can_use_split_dwarf() { output_filenames @@ -910,7 +908,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( producer.as_ptr().cast(), producer.len(), tcx.sess.opts.optimize != config::OptLevel::No, - flags.as_ptr().cast(), + c"".as_ptr().cast(), 0, // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead // put the path supplied to `MCSplitDwarfFile` into the debug info of the final @@ -940,8 +938,7 @@ pub fn build_compile_unit_di_node<'ll, 'tcx>( ); let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata); - let llvm_gcov_ident = cstr!("llvm.gcov"); - llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, llvm_gcov_ident.as_ptr(), val); + llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, c"llvm.gcov".as_ptr(), val); } return unit_metadata; @@ -980,6 +977,27 @@ fn build_field_di_node<'ll, 'tcx>( } } +/// Returns the `DIFlags` corresponding to the visibility of the item identified by `did`. +/// +/// `DIFlags::Flag{Public,Protected,Private}` correspond to `DW_AT_accessibility` +/// (public/protected/private) aren't exactly right for Rust, but neither is `DW_AT_visibility` +/// (local/exported/qualified), and there's no way to set `DW_AT_visibility` in LLVM's API. +fn visibility_di_flags<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + did: DefId, + type_did: DefId, +) -> DIFlags { + let parent_did = cx.tcx.parent(type_did); + let visibility = cx.tcx.visibility(did); + match visibility { + Visibility::Public => DIFlags::FlagPublic, + // Private fields have a restricted visibility of the module containing the type. + Visibility::Restricted(did) if did == parent_did => DIFlags::FlagPrivate, + // `pub(crate)`/`pub(super)` visibilities are any other restricted visibility. + Visibility::Restricted(..) => DIFlags::FlagProtected, + } +} + /// Creates the debuginfo node for a Rust struct type. Maybe be a regular struct or a tuple-struct. fn build_struct_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, @@ -1003,7 +1021,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( &compute_debuginfo_type_name(cx.tcx, struct_type, false), size_and_align_of(struct_type_and_layout), Some(containing_scope), - DIFlags::FlagZero, + visibility_di_flags(cx, adt_def.did(), adt_def.did()), ), // Fields: |cx, owner| { @@ -1026,7 +1044,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( &field_name[..], (field_layout.size, field_layout.align.abi), struct_type_and_layout.fields.offset(i), - DIFlags::FlagZero, + visibility_di_flags(cx, f.did, adt_def.did()), type_di_node(cx, field_layout.ty), ) }) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 7ef185250a3..4a2861af44c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -26,8 +26,8 @@ use crate::{ enums::{tag_base_type, DiscrResult}, file_metadata, size_and_align_of, type_di_node, type_map::{self, Stub, UniqueTypeId}, - unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA, - UNKNOWN_LINE_NUMBER, + unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec, + NO_GENERICS, NO_SCOPE_METADATA, UNKNOWN_LINE_NUMBER, }, utils::DIB, }, @@ -215,7 +215,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( &enum_type_name, cx.size_and_align_of(enum_type), NO_SCOPE_METADATA, - DIFlags::FlagZero, + visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()), ), |cx, enum_type_di_node| { match enum_type_and_layout.variants { @@ -320,6 +320,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( variant_index: VariantIdx, ) -> SmallVec<&'ll DIType> { let variant_layout = enum_type_and_layout.for_variant(cx, variant_index); + let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()); let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node( cx, enum_type_and_layout, @@ -327,6 +328,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( variant_index, enum_adt_def.variant(variant_index), variant_layout, + visibility_flags, ); let tag_base_type = cx.tcx.types.u32; @@ -364,7 +366,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( // since the later is sometimes smaller (if it has fewer fields). size_and_align_of(enum_type_and_layout), Size::ZERO, - DIFlags::FlagZero, + visibility_flags, variant_struct_type_wrapper_di_node, ), unsafe { @@ -376,7 +378,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, variant_names_type_di_node, - DIFlags::FlagZero, + visibility_flags, Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)), tag_base_type_align.bits() as u32, ) @@ -403,6 +405,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( (variant_index, variant_name) }), ); + let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()); let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices .map(|variant_index| { @@ -417,6 +420,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( variant_index, variant_def, variant_layout, + visibility_flags, ); VariantFieldInfo { @@ -437,6 +441,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( tag_base_type, tag_field, untagged_variant_index, + visibility_flags, ) } @@ -744,6 +749,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>( tag_base_type, tag_field, None, + DIFlags::FlagZero, ) } @@ -758,6 +764,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( tag_base_type: Ty<'tcx>, tag_field: usize, untagged_variant_index: Option<VariantIdx>, + di_flags: DIFlags, ) -> SmallVec<&'ll DIType> { let tag_base_type_di_node = type_di_node(cx, tag_base_type); let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1); @@ -801,7 +808,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( align.bits() as u32, // Union fields are always at offset zero Size::ZERO.bits(), - DIFlags::FlagZero, + di_flags, variant_struct_type_wrapper, ) } @@ -835,7 +842,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( TAG_FIELD_NAME_128_LO, size_and_align, lo_offset, - DIFlags::FlagZero, + di_flags, type_di_node, )); @@ -855,7 +862,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( TAG_FIELD_NAME, cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty), enum_type_and_layout.fields.offset(tag_field), - DIFlags::FlagZero, + di_flags, tag_base_type_di_node, )); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index df1df6d197e..eef8dbb33b4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -250,6 +250,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( variant_index: VariantIdx, variant_def: &VariantDef, variant_layout: TyAndLayout<'tcx>, + di_flags: DIFlags, ) -> &'ll DIType { debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty); @@ -267,7 +268,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( // NOTE: We use size and align of enum_type, not from variant_layout: size_and_align_of(enum_type_and_layout), Some(enum_type_di_node), - DIFlags::FlagZero, + di_flags, ), |cx, struct_type_di_node| { (0..variant_layout.fields.count()) @@ -289,7 +290,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( &field_name, (field_layout.size, field_layout.align.abi), variant_layout.fields.offset(field_index), - DIFlags::FlagZero, + di_flags, type_di_node(cx, field_layout.ty), ) }) @@ -395,7 +396,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( }) .collect(); - state_specific_fields.into_iter().chain(common_fields.into_iter()).collect() + state_specific_fields.into_iter().chain(common_fields).collect() }, |cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty), ) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 130ca2727e4..cba4e3811d5 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -7,8 +7,8 @@ use crate::{ enums::tag_base_type, file_metadata, size_and_align_of, type_di_node, type_map::{self, Stub, StubInfo, UniqueTypeId}, - unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, - UNKNOWN_LINE_NUMBER, + unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec, + NO_GENERICS, UNKNOWN_LINE_NUMBER, }, utils::{create_DIArray, get_namespace_for_item, DIB}, }, @@ -63,6 +63,8 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( let enum_type_and_layout = cx.layout_of(enum_type); let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false); + let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()); + debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout)); type_map::build_type_with_children( @@ -74,7 +76,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( &enum_type_name, size_and_align_of(enum_type_and_layout), Some(containing_scope), - DIFlags::FlagZero, + visibility_flags, ), |cx, enum_type_di_node| { // Build the struct type for each variant. These will be referenced by the @@ -92,6 +94,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( variant_index, enum_adt_def.variant(variant_index), enum_type_and_layout.for_variant(cx, variant_index), + visibility_flags, ), source_info: None, }) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index a0ae1e9bf5d..31631e8a864 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -112,7 +112,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { llvm::LLVMRustAddModuleFlag( self.llmod, llvm::LLVMModFlagBehavior::Warning, - "Dwarf Version\0".as_ptr().cast(), + c"Dwarf Version".as_ptr().cast(), dwarf_version, ); } else { @@ -120,17 +120,16 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { llvm::LLVMRustAddModuleFlag( self.llmod, llvm::LLVMModFlagBehavior::Warning, - "CodeView\0".as_ptr().cast(), + c"CodeView".as_ptr().cast(), 1, ) } // Prevent bitcode readers from deleting the debug info. - let ptr = "Debug Info Version\0".as_ptr(); llvm::LLVMRustAddModuleFlag( self.llmod, llvm::LLVMModFlagBehavior::Warning, - ptr.cast(), + c"Debug Info Version".as_ptr().cast(), llvm::LLVMRustDebugMetadataVersion(), ); } diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 164b12cf8d4..78c0725a637 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -84,7 +84,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { fn_type: &'ll Type, ) -> &'ll Value { // Declare C ABI functions with the visibility used by C by default. - let visibility = if self.tcx.sess.target.default_hidden_visibility { + let visibility = if self.tcx.sess.default_hidden_visibility() { llvm::Visibility::Hidden } else { llvm::Visibility::Default @@ -107,7 +107,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { unnamed: llvm::UnnamedAddr, fn_type: &'ll Type, ) -> &'ll Value { - let visibility = if self.tcx.sess.target.default_hidden_visibility { + let visibility = if self.tcx.sess.default_hidden_visibility() { llvm::Visibility::Hidden } else { llvm::Visibility::Default diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 57ea13ddcd6..e6e37a02335 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -107,7 +107,8 @@ impl IntoDiagnostic<'_, FatalError> for ParseTargetMachineConfig<'_> { let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message"); let message = handler.eagerly_translate_to_string(message.clone(), diag.args()); - let mut diag = handler.struct_diagnostic(fluent::codegen_llvm_parse_target_machine_config); + let mut diag = + handler.struct_almost_fatal(fluent::codegen_llvm_parse_target_machine_config); diag.set_arg("error", message); diag } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 23b424f25ba..58e68a64907 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1568,7 +1568,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // Alignment of T, must be a constant integer value: let alignment_ty = bx.type_i32(); - let alignment = bx.const_i32(bx.align_of(values_ty).bytes() as i32); + let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32); // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 116108ae5a9..dfef2fbab56 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -8,6 +8,7 @@ #![feature(rustdoc_internals)] #![doc(rust_logo)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(bootstrap, feature(c_str_literals))] #![feature(exact_size_is_empty)] #![feature(extern_types)] #![feature(hash_raw_entry)] diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 93cb7327a01..08519723eba 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -5,9 +5,6 @@ use crate::errors::{ }; use crate::llvm; use libc::c_int; -use rustc_codegen_ssa::target_features::{ - supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES, -}; use rustc_codegen_ssa::traits::PrintBackendInfo; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::small_c_str::SmallCStr; @@ -17,6 +14,7 @@ use rustc_session::config::{PrintKind, PrintRequest}; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::{MergeFunctions, PanicStrategy}; +use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; use std::ffi::{c_char, c_void, CStr, CString}; use std::path::Path; @@ -278,7 +276,7 @@ pub fn check_tied_features( features: &FxHashMap<&str, bool>, ) -> Option<&'static [&'static str]> { if !features.is_empty() { - for tied in tied_target_features(sess) { + for tied in sess.target.tied_target_features() { // Tied features must be set to the same value, or not set at all let mut tied_iter = tied.iter(); let enabled = features.get(tied_iter.next().unwrap()); @@ -294,7 +292,8 @@ pub fn check_tied_features( /// Must express features in the way Rust understands them pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> { let target_machine = create_informational_target_machine(sess); - supported_target_features(sess) + sess.target + .supported_target_features() .iter() .filter_map(|&(feature, gate)| { if sess.is_nightly_build() || allow_unstable || gate.is_stable() { @@ -362,7 +361,9 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> { fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) { let mut llvm_target_features = llvm_target_features(tm); let mut known_llvm_target_features = FxHashSet::<&'static str>::default(); - let mut rustc_target_features = supported_target_features(sess) + let mut rustc_target_features = sess + .target + .supported_target_features() .iter() .map(|(feature, _gate)| { // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings. @@ -515,7 +516,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str ); // -Ctarget-features - let supported_features = supported_target_features(sess); + let supported_features = sess.target.supported_target_features(); let mut featsmap = FxHashMap::default(); let feats = sess .opts diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 3d479c5c22d..01d1b1059b9 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -199,8 +199,8 @@ impl fmt::Display for CguReuse { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { CguReuse::No => write!(f, "No"), - CguReuse::PreLto => write!(f, "PreLto "), - CguReuse::PostLto => write!(f, "PostLto "), + CguReuse::PreLto => write!(f, "PreLto"), + CguReuse::PostLto => write!(f, "PostLto"), } } } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 618a72272e5..40fd8c5c1d6 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1848,7 +1848,7 @@ impl SharedEmitterMain { d.code(code); } d.replace_args(diag.args); - handler.emit_diagnostic(&mut d); + handler.emit_diagnostic(d); } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string(); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 40a985cf255..015ea10d721 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -578,7 +578,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { hir_id, no_sanitize_span, "`no_sanitize` will have no effect after inlining", - |lint| lint.span_note(inline_span, "inlining requested here"), + |lint| { + lint.span_note(inline_span, "inlining requested here"); + }, ) } } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index cd5eb77e06e..9b60f0844a0 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -51,10 +51,10 @@ pub mod codegen_attrs; pub mod common; pub mod debuginfo; pub mod errors; -pub mod glue; pub mod meth; pub mod mir; pub mod mono_item; +pub mod size_of_val; pub mod target_features; pub mod traits; diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 136d06d561a..a5bffc33d39 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -4,8 +4,8 @@ use super::FunctionCx; use crate::common::IntPredicate; use crate::errors; use crate::errors::InvalidMonomorphization; -use crate::glue; use crate::meth; +use crate::size_of_val; use crate::traits::*; use crate::MemFlags; @@ -88,21 +88,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::va_end => bx.va_end(args[0].immediate()), sym::size_of_val => { let tp_ty = fn_args.type_at(0); - if let OperandValue::Pair(_, meta) = args[0].val { - let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta)); - llsize - } else { - bx.const_usize(bx.layout_of(tp_ty).size.bytes()) - } + let meta = + if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None }; + let (llsize, _) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta); + llsize } sym::min_align_of_val => { let tp_ty = fn_args.type_at(0); - if let OperandValue::Pair(_, meta) = args[0].val { - let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta)); - llalign - } else { - bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes()) - } + let meta = + if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None }; + let (_, llalign) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta); + llalign } sym::vtable_size | sym::vtable_align => { let vtable = args[0].immediate(); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index feee3ac03d0..e8c58f6b6f8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -2,7 +2,7 @@ use super::place::PlaceRef; use super::{FunctionCx, LocalRef}; use crate::base; -use crate::glue; +use crate::size_of_val; use crate::traits::*; use crate::MemFlags; @@ -466,13 +466,13 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> { .ty; let OperandValue::Ref(llptr, Some(llextra), _) = self else { - bug!("store_unsized called with a sized value") + bug!("store_unsized called with a sized value (or with an extern type)") }; // Allocate an appropriate region on the stack, and copy the value into it. Since alloca // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the // pointer manually. - let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); + let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); let one = bx.const_usize(1); let align_minus_1 = bx.sub(align, one); let size_extra = bx.add(size, align_minus_1); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 83425dee1a8..c0bb3ac5661 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -2,7 +2,7 @@ use super::operand::OperandValue; use super::{FunctionCx, LocalRef}; use crate::common::IntPredicate; -use crate::glue; +use crate::size_of_val; use crate::traits::*; use rustc_middle::mir; @@ -99,6 +99,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let offset = self.layout.fields.offset(ix); let effective_field_align = self.align.restrict_for_offset(offset); + // `simple` is called when we don't need to adjust the offset to + // the dynamic alignment of the field. let mut simple = || { let llval = match self.layout.abi { _ if offset.bytes() == 0 => { @@ -141,28 +143,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { }; // Simple cases, which don't need DST adjustment: - // * no metadata available - just log the case - // * known alignment - sized types, `[T]`, `str` or a foreign type + // * known alignment - sized types, `[T]`, `str` + // * offset 0 -- rounding up to alignment cannot change the offset // Note that looking at `field.align` is incorrect since that is not necessarily equal // to the dynamic alignment of the type. match field.ty.kind() { - _ if self.llextra.is_none() => { - debug!( - "unsized field `{}`, of `{:?}` has no metadata for adjustment", - ix, self.llval - ); - return simple(); - } _ if field.is_sized() => return simple(), - ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(), + ty::Slice(..) | ty::Str => return simple(), + _ if offset.bytes() == 0 => return simple(), _ => {} } // We need to get the pointer manually now. // We do this by casting to a `*i8`, then offsetting it by the appropriate amount. // We do this instead of, say, simply adjusting the pointer from the result of a GEP - // because the field may have an arbitrary alignment in the LLVM representation - // anyway. + // because the field may have an arbitrary alignment in the LLVM representation. // // To demonstrate: // @@ -179,7 +174,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let unaligned_offset = bx.cx().const_usize(offset.bytes()); // Get the alignment of the field - let (_, mut unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta); + let (_, mut unsized_align) = size_of_val::size_and_align_of_dst(bx, field.ty, meta); // For packed types, we need to cap alignment. if let ty::Adt(def, _) = self.layout.ty.kind() diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index c34f1dbf856..087836ca37d 100644 --- a/compiler/rustc_codegen_ssa/src/glue.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -1,10 +1,11 @@ -//! -// -// Code relating to drop glue. +//! Computing the size and alignment of a value. +use crate::common; use crate::common::IntPredicate; use crate::meth; use crate::traits::*; +use rustc_hir::LangItem; +use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::WrappingRange; @@ -14,7 +15,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( info: Option<Bx::Value>, ) -> (Bx::Value, Bx::Value) { let layout = bx.layout_of(t); - debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout); + trace!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout); if layout.is_sized() { let size = bx.const_usize(layout.size.bytes()); let align = bx.const_usize(layout.align.abi.bytes()); @@ -51,7 +52,31 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx.const_usize(unit.align.abi.bytes()), ) } - _ => { + ty::Foreign(_) => { + // `extern` type. We cannot compute the size, so panic. + let msg_str = with_no_visible_paths!({ + with_no_trimmed_paths!({ + format!("attempted to compute the size or alignment of extern type `{t}`") + }) + }); + let msg = bx.const_str(&msg_str); + + // Obtain the panic entry point. + let (fn_abi, llfn) = common::build_langcall(bx, None, LangItem::PanicNounwind); + + // Generate the call. + // Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`. + // (But we are in good company, this code is duplicated plenty of times.) + let fn_ty = bx.fn_decl_backend_type(fn_abi); + + bx.call(fn_ty, /* fn_attrs */ None, Some(fn_abi), llfn, &[msg.0, msg.1], None); + + // This function does not return so we can now return whatever we want. + let size = bx.const_usize(layout.size.bytes()); + let align = bx.const_usize(layout.align.abi.bytes()); + (size, align) + } + ty::Adt(..) | ty::Tuple(..) => { // First get the size of all statically known fields. // Don't use size_of because it also rounds up to alignment, which we // want to avoid, as the unsized field's alignment could be smaller. @@ -59,10 +84,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( debug!("DST {} layout: {:?}", t, layout); let i = layout.fields.count() - 1; - let sized_size = layout.fields.offset(i).bytes(); + let unsized_offset_unadjusted = layout.fields.offset(i).bytes(); let sized_align = layout.align.abi.bytes(); - debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align); - let sized_size = bx.const_usize(sized_size); + debug!( + "DST {} offset of dyn field: {}, statically sized align: {}", + t, unsized_offset_unadjusted, sized_align + ); + let unsized_offset_unadjusted = bx.const_usize(unsized_offset_unadjusted); let sized_align = bx.const_usize(sized_align); // Recurse to get the size of the dynamically sized field (must be @@ -70,26 +98,26 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let field_ty = layout.field(bx, i).ty; let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info); - // FIXME (#26403, #27023): We should be adding padding - // to `sized_size` (to accommodate the `unsized_align` - // required of the unsized field that follows) before - // summing it with `sized_size`. (Note that since #26403 - // is unfixed, we do not yet add the necessary padding - // here. But this is where the add would go.) + // # First compute the dynamic alignment - // Return the sum of sizes and max of aligns. - let size = bx.add(sized_size, unsized_size); - - // Packed types ignore the alignment of their fields. - if let ty::Adt(def, _) = t.kind() { - if def.repr().packed() { - unsized_align = sized_align; + // For packed types, we need to cap the alignment. + if let ty::Adt(def, _) = t.kind() + && let Some(packed) = def.repr().pack + { + if packed.bytes() == 1 { + // We know this will be capped to 1. + unsized_align = bx.const_usize(1); + } else { + // We have to dynamically compute `min(unsized_align, packed)`. + let packed = bx.const_usize(packed.bytes()); + let cmp = bx.icmp(IntPredicate::IntULT, unsized_align, packed); + unsized_align = bx.select(cmp, unsized_align, packed); } } // Choose max of two known alignments (combined value must // be aligned according to more restrictive of the two). - let align = match ( + let full_align = match ( bx.const_to_opt_u128(sized_align, false), bx.const_to_opt_u128(unsized_align, false), ) { @@ -104,6 +132,19 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } }; + // # Then compute the dynamic size + + // The full formula for the size would be: + // let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align); + // let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align); + // However, `unsized_size` is a multiple of `unsized_align`. + // Therefore, we can equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`: + // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(unsized_align).align_to(full_align); + // Furthermore, `align >= unsized_align`, and therefore we only need to do: + // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(full_align); + + let full_size = bx.add(unsized_offset_unadjusted, unsized_size); + // Issue #27023: must add any necessary padding to `size` // (to make it a multiple of `align`) before returning it. // @@ -115,12 +156,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // // `(size + (align-1)) & -align` let one = bx.const_usize(1); - let addend = bx.sub(align, one); - let add = bx.add(size, addend); - let neg = bx.neg(align); - let size = bx.and(add, neg); + let addend = bx.sub(full_align, one); + let add = bx.add(full_size, addend); + let neg = bx.neg(full_align); + let full_size = bx.and(add, neg); - (size, align) + (full_size, full_align) } + _ => bug!("size_and_align_of_dst: {t} not supported"), } } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index c3b8859c779..0b9b08c6a24 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -11,436 +11,10 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::parse::feature_err; -use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::symbol::Symbol; use rustc_span::Span; -/// Features that control behaviour of rustc, rather than the codegen. -pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"]; - -/// Stability information for target features. -#[derive(Debug, Clone, Copy)] -pub enum Stability { - /// This target feature is stable, it can be used in `#[target_feature]` and - /// `#[cfg(target_feature)]`. - Stable, - /// This target feature is unstable; using it in `#[target_feature]` or `#[cfg(target_feature)]` - /// requires enabling the given nightly feature. - Unstable(Symbol), -} -use Stability::*; - -impl Stability { - fn as_feature_name(self) -> Option<Symbol> { - match self { - Stable => None, - Unstable(s) => Some(s), - } - } - - pub fn is_stable(self) -> bool { - matches!(self, Stable) - } -} - -// Here we list target features that rustc "understands": they can be used in `#[target_feature]` -// and `#[cfg(target_feature)]`. They also do not trigger any warnings when used with -// `-Ctarget-feature`. -// -// When adding features to the below lists -// check whether they're named already elsewhere in rust -// e.g. in stdarch and whether the given name matches LLVM's -// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted. -// -// Also note that all target features listed here must be purely additive: for target_feature 1.1 to -// be sound, we can never allow features like `+soft-float` (on x86) to be controlled on a -// per-function level, since we would then allow safe calls from functions with `+soft-float` to -// functions without that feature! -// -// When adding a new feature, be particularly mindful of features that affect function ABIs. Those -// need to be treated very carefully to avoid introducing unsoundness! This often affects features -// that enable/disable hardfloat support (see https://github.com/rust-lang/rust/issues/116344 for an -// example of this going wrong), but features enabling new SIMD registers are also a concern (see -// https://github.com/rust-lang/rust/issues/116558 for an example of this going wrong). -// -// Stabilizing a target feature requires t-lang approval. - -const ARM_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("aclass", Unstable(sym::arm_target_feature)), - ("aes", Unstable(sym::arm_target_feature)), - ("crc", Unstable(sym::arm_target_feature)), - ("d32", Unstable(sym::arm_target_feature)), - ("dotprod", Unstable(sym::arm_target_feature)), - ("dsp", Unstable(sym::arm_target_feature)), - ("fp-armv8", Unstable(sym::arm_target_feature)), - ("i8mm", Unstable(sym::arm_target_feature)), - ("mclass", Unstable(sym::arm_target_feature)), - ("neon", Unstable(sym::arm_target_feature)), - ("rclass", Unstable(sym::arm_target_feature)), - ("sha2", Unstable(sym::arm_target_feature)), - // This is needed for inline assembly, but shouldn't be stabilized as-is - // since it should be enabled per-function using #[instruction_set], not - // #[target_feature]. - ("thumb-mode", Unstable(sym::arm_target_feature)), - ("thumb2", Unstable(sym::arm_target_feature)), - ("trustzone", Unstable(sym::arm_target_feature)), - ("v5te", Unstable(sym::arm_target_feature)), - ("v6", Unstable(sym::arm_target_feature)), - ("v6k", Unstable(sym::arm_target_feature)), - ("v6t2", Unstable(sym::arm_target_feature)), - ("v7", Unstable(sym::arm_target_feature)), - ("v8", Unstable(sym::arm_target_feature)), - ("vfp2", Unstable(sym::arm_target_feature)), - ("vfp3", Unstable(sym::arm_target_feature)), - ("vfp4", Unstable(sym::arm_target_feature)), - ("virtualization", Unstable(sym::arm_target_feature)), - // tidy-alphabetical-end -]; - -const AARCH64_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - // FEAT_AES - ("aes", Stable), - // FEAT_BF16 - ("bf16", Stable), - // FEAT_BTI - ("bti", Stable), - // FEAT_CRC - ("crc", Stable), - // FEAT_DIT - ("dit", Stable), - // FEAT_DotProd - ("dotprod", Stable), - // FEAT_DPB - ("dpb", Stable), - // FEAT_DPB2 - ("dpb2", Stable), - // FEAT_F32MM - ("f32mm", Stable), - // FEAT_F64MM - ("f64mm", Stable), - // FEAT_FCMA - ("fcma", Stable), - // FEAT_FHM - ("fhm", Stable), - // FEAT_FLAGM - ("flagm", Stable), - // FEAT_FP16 - ("fp16", Stable), - // FEAT_FRINTTS - ("frintts", Stable), - // FEAT_I8MM - ("i8mm", Stable), - // FEAT_JSCVT - ("jsconv", Stable), - // FEAT_LOR - ("lor", Stable), - // FEAT_LSE - ("lse", Stable), - // FEAT_MTE - ("mte", Stable), - // FEAT_AdvSimd & FEAT_FP - ("neon", Stable), - // FEAT_PAUTH (address authentication) - ("paca", Stable), - // FEAT_PAUTH (generic authentication) - ("pacg", Stable), - // FEAT_PAN - ("pan", Stable), - // FEAT_PMUv3 - ("pmuv3", Stable), - // FEAT_RAND - ("rand", Stable), - // FEAT_RAS - ("ras", Stable), - // FEAT_RCPC - ("rcpc", Stable), - // FEAT_RCPC2 - ("rcpc2", Stable), - // FEAT_RDM - ("rdm", Stable), - // FEAT_SB - ("sb", Stable), - // FEAT_SHA1 & FEAT_SHA256 - ("sha2", Stable), - // FEAT_SHA512 & FEAT_SHA3 - ("sha3", Stable), - // FEAT_SM3 & FEAT_SM4 - ("sm4", Stable), - // FEAT_SPE - ("spe", Stable), - // FEAT_SSBS - ("ssbs", Stable), - // FEAT_SVE - ("sve", Stable), - // FEAT_SVE2 - ("sve2", Stable), - // FEAT_SVE2_AES - ("sve2-aes", Stable), - // FEAT_SVE2_BitPerm - ("sve2-bitperm", Stable), - // FEAT_SVE2_SHA3 - ("sve2-sha3", Stable), - // FEAT_SVE2_SM4 - ("sve2-sm4", Stable), - // FEAT_TME - ("tme", Stable), - ("v8.1a", Unstable(sym::aarch64_ver_target_feature)), - ("v8.2a", Unstable(sym::aarch64_ver_target_feature)), - ("v8.3a", Unstable(sym::aarch64_ver_target_feature)), - ("v8.4a", Unstable(sym::aarch64_ver_target_feature)), - ("v8.5a", Unstable(sym::aarch64_ver_target_feature)), - ("v8.6a", Unstable(sym::aarch64_ver_target_feature)), - ("v8.7a", Unstable(sym::aarch64_ver_target_feature)), - // FEAT_VHE - ("vh", Stable), - // tidy-alphabetical-end -]; - -const AARCH64_TIED_FEATURES: &[&[&str]] = &[ - &["paca", "pacg"], // Together these represent `pauth` in LLVM -]; - -const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("adx", Stable), - ("aes", Stable), - ("avx", Stable), - ("avx2", Stable), - ("avx512bf16", Unstable(sym::avx512_target_feature)), - ("avx512bitalg", Unstable(sym::avx512_target_feature)), - ("avx512bw", Unstable(sym::avx512_target_feature)), - ("avx512cd", Unstable(sym::avx512_target_feature)), - ("avx512dq", Unstable(sym::avx512_target_feature)), - ("avx512er", Unstable(sym::avx512_target_feature)), - ("avx512f", Unstable(sym::avx512_target_feature)), - ("avx512ifma", Unstable(sym::avx512_target_feature)), - ("avx512pf", Unstable(sym::avx512_target_feature)), - ("avx512vbmi", Unstable(sym::avx512_target_feature)), - ("avx512vbmi2", Unstable(sym::avx512_target_feature)), - ("avx512vl", Unstable(sym::avx512_target_feature)), - ("avx512vnni", Unstable(sym::avx512_target_feature)), - ("avx512vp2intersect", Unstable(sym::avx512_target_feature)), - ("avx512vpopcntdq", Unstable(sym::avx512_target_feature)), - ("bmi1", Stable), - ("bmi2", Stable), - ("cmpxchg16b", Stable), - ("ermsb", Unstable(sym::ermsb_target_feature)), - ("f16c", Stable), - ("fma", Stable), - ("fxsr", Stable), - ("gfni", Unstable(sym::avx512_target_feature)), - ("lzcnt", Stable), - ("movbe", Stable), - ("pclmulqdq", Stable), - ("popcnt", Stable), - ("rdrand", Stable), - ("rdseed", Stable), - ("rtm", Unstable(sym::rtm_target_feature)), - ("sha", Stable), - ("sse", Stable), - ("sse2", Stable), - ("sse3", Stable), - ("sse4.1", Stable), - ("sse4.2", Stable), - ("sse4a", Unstable(sym::sse4a_target_feature)), - ("ssse3", Stable), - ("tbm", Unstable(sym::tbm_target_feature)), - ("vaes", Unstable(sym::avx512_target_feature)), - ("vpclmulqdq", Unstable(sym::avx512_target_feature)), - ("xsave", Stable), - ("xsavec", Stable), - ("xsaveopt", Stable), - ("xsaves", Stable), - // tidy-alphabetical-end -]; - -const HEXAGON_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("hvx", Unstable(sym::hexagon_target_feature)), - ("hvx-length128b", Unstable(sym::hexagon_target_feature)), - // tidy-alphabetical-end -]; - -const POWERPC_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("altivec", Unstable(sym::powerpc_target_feature)), - ("power10-vector", Unstable(sym::powerpc_target_feature)), - ("power8-altivec", Unstable(sym::powerpc_target_feature)), - ("power8-vector", Unstable(sym::powerpc_target_feature)), - ("power9-altivec", Unstable(sym::powerpc_target_feature)), - ("power9-vector", Unstable(sym::powerpc_target_feature)), - ("vsx", Unstable(sym::powerpc_target_feature)), - // tidy-alphabetical-end -]; - -const MIPS_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("fp64", Unstable(sym::mips_target_feature)), - ("msa", Unstable(sym::mips_target_feature)), - ("virt", Unstable(sym::mips_target_feature)), - // tidy-alphabetical-end -]; - -const RISCV_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("a", Stable), - ("c", Stable), - ("d", Unstable(sym::riscv_target_feature)), - ("e", Unstable(sym::riscv_target_feature)), - ("f", Unstable(sym::riscv_target_feature)), - ("fast-unaligned-access", Unstable(sym::riscv_target_feature)), - ("m", Stable), - ("relax", Unstable(sym::riscv_target_feature)), - ("v", Unstable(sym::riscv_target_feature)), - ("zba", Stable), - ("zbb", Stable), - ("zbc", Stable), - ("zbkb", Stable), - ("zbkc", Stable), - ("zbkx", Stable), - ("zbs", Stable), - ("zdinx", Unstable(sym::riscv_target_feature)), - ("zfh", Unstable(sym::riscv_target_feature)), - ("zfhmin", Unstable(sym::riscv_target_feature)), - ("zfinx", Unstable(sym::riscv_target_feature)), - ("zhinx", Unstable(sym::riscv_target_feature)), - ("zhinxmin", Unstable(sym::riscv_target_feature)), - ("zk", Stable), - ("zkn", Stable), - ("zknd", Stable), - ("zkne", Stable), - ("zknh", Stable), - ("zkr", Stable), - ("zks", Stable), - ("zksed", Stable), - ("zksh", Stable), - ("zkt", Stable), - // tidy-alphabetical-end -]; - -const WASM_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("atomics", Unstable(sym::wasm_target_feature)), - ("bulk-memory", Unstable(sym::wasm_target_feature)), - ("exception-handling", Unstable(sym::wasm_target_feature)), - ("multivalue", Unstable(sym::wasm_target_feature)), - ("mutable-globals", Unstable(sym::wasm_target_feature)), - ("nontrapping-fptoint", Unstable(sym::wasm_target_feature)), - ("reference-types", Unstable(sym::wasm_target_feature)), - ("relaxed-simd", Unstable(sym::wasm_target_feature)), - ("sign-ext", Unstable(sym::wasm_target_feature)), - ("simd128", Stable), - // tidy-alphabetical-end -]; - -const BPF_ALLOWED_FEATURES: &[(&str, Stability)] = &[("alu32", Unstable(sym::bpf_target_feature))]; - -const CSKY_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("10e60", Unstable(sym::csky_target_feature)), - ("2e3", Unstable(sym::csky_target_feature)), - ("3e3r1", Unstable(sym::csky_target_feature)), - ("3e3r2", Unstable(sym::csky_target_feature)), - ("3e3r3", Unstable(sym::csky_target_feature)), - ("3e7", Unstable(sym::csky_target_feature)), - ("7e10", Unstable(sym::csky_target_feature)), - ("cache", Unstable(sym::csky_target_feature)), - ("doloop", Unstable(sym::csky_target_feature)), - ("dsp1e2", Unstable(sym::csky_target_feature)), - ("dspe60", Unstable(sym::csky_target_feature)), - ("e1", Unstable(sym::csky_target_feature)), - ("e2", Unstable(sym::csky_target_feature)), - ("edsp", Unstable(sym::csky_target_feature)), - ("elrw", Unstable(sym::csky_target_feature)), - ("float1e2", Unstable(sym::csky_target_feature)), - ("float1e3", Unstable(sym::csky_target_feature)), - ("float3e4", Unstable(sym::csky_target_feature)), - ("float7e60", Unstable(sym::csky_target_feature)), - ("floate1", Unstable(sym::csky_target_feature)), - ("hard-tp", Unstable(sym::csky_target_feature)), - ("high-registers", Unstable(sym::csky_target_feature)), - ("hwdiv", Unstable(sym::csky_target_feature)), - ("mp", Unstable(sym::csky_target_feature)), - ("mp1e2", Unstable(sym::csky_target_feature)), - ("nvic", Unstable(sym::csky_target_feature)), - ("trust", Unstable(sym::csky_target_feature)), - ("vdsp2e60f", Unstable(sym::csky_target_feature)), - ("vdspv1", Unstable(sym::csky_target_feature)), - ("vdspv2", Unstable(sym::csky_target_feature)), - // tidy-alphabetical-end - //fpu - // tidy-alphabetical-start - ("fdivdu", Unstable(sym::csky_target_feature)), - ("fpuv2_df", Unstable(sym::csky_target_feature)), - ("fpuv2_sf", Unstable(sym::csky_target_feature)), - ("fpuv3_df", Unstable(sym::csky_target_feature)), - ("fpuv3_hf", Unstable(sym::csky_target_feature)), - ("fpuv3_hi", Unstable(sym::csky_target_feature)), - ("fpuv3_sf", Unstable(sym::csky_target_feature)), - ("hard-float", Unstable(sym::csky_target_feature)), - ("hard-float-abi", Unstable(sym::csky_target_feature)), - // tidy-alphabetical-end -]; - -const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[ - // tidy-alphabetical-start - ("d", Unstable(sym::loongarch_target_feature)), - ("f", Unstable(sym::loongarch_target_feature)), - ("lasx", Unstable(sym::loongarch_target_feature)), - ("lbt", Unstable(sym::loongarch_target_feature)), - ("lsx", Unstable(sym::loongarch_target_feature)), - ("lvz", Unstable(sym::loongarch_target_feature)), - ("ual", Unstable(sym::loongarch_target_feature)), - // tidy-alphabetical-end -]; - -/// When rustdoc is running, provide a list of all known features so that all their respective -/// primitives may be documented. -/// -/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator! -pub fn all_known_features() -> impl Iterator<Item = (&'static str, Stability)> { - std::iter::empty() - .chain(ARM_ALLOWED_FEATURES.iter()) - .chain(AARCH64_ALLOWED_FEATURES.iter()) - .chain(X86_ALLOWED_FEATURES.iter()) - .chain(HEXAGON_ALLOWED_FEATURES.iter()) - .chain(POWERPC_ALLOWED_FEATURES.iter()) - .chain(MIPS_ALLOWED_FEATURES.iter()) - .chain(RISCV_ALLOWED_FEATURES.iter()) - .chain(WASM_ALLOWED_FEATURES.iter()) - .chain(BPF_ALLOWED_FEATURES.iter()) - .chain(CSKY_ALLOWED_FEATURES) - .chain(LOONGARCH_ALLOWED_FEATURES) - .cloned() -} - -pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Stability)] { - match &*sess.target.arch { - "arm" => ARM_ALLOWED_FEATURES, - "aarch64" => AARCH64_ALLOWED_FEATURES, - "x86" | "x86_64" => X86_ALLOWED_FEATURES, - "hexagon" => HEXAGON_ALLOWED_FEATURES, - "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES, - "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES, - "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, - "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES, - "bpf" => BPF_ALLOWED_FEATURES, - "csky" => CSKY_ALLOWED_FEATURES, - "loongarch64" => LOONGARCH_ALLOWED_FEATURES, - _ => &[], - } -} - -pub fn tied_target_features(sess: &Session) -> &'static [&'static [&'static str]] { - match &*sess.target.arch { - "aarch64" => AARCH64_TIED_FEATURES, - _ => &[], - } -} - pub fn from_target_feature( tcx: TyCtxt<'_>, attr: &ast::Attribute, @@ -562,9 +136,13 @@ pub(crate) fn provide(providers: &mut Providers) { if tcx.sess.opts.actually_rustdoc { // rustdoc needs to be able to document functions that use all the features, so // whitelist them all - all_known_features().map(|(a, b)| (a.to_string(), b.as_feature_name())).collect() + rustc_target::target_features::all_known_features() + .map(|(a, b)| (a.to_string(), b.as_feature_name())) + .collect() } else { - supported_target_features(tcx.sess) + tcx.sess + .target + .supported_target_features() .iter() .map(|&(a, b)| (a.to_string(), b.as_feature_name())) .collect() diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 9e992637f46..dbc29e607ef 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -33,7 +33,7 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { /// return if it has a `const` modifier. If it is an intrinsic, report whether said intrinsic /// has a `rustc_const_{un,}stable` attribute. Otherwise, return `Constness::NotConst`. fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { - let node = tcx.hir().get_by_def_id(def_id); + let node = tcx.hir_node_by_def_id(def_id); match node { hir::Node::Ctor(_) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index bbebf329d26..847d6503f20 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -686,14 +686,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!(layout.fields.count() > 0); trace!("DST layout: {:?}", layout); - let sized_size = layout.fields.offset(layout.fields.count() - 1); + let unsized_offset_unadjusted = layout.fields.offset(layout.fields.count() - 1); let sized_align = layout.align.abi; - trace!( - "DST {} statically sized prefix size: {:?} align: {:?}", - layout.ty, - sized_size, - sized_align - ); // Recurse to get the size of the dynamically sized field (must be // the last field). Can't have foreign types here, how would we @@ -707,36 +701,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(None); }; - // FIXME (#26403, #27023): We should be adding padding - // to `sized_size` (to accommodate the `unsized_align` - // required of the unsized field that follows) before - // summing it with `sized_size`. (Note that since #26403 - // is unfixed, we do not yet add the necessary padding - // here. But this is where the add would go.) - - // Return the sum of sizes and max of aligns. - let size = sized_size + unsized_size; // `Size` addition + // # First compute the dynamic alignment - // Packed types ignore the alignment of their fields. + // Packed type alignment needs to be capped. if let ty::Adt(def, _) = layout.ty.kind() { - if def.repr().packed() { - unsized_align = sized_align; + if let Some(packed) = def.repr().pack { + unsized_align = unsized_align.min(packed); } } // Choose max of two known alignments (combined value must // be aligned according to more restrictive of the two). - let align = sized_align.max(unsized_align); + let full_align = sized_align.max(unsized_align); + + // # Then compute the dynamic size - // Issue #27023: must add any necessary padding to `size` - // (to make it a multiple of `align`) before returning it. - let size = size.align_to(align); + let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align); + let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align); + + // Just for our sanitiy's sake, assert that this is equal to what codegen would compute. + assert_eq!( + full_size, + (unsized_offset_unadjusted + unsized_size).align_to(full_align) + ); // Check if this brought us over the size limit. - if size > self.max_size_of_val() { + if full_size > self.max_size_of_val() { throw_ub!(InvalidMeta(InvalidMetaKind::TooBig)); } - Ok(Some((size, align))) + Ok(Some((full_size, full_align))) } ty::Dynamic(_, _, ty::Dyn) => { let vtable = metadata.unwrap_meta().to_pointer(self)?; diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 4d9e296d544..9a034ba22b9 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -174,12 +174,15 @@ where }; (base_meta, offset.align_to(align)) } - None => { - // For unsized types with an extern type tail we perform no adjustments. - // NOTE: keep this in sync with `PlaceRef::project_field` in the codegen backend. - assert!(matches!(base_meta, MemPlaceMeta::None)); + None if offset == Size::ZERO => { + // If the offset is 0, then rounding it up to alignment wouldn't change anything, + // so we can do this even for types where we cannot determine the alignment. (base_meta, offset) } + None => { + // We don't know the alignment of this field, so we cannot adjust. + throw_unsup_format!("`extern type` does not have a known offset") + } } } else { // base_meta could be present; we might be accessing a sized field of an unsized @@ -205,6 +208,24 @@ where if layout.abi.is_uninhabited() { // `read_discriminant` should have excluded uninhabited variants... but ConstProp calls // us on dead code. + // In the future we might want to allow this to permit code like this: + // (this is a Rust/MIR pseudocode mix) + // ``` + // enum Option2 { + // Some(i32, !), + // None, + // } + // + // fn panic() -> ! { panic!() } + // + // let x: Option2; + // x.Some.0 = 42; + // x.Some.1 = panic(); + // SetDiscriminant(x, Some); + // ``` + // However, for now we don't generate such MIR, and this check here *has* found real + // bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting + // it. throw_inval!(ConstPropNonsense) } // This cannot be `transmute` as variants *can* have a smaller size than the entire enum. diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 20f251d5c91..07500f74477 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -227,7 +227,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // Sometimes the index is beyond the number of upvars (seen // for a coroutine). let var_hir_id = captured_place.get_root_variable(); - let node = self.ecx.tcx.hir().get(var_hir_id); + let node = self.ecx.tcx.hir_node(var_hir_id); if let hir::Node::Pat(pat) = node { if let hir::PatKind::Binding(_, _, ident, _) = pat.kind { name = Some(ident.name); diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 5c5a6e8db57..de0590a4b14 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -21,7 +21,7 @@ pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { /// `read_discriminant` can be hooked for better error messages. #[inline(always)] fn read_discriminant(&mut self, v: &Self::V) -> InterpResult<'tcx, VariantIdx> { - Ok(self.ecx().read_discriminant(&v.to_op(self.ecx())?)?) + self.ecx().read_discriminant(&v.to_op(self.ecx())?) } /// This function provides the chance to reorder the order in which fields are visited for 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 5380d3071d6..bb17602d3ba 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -277,8 +277,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // "secondary" errors if they occurred. let secondary_errors = mem::take(&mut self.secondary_errors); if self.error_emitted.is_none() { - for mut error in secondary_errors { - self.tcx.sess.diagnostic().emit_diagnostic(&mut error); + for error in secondary_errors { + self.tcx.sess.diagnostic().emit_diagnostic(error); } } else { assert!(self.tcx.sess.has_errors().is_some()); diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 5bf9911269c..2de6362b9fe 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -119,8 +119,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { match self_ty.kind() { Param(param_ty) => { debug!(?param_ty); - let caller_hir_id = tcx.local_def_id_to_hir_id(caller); - if let Some(generics) = tcx.hir().get(caller_hir_id).generics() { + if let Some(generics) = tcx.hir_node_by_def_id(caller).generics() { let constraint = with_no_trimmed_paths!(format!( "~const {}", trait_ref.print_only_trait_path() diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 60b343afbed..ed2e558bffa 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -198,7 +198,7 @@ impl<K: Ord, V> SortedMap<K, V> { if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 { // We can copy the whole range without having to mix with // existing elements. - self.data.splice(index..index, elements.into_iter()); + self.data.splice(index..index, elements); return; } diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs index cb7f7d318dc..cafa91c8b8b 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs @@ -81,6 +81,7 @@ /// E::A, /// } /// ``` +#[cfg(bootstrap)] #[macro_export] macro_rules! impl_tag { ( @@ -140,5 +141,148 @@ macro_rules! impl_tag { }; } +/// Implements [`Tag`] for a given type. +/// +/// You can use `impl_tag` on structs and enums. +/// You need to specify the type and all its possible values, +/// which can only be paths with optional fields. +/// +/// [`Tag`]: crate::tagged_ptr::Tag +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// #![feature(macro_metavar_expr)] +/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag}; +/// +/// #[derive(Copy, Clone, PartialEq, Debug)] +/// enum SomeTag { +/// A, +/// B, +/// X { v: bool }, +/// Y(bool, bool), +/// } +/// +/// impl_tag! { +/// // The type for which the `Tag` will be implemented +/// impl Tag for SomeTag; +/// // You need to specify all possible tag values: +/// SomeTag::A, // 0 +/// SomeTag::B, // 1 +/// // For variants with fields, you need to specify the fields: +/// SomeTag::X { v: true }, // 2 +/// SomeTag::X { v: false }, // 3 +/// // For tuple variants use named syntax: +/// SomeTag::Y { 0: true, 1: true }, // 4 +/// SomeTag::Y { 0: false, 1: true }, // 5 +/// SomeTag::Y { 0: true, 1: false }, // 6 +/// SomeTag::Y { 0: false, 1: false }, // 7 +/// } +/// +/// // Tag values are assigned in order: +/// assert_eq!(SomeTag::A.into_usize(), 0); +/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3); +/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5); +/// +/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B); +/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true }); +/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false)); +/// ``` +/// +/// Structs are supported: +/// +/// ``` +/// #![feature(macro_metavar_expr)] +/// # use rustc_data_structures::impl_tag; +/// #[derive(Copy, Clone)] +/// struct Flags { a: bool, b: bool } +/// +/// impl_tag! { +/// impl Tag for Flags; +/// Flags { a: true, b: true }, +/// Flags { a: false, b: true }, +/// Flags { a: true, b: false }, +/// Flags { a: false, b: false }, +/// } +/// ``` +/// +/// Not specifying all values results in a compile error: +/// +/// ```compile_fail,E0004 +/// #![feature(macro_metavar_expr)] +/// # use rustc_data_structures::impl_tag; +/// #[derive(Copy, Clone)] +/// enum E { +/// A, +/// B, +/// } +/// +/// impl_tag! { +/// impl Tag for E; +/// E::A, +/// } +/// ``` +#[cfg(not(bootstrap))] +#[macro_export] +macro_rules! impl_tag { + ( + impl Tag for $Self:ty; + $( + $($path:ident)::* $( { $( $fields:tt )* })?, + )* + ) => { + // Safety: + // `bits_for_tags` is called on the same `${index()}`-es as + // `into_usize` returns, thus `BITS` constant is correct. + unsafe impl $crate::tagged_ptr::Tag for $Self { + const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[ + $( + ${index()}, + $( ${ignore($path)} )* + )* + ]); + + #[inline] + fn into_usize(self) -> usize { + // This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc) + // (or at least it should, see <https://github.com/rust-lang/rust/issues/110613>) + #[forbid(unreachable_patterns)] + match self { + // `match` is doing heavy lifting here, by requiring exhaustiveness + $( + $($path)::* $( { $( $fields )* } )? => ${index()}, + )* + } + } + + #[inline] + unsafe fn from_usize(tag: usize) -> Self { + match tag { + $( + ${index()} => $($path)::* $( { $( $fields )* } )?, + )* + + // Safety: + // `into_usize` only returns `${index()}` of the same + // repetition as we are filtering above, thus if this is + // reached, the safety contract of this function was + // already breached. + _ => unsafe { + debug_assert!( + false, + "invalid tag: {tag}\ + (this is a bug in the caller of `from_usize`)" + ); + std::hint::unreachable_unchecked() + }, + } + } + + } + }; +} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 8b7a4dbff9d..e49db64536f 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -587,10 +587,8 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { let mut print_formatted = if pager_name == "less" { cmd.arg("-r"); true - } else if ["bat", "catbat", "delta"].iter().any(|v| *v == pager_name) { - true } else { - false + ["bat", "catbat", "delta"].iter().any(|v| *v == pager_name) }; if color == ColorConfig::Never { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 4fb63d67e78..403e0ec7950 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -91,10 +91,7 @@ where #[rustc_diagnostic_item = "DecorateLint"] pub trait DecorateLint<'a, G: EmissionGuarantee> { /// Decorate and emit a lint. - fn decorate_lint<'b>( - self, - diag: &'b mut DiagnosticBuilder<'a, G>, - ) -> &'b mut DiagnosticBuilder<'a, G>; + fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, G>); fn msg(&self) -> DiagnosticMessage; } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index b8bd86a72e4..315e47c0971 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -132,7 +132,7 @@ impl EmissionGuarantee for ErrorGuaranteed { DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - let guar = handler.emit_diagnostic(&mut db.inner.diagnostic); + let guar = handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic); // Only allow a guarantee if the `level` wasn't switched to a // non-error - the field isn't `pub`, but the whole `Diagnostic` @@ -181,7 +181,7 @@ impl EmissionGuarantee for () { DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&mut db.inner.diagnostic); + handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic); } // `.emit()` was previously called, disallowed from repeating it. DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} @@ -207,7 +207,7 @@ impl EmissionGuarantee for Noted { // First `.emit()` call, the `&Handler` is still available. DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&mut db.inner.diagnostic); + handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic); } // `.emit()` was previously called, disallowed from repeating it. DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} @@ -236,7 +236,7 @@ impl EmissionGuarantee for Bug { DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&mut db.inner.diagnostic); + handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic); } // `.emit()` was previously called, disallowed from repeating it. DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} @@ -260,7 +260,7 @@ impl EmissionGuarantee for ! { DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&mut db.inner.diagnostic); + handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic); } // `.emit()` was previously called, disallowed from repeating it. DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} @@ -284,7 +284,7 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError { DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&mut db.inner.diagnostic); + handler.emit_diagnostic_without_consuming(&mut db.inner.diagnostic); } // `.emit()` was previously called, disallowed from repeating it. DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} @@ -365,7 +365,9 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { } } - /// Emit the diagnostic. + /// Emit the diagnostic. Does not consume `self`, which may be surprising, + /// but there are various places that rely on continuing to use `self` + /// after calling `emit`. #[track_caller] pub fn emit(&mut self) -> G { G::diagnostic_builder_emit_producing_guarantee(self) @@ -640,13 +642,13 @@ impl Drop for DiagnosticBuilderInner<'_> { // No `.emit()` or `.cancel()` calls. DiagnosticBuilderState::Emittable(handler) => { if !panicking() { - handler.emit_diagnostic(&mut Diagnostic::new( + handler.emit_diagnostic(Diagnostic::new( Level::Bug, DiagnosticMessage::from( "the following error was constructed but not emitted", ), )); - handler.emit_diagnostic(&mut self.diagnostic); + handler.emit_diagnostic_without_consuming(&mut self.diagnostic); panic!("error was constructed but not emitted"); } } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 4f77f09b26e..558262460c7 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -378,3 +378,9 @@ pub struct IndicateAnonymousLifetime { pub count: usize, pub suggestion: String, } + +impl IntoDiagnosticArg for type_ir::ClosureKind { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(self.as_str().into()) + } +} diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 3f257fdd9cf..ec37240e394 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -581,7 +581,7 @@ impl Emitter for SilentEmitter { if let Some(ref note) = self.fatal_note { d.note(note.clone()); } - self.fatal_handler.emit_diagnostic(&mut d); + self.fatal_handler.emit_diagnostic(d); } } } @@ -2677,10 +2677,7 @@ fn from_stderr(color: ColorConfig) -> Destination { /// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead. /// /// See #36178. -#[cfg(windows)] -const BRIGHT_BLUE: Color = Color::Cyan; -#[cfg(not(windows))] -const BRIGHT_BLUE: Color = Color::Blue; +const BRIGHT_BLUE: Color = if cfg!(windows) { Color::Cyan } else { Color::Blue }; impl Style { fn color_spec(&self, lvl: Level) -> ColorSpec { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index daa8a7706eb..cf73c638d85 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -585,11 +585,6 @@ impl Handler { self } - pub fn treat_err_as_bug(mut self, treat_err_as_bug: NonZeroUsize) -> Self { - self.inner.get_mut().flags.treat_err_as_bug = Some(treat_err_as_bug); - self - } - pub fn with_flags(mut self, flags: HandlerFlags) -> Self { self.inner.get_mut().flags = flags; self @@ -727,7 +722,12 @@ impl Handler { self.inner.borrow_mut().emit_stashed_diagnostics() } - /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`. + /// Construct a builder with the `msg` at the level appropriate for the + /// specific `EmissionGuarantee`. + /// + /// Note: this is necessary for `derive(Diagnostic)`, but shouldn't be used + /// outside of that. Instead use `struct_err`, `struct_warn`, etc., which + /// make the diagnostic kind clearer. #[rustc_lint_diagnostics] #[track_caller] pub fn struct_diagnostic<G: EmissionGuarantee>( @@ -942,13 +942,23 @@ impl Handler { result } - /// Construct a builder at the `Error` level with the `msg`. + /// Construct a builder at the `Fatal` level with the `msg`. #[rustc_lint_diagnostics] #[track_caller] pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> { DiagnosticBuilder::new(self, Level::Fatal, msg) } + /// Construct a builder at the `Fatal` level with the `msg`, that doesn't abort. + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_almost_fatal( + &self, + msg: impl Into<DiagnosticMessage>, + ) -> DiagnosticBuilder<'_, FatalError> { + DiagnosticBuilder::new(self, Level::Fatal, msg) + } + /// Construct a builder at the `Help` level with the `msg`. #[rustc_lint_diagnostics] pub fn struct_help(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { @@ -965,8 +975,7 @@ impl Handler { #[rustc_lint_diagnostics] #[track_caller] pub fn span_fatal(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! { - self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span); - FatalError.raise() + self.struct_span_fatal(span, msg).emit() } #[rustc_lint_diagnostics] @@ -977,8 +986,7 @@ impl Handler { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> ! { - self.emit_diag_at_span(Diagnostic::new_with_code(Fatal, Some(code), msg), span); - FatalError.raise() + self.struct_span_fatal_with_code(span, msg, code).emit() } #[rustc_lint_diagnostics] @@ -988,7 +996,7 @@ impl Handler { span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>, ) -> ErrorGuaranteed { - self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span).unwrap() + self.struct_span_err(span, msg).emit() } #[rustc_lint_diagnostics] @@ -999,17 +1007,13 @@ impl Handler { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> ErrorGuaranteed { - self.emit_diag_at_span( - Diagnostic::new_with_code(Error { lint: false }, Some(code), msg), - span, - ) - .unwrap() + self.struct_span_err_with_code(span, msg, code).emit() } #[rustc_lint_diagnostics] #[track_caller] pub fn span_warn(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) { - self.emit_diag_at_span(Diagnostic::new(Warning(None), msg), span); + self.struct_span_warn(span, msg).emit() } #[rustc_lint_diagnostics] @@ -1020,10 +1024,10 @@ impl Handler { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) { - self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); + self.struct_span_warn_with_code(span, msg, code).emit() } - pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<String>) -> ! { + pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! { self.inner.borrow_mut().span_bug(span, msg) } @@ -1035,7 +1039,7 @@ impl Handler { pub fn span_delayed_bug( &self, sp: impl Into<MultiSpan>, - msg: impl Into<String>, + msg: impl Into<DiagnosticMessage>, ) -> ErrorGuaranteed { let mut inner = self.inner.borrow_mut(); @@ -1046,11 +1050,11 @@ impl Handler { inner.err_count + inner.lint_err_count + inner.delayed_bug_count() + 1 >= c.get() }) { // FIXME: don't abort here if report_delayed_bugs is off - inner.span_bug(sp, msg.into()); + inner.span_bug(sp, msg); } - let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg.into()); - diagnostic.set_span(sp.into()); - inner.emit_diagnostic(&mut diagnostic).unwrap() + let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); + diagnostic.set_span(sp); + inner.emit_diagnostic(diagnostic).unwrap() } // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's @@ -1060,7 +1064,7 @@ impl Handler { let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); if inner.flags.report_delayed_bugs { - inner.emit_diagnostic(&mut diagnostic); + inner.emit_diagnostic_without_consuming(&mut diagnostic); } let backtrace = std::backtrace::Backtrace::capture(); inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace)); @@ -1068,20 +1072,22 @@ impl Handler { #[track_caller] pub fn span_bug_no_panic(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) { - self.emit_diag_at_span(Diagnostic::new(Bug, msg), span); + let mut diag = Diagnostic::new(Bug, msg); + diag.set_span(span); + self.emit_diagnostic(diag); } #[track_caller] #[rustc_lint_diagnostics] pub fn span_note(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) { - self.emit_diag_at_span(Diagnostic::new(Note, msg), span); + self.struct_span_note(span, msg).emit() } #[track_caller] #[rustc_lint_diagnostics] pub fn struct_span_note( &self, - span: Span, + span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, ()> { let mut db = DiagnosticBuilder::new(self, Note, msg); @@ -1091,22 +1097,22 @@ impl Handler { #[rustc_lint_diagnostics] pub fn fatal(&self, msg: impl Into<DiagnosticMessage>) -> ! { - DiagnosticBuilder::<FatalError>::new(self, Fatal, msg).emit().raise() + self.struct_fatal(msg).emit() } #[rustc_lint_diagnostics] pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed { - DiagnosticBuilder::<ErrorGuaranteed>::new(self, Error { lint: false }, msg).emit() + self.struct_err(msg).emit() } #[rustc_lint_diagnostics] pub fn warn(&self, msg: impl Into<DiagnosticMessage>) { - DiagnosticBuilder::<()>::new(self, Warning(None), msg).emit(); + self.struct_warn(msg).emit() } #[rustc_lint_diagnostics] pub fn note(&self, msg: impl Into<DiagnosticMessage>) { - DiagnosticBuilder::<()>::new(self, Note, msg).emit(); + self.struct_note(msg).emit() } pub fn bug(&self, msg: impl Into<DiagnosticMessage>) -> ! { @@ -1181,10 +1187,10 @@ impl Handler { DiagnosticMessage::Str(warnings), )), (_, 0) => { - inner.emit_diagnostic(&mut Diagnostic::new(Fatal, errors)); + inner.emit_diagnostic(Diagnostic::new(Fatal, errors)); } (_, _) => { - inner.emit_diagnostic(&mut Diagnostic::new(Fatal, format!("{errors}; {warnings}"))); + inner.emit_diagnostic(Diagnostic::new(Fatal, format!("{errors}; {warnings}"))); } } @@ -1251,8 +1257,17 @@ impl Handler { self.inner.borrow_mut().emitter.emit_diagnostic(&db); } - pub fn emit_diagnostic(&self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> { - self.inner.borrow_mut().emit_diagnostic(diagnostic) + pub fn emit_diagnostic(&self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> { + self.emit_diagnostic_without_consuming(&mut diagnostic) + } + + // It's unfortunate this exists. `emit_diagnostic` is preferred, because it + // consumes the diagnostic, thus ensuring it is emitted just once. + pub(crate) fn emit_diagnostic_without_consuming( + &self, + diagnostic: &mut Diagnostic, + ) -> Option<ErrorGuaranteed> { + self.inner.borrow_mut().emit_diagnostic_without_consuming(diagnostic) } pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { @@ -1327,14 +1342,6 @@ impl Handler { note.into_diagnostic(self) } - fn emit_diag_at_span( - &self, - mut diag: Diagnostic, - sp: impl Into<MultiSpan>, - ) -> Option<ErrorGuaranteed> { - self.emit_diagnostic(diag.set_span(sp)) - } - pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type); } @@ -1374,7 +1381,7 @@ impl Handler { // Here the diagnostic is given back to `emit_diagnostic` where it was first // intercepted. Now it should be processed as usual, since the unstable expectation // id is now stable. - inner.emit_diagnostic(&mut diag); + inner.emit_diagnostic(diag); } } @@ -1416,7 +1423,7 @@ impl HandlerInner { let has_errors = self.has_errors(); let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>(); let mut reported = None; - for mut diag in diags { + for diag in diags { // Decrement the count tracking the stash; emitting will increment it. if diag.is_error() { if matches!(diag.level, Level::Error { lint: true }) { @@ -1436,14 +1443,20 @@ impl HandlerInner { } } } - let reported_this = self.emit_diagnostic(&mut diag); + let reported_this = self.emit_diagnostic(diag); reported = reported.or(reported_this); } reported } - // FIXME(eddyb) this should ideally take `diagnostic` by value. - fn emit_diagnostic(&mut self, diagnostic: &mut Diagnostic) -> Option<ErrorGuaranteed> { + fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> { + self.emit_diagnostic_without_consuming(&mut diagnostic) + } + + fn emit_diagnostic_without_consuming( + &mut self, + diagnostic: &mut Diagnostic, + ) -> Option<ErrorGuaranteed> { if matches!(diagnostic.level, Level::Error { .. } | Level::Fatal) && self.treat_err_as_bug() { diagnostic.level = Level::Bug; @@ -1579,17 +1592,15 @@ impl HandlerInner { } #[track_caller] - fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: impl Into<String>) -> ! { - self.emit_diag_at_span(Diagnostic::new(Bug, msg.into()), sp); + fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! { + let mut diag = Diagnostic::new(Bug, msg); + diag.set_span(sp); + self.emit_diagnostic(diag); panic::panic_any(ExplicitBug); } - fn emit_diag_at_span(&mut self, mut diag: Diagnostic, sp: impl Into<MultiSpan>) { - self.emit_diagnostic(diag.set_span(sp)); - } - fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) { - self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg)); + self.emit_diagnostic(Diagnostic::new(FailureNote, msg)); } fn flush_delayed( @@ -1621,7 +1632,7 @@ impl HandlerInner { if no_bugs { // Put the overall explanation before the `DelayedBug`s, to // frame them better (e.g. separate warnings from them). - self.emit_diagnostic(&mut Diagnostic::new(Bug, explanation)); + self.emit_diagnostic(Diagnostic::new(Bug, explanation)); no_bugs = false; } @@ -1636,7 +1647,7 @@ impl HandlerInner { } bug.level = Level::Bug; - self.emit_diagnostic(&mut bug); + self.emit_diagnostic(bug); } // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages. diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 11db4bb4017..d75556ac7c4 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1145,7 +1145,7 @@ impl<'a> ExtCtxt<'a> { pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) { self.sess.diagnostic().span_err(sp, msg); } - pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<String>) -> ! { + pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! { self.sess.diagnostic().span_bug(sp, msg); } pub fn trace_macros_diag(&mut self) { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 47d4b802c0f..89caf8aa231 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -41,6 +41,7 @@ use std::path::PathBuf; use std::rc::Rc; use std::{iter, mem}; +#[cfg(bootstrap)] macro_rules! ast_fragments { ( $($Kind:ident($AstTy:ty) { @@ -165,6 +166,131 @@ macro_rules! ast_fragments { } } +#[cfg(not(bootstrap))] +macro_rules! ast_fragments { + ( + $($Kind:ident($AstTy:ty) { + $kind_name:expr; + $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)? + $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)? + fn $make_ast:ident; + })* + ) => { + /// A fragment of AST that can be produced by a single macro expansion. + /// Can also serve as an input and intermediate result for macro expansion operations. + pub enum AstFragment { + OptExpr(Option<P<ast::Expr>>), + MethodReceiverExpr(P<ast::Expr>), + $($Kind($AstTy),)* + } + + /// "Discriminant" of an AST fragment. + #[derive(Copy, Clone, PartialEq, Eq)] + pub enum AstFragmentKind { + OptExpr, + MethodReceiverExpr, + $($Kind,)* + } + + impl AstFragmentKind { + pub fn name(self) -> &'static str { + match self { + AstFragmentKind::OptExpr => "expression", + AstFragmentKind::MethodReceiverExpr => "expression", + $(AstFragmentKind::$Kind => $kind_name,)* + } + } + + fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> { + match self { + AstFragmentKind::OptExpr => + result.make_expr().map(Some).map(AstFragment::OptExpr), + AstFragmentKind::MethodReceiverExpr => + result.make_expr().map(AstFragment::MethodReceiverExpr), + $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)* + } + } + } + + impl AstFragment { + pub fn add_placeholders(&mut self, placeholders: &[NodeId]) { + if placeholders.is_empty() { + return; + } + match self { + $($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| { + ${ignore($flat_map_ast_elt)} + placeholder(AstFragmentKind::$Kind, *id, None).$make_ast() + })),)?)* + _ => panic!("unexpected AST fragment kind") + } + } + + pub fn make_opt_expr(self) -> Option<P<ast::Expr>> { + match self { + AstFragment::OptExpr(expr) => expr, + _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), + } + } + + pub fn make_method_receiver_expr(self) -> P<ast::Expr> { + match self { + AstFragment::MethodReceiverExpr(expr) => expr, + _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), + } + } + + $(pub fn $make_ast(self) -> $AstTy { + match self { + AstFragment::$Kind(ast) => ast, + _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), + } + })* + + fn make_ast<T: InvocationCollectorNode>(self) -> T::OutputTy { + T::fragment_to_output(self) + } + + pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) { + match self { + AstFragment::OptExpr(opt_expr) => { + visit_clobber(opt_expr, |opt_expr| { + if let Some(expr) = opt_expr { + vis.filter_map_expr(expr) + } else { + None + } + }); + } + AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr), + $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)* + $($(AstFragment::$Kind(ast) => + ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)* + } + } + + pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) { + match self { + AstFragment::OptExpr(Some(expr)) => visitor.visit_expr(expr), + AstFragment::OptExpr(None) => {} + AstFragment::MethodReceiverExpr(expr) => visitor.visit_method_receiver_expr(expr), + $($(AstFragment::$Kind(ast) => visitor.$visit_ast(ast),)?)* + $($(AstFragment::$Kind(ast) => for ast_elt in &ast[..] { + visitor.$visit_ast_elt(ast_elt, $($args)*); + })?)* + } + } + } + + impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> { + $(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a>>) + -> Option<$AstTy> { + Some(self.make(AstFragmentKind::$Kind).$make_ast()) + })* + } + } +} + ast_fragments! { Expr(P<ast::Expr>) { "expression"; one fn visit_expr; fn visit_expr; fn make_expr; } Pat(P<ast::Pat>) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; } diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index c29edc3dc9f..4b8c6feb93e 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -10,9 +10,8 @@ use rustc_span::Span; /// A meta-variable expression, for expansions based on properties of meta-variables. #[derive(Debug, Clone, PartialEq, Encodable, Decodable)] pub(crate) enum MetaVarExpr { - /// The number of repetitions of an identifier, optionally limited to a number - /// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited. - Count(Ident, Option<usize>), + /// The number of repetitions of an identifier. + Count(Ident, usize), /// Ignore a meta-variable for repetition without expansion. Ignore(Ident), @@ -43,7 +42,10 @@ impl MetaVarExpr { let mut iter = args.trees(); let rslt = match ident.as_str() { "count" => parse_count(&mut iter, sess, ident.span)?, - "ignore" => MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?), + "ignore" => { + eat_dollar(&mut iter, sess, ident.span)?; + MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?) + } "index" => MetaVarExpr::Index(parse_depth(&mut iter, sess, ident.span)?), "length" => MetaVarExpr::Length(parse_depth(&mut iter, sess, ident.span)?), _ => { @@ -92,6 +94,7 @@ fn parse_count<'sess>( sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, MetaVarExpr> { + eat_dollar(iter, sess, span)?; let ident = parse_ident(iter, sess, span)?; let depth = if try_eat_comma(iter) { if iter.look_ahead(0).is_none() { @@ -100,9 +103,9 @@ fn parse_count<'sess>( "`count` followed by a comma must have an associated index indicating its depth", )); } - Some(parse_depth(iter, sess, span)?) + parse_depth(iter, sess, span)? } else { - None + 0 }; Ok(MetaVarExpr::Count(ident, depth)) } @@ -166,3 +169,20 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool { } false } + +/// Expects that the next item is a dollar sign. +fn eat_dollar<'sess>( + iter: &mut RefTokenTreeCursor<'_>, + sess: &'sess ParseSess, + span: Span, +) -> PResult<'sess, ()> { + if let Some(TokenTree::Token(token::Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0) + { + let _ = iter.next(); + return Ok(()); + } + Err(sess.span_diagnostic.struct_span_err( + span, + "meta-variables within meta-variable expressions must be referenced using a dollar sign", + )) +} diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 18707cebcd5..80fd82e0302 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -440,7 +440,7 @@ fn lockstep_iter_size( /// declared inside a single repetition and the index `1` implies two nested repetitions. fn count_repetitions<'a>( cx: &ExtCtxt<'a>, - depth_opt: Option<usize>, + depth_user: usize, mut matched: &NamedMatch, repeats: &[(usize, usize)], sp: &DelimSpan, @@ -449,37 +449,45 @@ fn count_repetitions<'a>( // (or at the top-level of `matched` if no depth is given). fn count<'a>( cx: &ExtCtxt<'a>, - declared_lhs_depth: usize, - depth_opt: Option<usize>, + depth_curr: usize, + depth_max: usize, matched: &NamedMatch, sp: &DelimSpan, ) -> PResult<'a, usize> { match matched { - MatchedTokenTree(_) | MatchedNonterminal(_) => { - if declared_lhs_depth == 0 { - return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() })); - } - match depth_opt { - None => Ok(1), - Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")), - } - } + MatchedTokenTree(_) | MatchedNonterminal(_) => Ok(1), MatchedSeq(named_matches) => { - let new_declared_lhs_depth = declared_lhs_depth + 1; - match depth_opt { - None => named_matches - .iter() - .map(|elem| count(cx, new_declared_lhs_depth, None, elem, sp)) - .sum(), - Some(0) => Ok(named_matches.len()), - Some(depth) => named_matches + if depth_curr == depth_max { + Ok(named_matches.len()) + } else { + named_matches .iter() - .map(|elem| count(cx, new_declared_lhs_depth, Some(depth - 1), elem, sp)) - .sum(), + .map(|elem| count(cx, depth_curr + 1, depth_max, elem, sp)) + .sum() } } } } + + /// Maximum depth + fn depth(counter: usize, matched: &NamedMatch) -> usize { + match matched { + MatchedTokenTree(_) | MatchedNonterminal(_) => counter, + MatchedSeq(named_matches) => { + let rslt = counter + 1; + if let Some(elem) = named_matches.first() { depth(rslt, elem) } else { rslt } + } + } + } + + let depth_max = depth(0, matched) + .checked_sub(1) + .and_then(|el| el.checked_sub(repeats.len())) + .unwrap_or_default(); + if depth_user > depth_max { + return Err(out_of_bounds_err(cx, depth_max + 1, sp.entire(), "count")); + } + // `repeats` records all of the nested levels at which we are currently // matching meta-variables. The meta-var-expr `count($x)` only counts // matches that occur in this "subtree" of the `NamedMatch` where we @@ -491,7 +499,12 @@ fn count_repetitions<'a>( matched = &ads[idx]; } } - count(cx, 0, depth_opt, matched, sp) + + if let MatchedTokenTree(_) | MatchedNonterminal(_) = matched { + return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() })); + } + + count(cx, depth_user, depth_max, matched, sp) } /// Returns a `NamedMatch` item declared on the LHS given an arbitrary [Ident] @@ -523,7 +536,7 @@ fn out_of_bounds_err<'a>( ) } else { format!( - "depth parameter on meta-variable expression `{ty}` \ + "depth parameter of meta-variable expression `{ty}` \ must be less than {max}" ) }; @@ -545,9 +558,9 @@ fn transcribe_metavar_expr<'a>( span }; match *expr { - MetaVarExpr::Count(original_ident, depth_opt) => { + MetaVarExpr::Count(original_ident, depth) => { let matched = matched_from_ident(cx, original_ident, interp)?; - let count = count_repetitions(cx, depth_opt, matched, repeats, sp)?; + let count = count_repetitions(cx, depth, matched, repeats, sp)?; let tt = TokenTree::token_alone( TokenKind::lit(token::Integer, sym::integer(count), None), visited_span(), diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 5308e338d7f..d2c26668ea8 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -502,7 +502,7 @@ impl server::FreeFunctions for Rustc<'_, '_> { None, ); } - self.sess().span_diagnostic.emit_diagnostic(&mut diag); + self.sess().span_diagnostic.emit_diagnostic(diag); } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 01508375b1a..760945554f0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -435,8 +435,6 @@ pub enum TraitBoundModifier { #[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), - // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` - LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>), Outlives(&'hir Lifetime), } @@ -451,7 +449,6 @@ impl GenericBound<'_> { pub fn span(&self) -> Span { match self { GenericBound::Trait(t, ..) => t.span, - GenericBound::LangItemTrait(_, span, ..) => *span, GenericBound::Outlives(l) => l.ident.span, } } @@ -1560,7 +1557,7 @@ impl Expr<'_> { ExprKind::Call(..) => ExprPrecedence::Call, ExprKind::MethodCall(..) => ExprPrecedence::MethodCall, ExprKind::Tup(_) => ExprPrecedence::Tup, - ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node.into()), + ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), ExprKind::Unary(..) => ExprPrecedence::Unary, ExprKind::Lit(_) => ExprPrecedence::Lit, ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, @@ -1700,11 +1697,9 @@ impl Expr<'_> { // them being used only for its side-effects. base.can_have_side_effects() } - ExprKind::Struct(_, fields, init) => fields - .iter() - .map(|field| field.expr) - .chain(init.into_iter()) - .any(|e| e.can_have_side_effects()), + ExprKind::Struct(_, fields, init) => { + fields.iter().map(|field| field.expr).chain(init).any(|e| e.can_have_side_effects()) + } ExprKind::Array(args) | ExprKind::Tup(args) @@ -2815,7 +2810,7 @@ impl TraitRef<'_> { match self.path.res { Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did), Res::Err => None, - _ => unreachable!(), + res => panic!("{res:?} did not resolve to a trait or trait alias"), } } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9cf1db166a5..67e058a3219 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1075,10 +1075,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB GenericBound::Trait(ref typ, _modifier) => { visitor.visit_poly_trait_ref(typ); } - GenericBound::LangItemTrait(_, _span, hir_id, args) => { - visitor.visit_id(hir_id); - visitor.visit_generic_args(args); - } GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), } } diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 0d65ddb5642..8948a03e4a6 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -67,6 +67,42 @@ impl Display for Target { } impl Target { + pub fn is_associated_item(self) -> bool { + match self { + Target::AssocConst | Target::AssocTy | Target::Method(_) => true, + Target::ExternCrate + | Target::Use + | Target::Static + | Target::Const + | Target::Fn + | Target::Closure + | Target::Mod + | Target::ForeignMod + | Target::GlobalAsm + | Target::TyAlias + | Target::OpaqueTy + | Target::Enum + | Target::Variant + | Target::Struct + | Target::Field + | Target::Union + | Target::Trait + | Target::TraitAlias + | Target::Impl + | Target::Expression + | Target::Statement + | Target::Arm + | Target::ForeignFn + | Target::ForeignStatic + | Target::ForeignTy + | Target::GenericParam(_) + | Target::MacroDef + | Target::Param + | Target::PatField + | Target::ExprField => false, + } + } + pub fn from_item(item: &Item<'_>) -> Target { match item.kind { ItemKind::ExternCrate(..) => Target::ExternCrate, diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs index dfec3c5e829..0748644cc0a 100644 --- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs +++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs @@ -134,17 +134,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ { only_self_bounds, ); } - &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => { - self.instantiate_lang_item_trait_ref( - lang_item, - span, - hir_id, - args, - param_ty, - bounds, - only_self_bounds, - ); - } hir::GenericBound::Outlives(lifetime) => { let region = self.ast_region_to_region(lifetime, None); bounds.push_region_bound( diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 47fbed45b91..be73c027fdc 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -661,7 +661,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( args.args[0].hir_id(), multispan, msg, - |lint| lint, + |_| {}, ); } diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 14e810d1336..9afb04b7470 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -24,7 +24,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .. }), .. - }) = tcx.hir().get_by_def_id(parent_id) + }) = tcx.hir_node_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id { if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) { @@ -122,7 +122,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Applicability::MachineApplicable, ); self.maybe_lint_blanket_trait_impl(self_ty, lint); - lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 20d36a1b069..6f8e80172dd 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -477,7 +477,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Const::new_misc_error(tcx, ty).into() } } - _ => unreachable!(), + (kind, arg) => span_bug!( + self.span, + "mismatched path argument for kind {kind:?}: found arg {arg:?}" + ), } } @@ -675,36 +678,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) } - fn instantiate_poly_trait_ref_inner( + /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct + /// a full trait reference. The resulting trait reference is returned. This may also generate + /// auxiliary bounds, which are added to `bounds`. + /// + /// Example: + /// + /// ```ignore (illustrative) + /// poly_trait_ref = Iterator<Item = u32> + /// self_ty = Foo + /// ``` + /// + /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`. + /// + /// **A note on binders:** against our usual convention, there is an implied binder around + /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions. + /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>` + /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be + /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly, + /// however. + #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))] + pub(crate) fn instantiate_poly_trait_ref( &self, - hir_id: hir::HirId, + trait_ref: &hir::TraitRef<'_>, span: Span, - binding_span: Option<Span>, constness: ty::BoundConstness, polarity: ty::ImplPolarity, + self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, - trait_ref_span: Span, - trait_def_id: DefId, - trait_segment: &hir::PathSegment<'_>, - args: &GenericArgs<'_>, - infer_args: bool, - self_ty: Ty<'tcx>, only_self_bounds: OnlySelfBounds, ) -> GenericArgCountResult { + let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); + let trait_segment = trait_ref.path.segments.last().unwrap(); + let args = trait_segment.args(); + + self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); + self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false); + let (generic_args, arg_count) = self.create_args_for_ast_path( - trait_ref_span, + trait_ref.path.span, trait_def_id, &[], trait_segment, args, - infer_args, + trait_segment.infer_args, Some(self_ty), constness, ); let tcx = self.tcx(); - let bound_vars = tcx.late_bound_vars(hir_id); + let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); debug!(?bound_vars); let assoc_bindings = self.create_assoc_bindings_for_generic_args(args); @@ -732,13 +756,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Specify type to assert that error was already reported in `Err` case. let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding( - hir_id, + trait_ref.hir_ref_id, poly_trait_ref, binding, bounds, speculative, &mut dup_bindings, - binding_span.unwrap_or(binding.span), + binding.span, constness, only_self_bounds, polarity, @@ -749,102 +773,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { arg_count } - /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct - /// a full trait reference. The resulting trait reference is returned. This may also generate - /// auxiliary bounds, which are added to `bounds`. - /// - /// Example: - /// - /// ```ignore (illustrative) - /// poly_trait_ref = Iterator<Item = u32> - /// self_ty = Foo - /// ``` - /// - /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`. - /// - /// **A note on binders:** against our usual convention, there is an implied bounder around - /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions. - /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>` - /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be - /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly, - /// however. - #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))] - pub(crate) fn instantiate_poly_trait_ref( - &self, - trait_ref: &hir::TraitRef<'_>, - span: Span, - constness: ty::BoundConstness, - polarity: ty::ImplPolarity, - self_ty: Ty<'tcx>, - bounds: &mut Bounds<'tcx>, - speculative: bool, - only_self_bounds: OnlySelfBounds, - ) -> GenericArgCountResult { - let hir_id = trait_ref.hir_ref_id; - let binding_span = None; - let trait_ref_span = trait_ref.path.span; - let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); - let trait_segment = trait_ref.path.segments.last().unwrap(); - let args = trait_segment.args(); - let infer_args = trait_segment.infer_args; - - self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); - self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false); - - self.instantiate_poly_trait_ref_inner( - hir_id, - span, - binding_span, - constness, - polarity, - bounds, - speculative, - trait_ref_span, - trait_def_id, - trait_segment, - args, - infer_args, - self_ty, - only_self_bounds, - ) - } - - pub(crate) fn instantiate_lang_item_trait_ref( - &self, - lang_item: hir::LangItem, - span: Span, - hir_id: hir::HirId, - args: &GenericArgs<'_>, - self_ty: Ty<'tcx>, - bounds: &mut Bounds<'tcx>, - only_self_bounds: OnlySelfBounds, - ) { - let binding_span = Some(span); - let constness = ty::BoundConstness::NotConst; - let speculative = false; - let trait_ref_span = span; - let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span)); - let trait_segment = &hir::PathSegment::invalid(); - let infer_args = false; - - self.instantiate_poly_trait_ref_inner( - hir_id, - span, - binding_span, - constness, - ty::ImplPolarity::Positive, - bounds, - speculative, - trait_ref_span, - trait_def_id, - trait_segment, - args, - infer_args, - self_ty, - only_self_bounds, - ); - } - fn ast_path_to_mono_trait_ref( &self, span: Span, @@ -1506,8 +1434,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), Applicability::MachineApplicable, ); - - lint }, ); } @@ -1946,7 +1872,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "s", ), [only] => (only.to_string(), ""), - [] => unreachable!(), + [] => unreachable!("expected at least one generic to prohibit"), }; let last_span = *arg_spans.last().unwrap(); let span: MultiSpan = arg_spans.into(); @@ -2555,8 +2481,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len()) { // Resolve our own lifetime parameters. - let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() }; - let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() }; + let GenericParamDefKind::Lifetime { .. } = param.kind else { + span_bug!( + tcx.def_span(param.def_id), + "only expected lifetime for opaque's own generics, got {:?}", + param.kind + ); + }; + let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { + bug!( + "expected lifetime argument for param {param:?}, found {:?}", + &lifetimes[i] + ) + }; self.ast_region_to_region(lifetime, None).into() } else { tcx.mk_param_from_def(param) @@ -2715,7 +2652,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let hir = tcx.hir(); let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) = - hir.get(fn_hir_id) + tcx.hir_node(fn_hir_id) else { return None; }; diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index ce5426b5142..dd5deb6f244 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -73,7 +73,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) | ty::ClauseKind::ConstEvaluatable(_) => { - bug!() + span_bug!(span, "did not expect {pred} clause in object bounds"); } } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 6e18abf632e..8413a1cc0db 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -51,7 +51,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { hir_id, span, "use of calling convention not supported on this target", - |lint| lint, + |_| {}, ); } } @@ -190,7 +190,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { "static of uninhabited type", |lint| { lint - .note("uninhabited statics cannot be initialized, and any access would be an immediate error") + .note("uninhabited statics cannot be initialized, and any access would be an immediate error"); }, ); } @@ -504,7 +504,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { let origin = tcx.opaque_type_origin(id.owner_id.def_id); if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin - && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id) + && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { // Skip opaques from RPIT in traits with no default body. @@ -1093,7 +1093,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) "this {descr} contains `{field_ty}`, which {note}, \ and makes it not a breaking change to become \ non-zero-sized in the future." - )) + )); }, ) } else { @@ -1173,7 +1173,7 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) ty::VariantDiscr::Explicit(discr_def_id) => { // In the case the discriminant is both a duplicate and overflowed, let the user know if let hir::Node::AnonConst(expr) = - tcx.hir().get_by_def_id(discr_def_id.expect_local()) + tcx.hir_node_by_def_id(discr_def_id.expect_local()) && let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node && *lit_value != dis.val 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 1412fd1a987..264868fdfc7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2,9 +2,7 @@ use super::potentially_plural_count; use crate::errors::LifetimesOrBoundsMismatchOnTrait; use hir::def_id::{DefId, LocalDefId}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; -use rustc_errors::{ - pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed, MultiSpan, -}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit; @@ -50,13 +48,7 @@ pub(super) fn compare_impl_method<'tcx>( let _: Result<_, ErrorGuaranteed> = try { check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?; - compare_method_predicate_entailment( - tcx, - impl_m, - trait_m, - impl_trait_ref, - CheckImpliedWfMode::Check, - )?; + compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?; refine::check_refining_return_position_impl_trait_in_trait( tcx, impl_m, @@ -170,7 +162,6 @@ fn compare_method_predicate_entailment<'tcx>( impl_m: ty::AssocItem, trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, - check_implied_wf: CheckImpliedWfMode, ) -> Result<(), ErrorGuaranteed> { let trait_to_impl_args = impl_trait_ref.args; @@ -317,10 +308,10 @@ fn compare_method_predicate_entailment<'tcx>( return Err(emitted); } - if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() { + if !(impl_sig, trait_sig).references_error() { // Select obligations to make progress on inference before processing // the wf obligation below. - // FIXME(-Ztrait-solver=next): Not needed when the hack below is removed. + // FIXME(-Znext-solver): Not needed when the hack below is removed. let errors = ocx.select_where_possible(); if !errors.is_empty() { let reported = infcx.err_ctxt().report_fulfillment_errors(errors); @@ -333,8 +324,9 @@ fn compare_method_predicate_entailment<'tcx>( // trigger the lint. Instead, let's only consider type outlives and // region outlives obligations. // - // FIXME(-Ztrait-solver=next): Try removing this hack again once - // the new solver is stable. + // FIXME(-Znext-solver): Try removing this hack again once the new + // solver is stable. We should just be able to register a WF pred for + // the fn sig. let mut wf_args: smallvec::SmallVec<[_; 4]> = unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect(); // Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?)) @@ -357,7 +349,7 @@ fn compare_method_predicate_entailment<'tcx>( // We need to register Projection oblgiations too, because we may end up with // an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`. // If we only register the region outlives obligation, this leads to an unconstrained var. - // See `implied_bounds_entailment_alias_var` test. + // See `implied_bounds_entailment_alias_var.rs` test. ty::PredicateKind::Clause( ty::ClauseKind::RegionOutlives(..) | ty::ClauseKind::TypeOutlives(..) @@ -378,26 +370,8 @@ fn compare_method_predicate_entailment<'tcx>( // version. let errors = ocx.select_all_or_error(); if !errors.is_empty() { - match check_implied_wf { - CheckImpliedWfMode::Check => { - let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id); - return compare_method_predicate_entailment( - tcx, - impl_m, - trait_m, - impl_trait_ref, - CheckImpliedWfMode::Skip, - ) - .map(|()| { - // If the skip-mode was successful, emit a lint. - emit_implied_wf_lint(infcx.tcx, impl_m, impl_m_hir_id, vec![]); - }); - } - CheckImpliedWfMode::Skip => { - let reported = infcx.err_ctxt().report_fulfillment_errors(errors); - return Err(reported); - } - } + let reported = infcx.err_ctxt().report_fulfillment_errors(errors); + return Err(reported); } // Finally, resolve all regions. This catches wily misuses of @@ -408,119 +382,14 @@ fn compare_method_predicate_entailment<'tcx>( ); let errors = infcx.resolve_regions(&outlives_env); if !errors.is_empty() { - // FIXME(compiler-errors): This can be simplified when IMPLIED_BOUNDS_ENTAILMENT - // becomes a hard error (i.e. ideally we'd just call `resolve_regions_and_report_errors` - let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id); - match check_implied_wf { - CheckImpliedWfMode::Check => { - return compare_method_predicate_entailment( - tcx, - impl_m, - trait_m, - impl_trait_ref, - CheckImpliedWfMode::Skip, - ) - .map(|()| { - let bad_args = extract_bad_args_for_implies_lint( - tcx, - &errors, - (trait_m, trait_sig), - // Unnormalized impl sig corresponds to the HIR types written - (impl_m, unnormalized_impl_sig), - impl_m_hir_id, - ); - // If the skip-mode was successful, emit a lint. - emit_implied_wf_lint(tcx, impl_m, impl_m_hir_id, bad_args); - }); - } - CheckImpliedWfMode::Skip => { - if infcx.tainted_by_errors().is_none() { - infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors); - } - return Err(tcx - .sess - .span_delayed_bug(rustc_span::DUMMY_SP, "error should have been emitted")); - } - } + return Err(infcx + .tainted_by_errors() + .unwrap_or_else(|| infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors))); } Ok(()) } -fn extract_bad_args_for_implies_lint<'tcx>( - tcx: TyCtxt<'tcx>, - errors: &[infer::RegionResolutionError<'tcx>], - (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>), - (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>), - hir_id: hir::HirId, -) -> Vec<(Span, Option<String>)> { - let mut blame_generics = vec![]; - for error in errors { - // Look for the subregion origin that contains an input/output type - let origin = match error { - infer::RegionResolutionError::ConcreteFailure(o, ..) => o, - infer::RegionResolutionError::GenericBoundFailure(o, ..) => o, - infer::RegionResolutionError::SubSupConflict(_, _, o, ..) => o, - infer::RegionResolutionError::UpperBoundUniverseConflict(.., o, _) => o, - }; - // Extract (possible) input/output types from origin - match origin { - infer::SubregionOrigin::Subtype(trace) => { - if let Some((a, b)) = trace.values.ty() { - blame_generics.extend([a, b]); - } - } - infer::SubregionOrigin::RelateParamBound(_, ty, _) => blame_generics.push(*ty), - infer::SubregionOrigin::ReferenceOutlivesReferent(ty, _) => blame_generics.push(*ty), - _ => {} - } - } - - let fn_decl = tcx.hir().fn_decl_by_hir_id(hir_id).unwrap(); - let opt_ret_ty = match fn_decl.output { - hir::FnRetTy::DefaultReturn(_) => None, - hir::FnRetTy::Return(ty) => Some(ty), - }; - - // Map late-bound regions from trait to impl, so the names are right. - let mapping = std::iter::zip( - tcx.fn_sig(trait_m.def_id).skip_binder().bound_vars(), - tcx.fn_sig(impl_m.def_id).skip_binder().bound_vars(), - ) - .filter_map(|(impl_bv, trait_bv)| { - if let ty::BoundVariableKind::Region(impl_bv) = impl_bv - && let ty::BoundVariableKind::Region(trait_bv) = trait_bv - { - Some((impl_bv, trait_bv)) - } else { - None - } - }) - .collect(); - - // For each arg, see if it was in the "blame" of any of the region errors. - // If so, then try to produce a suggestion to replace the argument type with - // one from the trait. - let mut bad_args = vec![]; - for (idx, (ty, hir_ty)) in - std::iter::zip(impl_sig.inputs_and_output, fn_decl.inputs.iter().chain(opt_ret_ty)) - .enumerate() - { - let expected_ty = trait_sig.inputs_and_output[idx] - .fold_with(&mut RemapLateBound { tcx, mapping: &mapping }); - if blame_generics.iter().any(|blame| ty.contains(*blame)) { - let expected_ty_sugg = expected_ty.to_string(); - bad_args.push(( - hir_ty.span, - // Only suggest something if it actually changed. - (expected_ty_sugg != ty.to_string()).then_some(expected_ty_sugg), - )); - } - } - - bad_args -} - struct RemapLateBound<'a, 'tcx> { tcx: TyCtxt<'tcx>, mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>, @@ -544,53 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> { } } -fn emit_implied_wf_lint<'tcx>( - tcx: TyCtxt<'tcx>, - impl_m: ty::AssocItem, - hir_id: hir::HirId, - bad_args: Vec<(Span, Option<String>)>, -) { - let span: MultiSpan = if bad_args.is_empty() { - tcx.def_span(impl_m.def_id).into() - } else { - bad_args.iter().map(|(span, _)| *span).collect::<Vec<_>>().into() - }; - tcx.struct_span_lint_hir( - rustc_session::lint::builtin::IMPLIED_BOUNDS_ENTAILMENT, - hir_id, - span, - "impl method assumes more implied bounds than the corresponding trait method", - |lint| { - let bad_args: Vec<_> = - bad_args.into_iter().filter_map(|(span, sugg)| Some((span, sugg?))).collect(); - if !bad_args.is_empty() { - lint.multipart_suggestion( - format!( - "replace {} type{} to make the impl signature compatible", - pluralize!("this", bad_args.len()), - pluralize!(bad_args.len()) - ), - bad_args, - Applicability::MaybeIncorrect, - ); - } - lint - }, - ); -} - -#[derive(Debug, PartialEq, Eq)] -enum CheckImpliedWfMode { - /// Checks implied well-formedness of the impl method. If it fails, we will - /// re-check with `Skip`, and emit a lint if it succeeds. - Check, - /// Skips checking implied well-formedness of the impl method, but will emit - /// a lint if the `compare_method_predicate_entailment` succeeded. This means that - /// the reason that we had failed earlier during `Check` was due to the impl - /// having stronger requirements than the trait. - Skip, -} - fn compare_asyncness<'tcx>( tcx: TyCtxt<'tcx>, impl_m: ty::AssocItem, @@ -1086,8 +908,14 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> { _ => return Ok(region), } - let e = if let Some(region) = self.map.get(®ion) { - if let ty::ReEarlyParam(e) = region.kind() { e } else { bug!() } + let e = if let Some(id_region) = self.map.get(®ion) { + if let ty::ReEarlyParam(e) = id_region.kind() { + e + } else { + bug!( + "expected to map region {region} to early-bound identity region, but got {id_region}" + ); + } } else { let guar = match region.kind() { ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) @@ -1710,92 +1538,87 @@ fn compare_synthetic_generics<'tcx>( trait_m.name ); err.span_label(trait_span, "declaration in trait here"); - match (impl_synthetic, trait_synthetic) { + if impl_synthetic { // The case where the impl method uses `impl Trait` but the trait method uses // explicit generics - (true, false) => { - err.span_label(impl_span, "expected generic parameter, found `impl Trait`"); - let _: Option<_> = try { - // try taking the name from the trait impl - // FIXME: this is obviously suboptimal since the name can already be used - // as another generic argument - let new_name = tcx.opt_item_name(trait_def_id)?; - let trait_m = trait_m.def_id.as_local()?; - let trait_m = tcx.hir().expect_trait_item(trait_m); - - let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); - - // in case there are no generics, take the spot between the function name - // and the opening paren of the argument list - let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi(); - // in case there are generics, just replace them - let generics_span = - impl_m.generics.span.substitute_dummy(new_generics_span); - // replace with the generics from the trait - let new_generics = - tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?; - - err.multipart_suggestion( - "try changing the `impl Trait` argument to a generic parameter", - vec![ - // replace `impl Trait` with `T` - (impl_span, new_name.to_string()), - // replace impl method generics with trait method generics - // This isn't quite right, as users might have changed the names - // of the generics, but it works for the common case - (generics_span, new_generics), - ], - Applicability::MaybeIncorrect, - ); - }; - } + err.span_label(impl_span, "expected generic parameter, found `impl Trait`"); + let _: Option<_> = try { + // try taking the name from the trait impl + // FIXME: this is obviously suboptimal since the name can already be used + // as another generic argument + let new_name = tcx.opt_item_name(trait_def_id)?; + let trait_m = trait_m.def_id.as_local()?; + let trait_m = tcx.hir().expect_trait_item(trait_m); + + let impl_m = impl_m.def_id.as_local()?; + let impl_m = tcx.hir().expect_impl_item(impl_m); + + // in case there are no generics, take the spot between the function name + // and the opening paren of the argument list + let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi(); + // in case there are generics, just replace them + let generics_span = impl_m.generics.span.substitute_dummy(new_generics_span); + // replace with the generics from the trait + let new_generics = + tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?; + + err.multipart_suggestion( + "try changing the `impl Trait` argument to a generic parameter", + vec![ + // replace `impl Trait` with `T` + (impl_span, new_name.to_string()), + // replace impl method generics with trait method generics + // This isn't quite right, as users might have changed the names + // of the generics, but it works for the common case + (generics_span, new_generics), + ], + Applicability::MaybeIncorrect, + ); + }; + } else { // The case where the trait method uses `impl Trait`, but the impl method uses // explicit generics. - (false, true) => { - err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); - let _: Option<_> = try { - let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); - let (sig, _) = impl_m.expect_fn(); - let input_tys = sig.decl.inputs; - - struct Visitor(Option<Span>, hir::def_id::LocalDefId); - impl<'v> intravisit::Visitor<'v> for Visitor { - fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { - intravisit::walk_ty(self, ty); - if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind - && let Res::Def(DefKind::TyParam, def_id) = path.res - && def_id == self.1.to_def_id() - { - self.0 = Some(ty.span); - } + err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); + let _: Option<_> = try { + let impl_m = impl_m.def_id.as_local()?; + let impl_m = tcx.hir().expect_impl_item(impl_m); + let (sig, _) = impl_m.expect_fn(); + let input_tys = sig.decl.inputs; + + struct Visitor(Option<Span>, hir::def_id::LocalDefId); + impl<'v> intravisit::Visitor<'v> for Visitor { + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { + intravisit::walk_ty(self, ty); + if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind + && let Res::Def(DefKind::TyParam, def_id) = path.res + && def_id == self.1.to_def_id() + { + self.0 = Some(ty.span); } } + } - let mut visitor = Visitor(None, impl_def_id); - for ty in input_tys { - intravisit::Visitor::visit_ty(&mut visitor, ty); - } - let span = visitor.0?; - - let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds; - let bounds = bounds.first()?.span().to(bounds.last()?.span()); - let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?; - - err.multipart_suggestion( - "try removing the generic parameter and using `impl Trait` instead", - vec![ - // delete generic parameters - (impl_m.generics.span, String::new()), - // replace param usage with `impl Trait` - (span, format!("impl {bounds}")), - ], - Applicability::MaybeIncorrect, - ); - }; - } - _ => unreachable!(), + let mut visitor = Visitor(None, impl_def_id); + for ty in input_tys { + intravisit::Visitor::visit_ty(&mut visitor, ty); + } + let span = visitor.0?; + + let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds; + let bounds = bounds.first()?.span().to(bounds.last()?.span()); + let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?; + + err.multipart_suggestion( + "try removing the generic parameter and using `impl Trait` instead", + vec![ + // delete generic parameters + (impl_m.generics.span, String::new()), + // replace param usage with `impl Trait` + (span, format!("impl {bounds}")), + ], + Applicability::MaybeIncorrect, + ); + }; } error_found = Some(err.emit_unless(delay)); } @@ -1859,7 +1682,9 @@ fn compare_generic_param_kinds<'tcx>( // this is exhaustive so that anyone adding new generic param kinds knows // to make sure this error is reported for them. (Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false, - (Lifetime { .. }, _) | (_, Lifetime { .. }) => unreachable!(), + (Lifetime { .. }, _) | (_, Lifetime { .. }) => { + bug!("lifetime params are expected to be filtered by `ty_const_params_of`") + } } { let param_impl_span = tcx.def_span(param_impl.def_id); let param_trait_span = tcx.def_span(param_trait.def_id); @@ -1883,7 +1708,10 @@ fn compare_generic_param_kinds<'tcx>( ) } Type { .. } => format!("{prefix} type parameter"), - Lifetime { .. } => unreachable!(), + Lifetime { .. } => span_bug!( + tcx.def_span(param.def_id), + "lifetime params are expected to be filtered by `ty_const_params_of`" + ), }; let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap(); @@ -2181,13 +2009,16 @@ pub(super) fn check_type_bounds<'tcx>( let impl_ty_span = if impl_ty.is_impl_trait_in_trait() { tcx.def_span(impl_ty_def_id) } else { - match tcx.hir().get_by_def_id(impl_ty_def_id) { + match tcx.hir_node_by_def_id(impl_ty_def_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(_, Some(ty)), .. }) => ty.span, hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span, - _ => bug!(), + item => span_bug!( + tcx.def_span(impl_ty_def_id), + "cannot call `check_type_bounds` on item: {item:?}", + ), } }; let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl_ty_def_id)?; 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 86c38480d57..67796855ece 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 @@ -262,7 +262,10 @@ fn report_mismatched_rpitit_signature<'tcx>( if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() { let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else { - bug!(); + span_bug!( + tcx.def_span(trait_m_def_id), + "expected return type of async fn in trait to be a AFIT projection" + ); }; let Some(future_output_ty) = tcx .explicit_item_bounds(future_ty.def_id) @@ -272,13 +275,13 @@ fn report_mismatched_rpitit_signature<'tcx>( _ => None, }) else { - bug!() + span_bug!(tcx.def_span(trait_m_def_id), "expected `Future` projection bound in AFIT"); }; return_ty = future_output_ty; } let (span, impl_return_span, pre, post) = - match tcx.hir().get_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output { + match tcx.hir_node_by_def_id(impl_m_def_id.expect_local()).fn_decl().unwrap().output { hir::FnRetTy::DefaultReturn(span) => (tcx.def_span(impl_m_def_id), span, "-> ", " "), hir::FnRetTy::Return(ty) => (ty.span, ty.span, "", ""), }; diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index 947e50d3161..8f194ae88ab 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -43,7 +43,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { return None; } let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local()); - match tcx.hir().find(hir_id) { + match tcx.opt_hir_node(hir_id) { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { generics.params.is_empty().not().then_some(generics.span) } @@ -58,7 +58,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { return None; } let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local()); - match tcx.hir().find(hir_id) { + match tcx.opt_hir_node(hir_id) { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => { Some(generics.where_clause_span) } @@ -80,7 +80,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { return None; } let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local()); - match tcx.hir().find(hir_id) { + match tcx.opt_hir_node(hir_id) { Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => { Some(fn_sig.decl.output.span()) } @@ -199,7 +199,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { let start_t = tcx.type_of(start_def_id).instantiate_identity(); match start_t.kind() { ty::FnDef(..) => { - if let Some(Node::Item(it)) = tcx.hir().find(start_id) { + if let Some(Node::Item(it)) = tcx.opt_hir_node(start_id) { if let hir::ItemKind::Fn(sig, generics, _) = &it.kind { let mut error = false; if !generics.params.is_empty() { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 2428fe6ae79..d86ebc2c9c3 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, 64 => InlineAsmType::I64, - _ => unreachable!(), + width => bug!("unsupported pointer width: {width}"), }; match *ty.kind() { @@ -101,7 +101,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { 16 => InlineAsmType::VecI16(size), 32 => InlineAsmType::VecI32(size), 64 => InlineAsmType::VecI64(size), - _ => unreachable!(), + width => bug!("unsupported pointer width: {width}"), }) } ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)), @@ -109,7 +109,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { _ => None, } } - ty::Infer(_) => unreachable!(), + ty::Infer(_) => bug!("unexpected infer ty in asm operand"), _ => None, } } @@ -136,8 +136,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => { let fields = &adt.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args); - let ty::Adt(ty, args) = ty.kind() else { unreachable!() }; - assert!(ty.is_manually_drop()); + // FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`? + // If so, just get it from the args. + let ty::Adt(ty, args) = ty.kind() else { + unreachable!("expected first field of `MaybeUninit` to be an ADT") + }; + assert!( + ty.is_manually_drop(), + "expected first field of `MaybeUnit` to be `ManuallyDrop`" + ); let fields = &ty.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args); self.get_asm_ty(ty) @@ -269,7 +276,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { lint.help(format!( "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`", )); - lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index d08a8305105..df17879a967 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -130,7 +130,7 @@ fn get_owner_return_paths( ) -> Option<(LocalDefId, ReturnsVisitor<'_>)> { let hir_id = tcx.local_def_id_to_hir_id(def_id); let parent_id = tcx.hir().get_parent_item(hir_id).def_id; - tcx.hir().find_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| { + tcx.opt_hir_node_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| { let body = tcx.hir().body(body_id); let mut visitor = ReturnsVisitor::default(); visitor.visit_body(body); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3e805ab00b9..64026cdfff4 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -204,11 +204,14 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() res = Err(err.emit()); } // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. - match (tcx.impl_polarity(def_id), impl_.polarity) { - (ty::ImplPolarity::Positive, _) => { + match tcx.impl_polarity(def_id) { + ty::ImplPolarity::Positive => { res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait)); } - (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => { + ty::ImplPolarity::Negative => { + let ast::ImplPolarity::Negative(span) = impl_.polarity else { + bug!("impl_polarity query disagrees with impl's polarity in AST"); + }; // FIXME(#27579): what amount of WF checking do we need for neg impls? if let hir::Defaultness::Default { .. } = impl_.defaultness { let mut spans = vec![span]; @@ -222,10 +225,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() .emit()); } } - (ty::ImplPolarity::Reservation, _) => { + ty::ImplPolarity::Reservation => { // FIXME: what amount of WF checking do we need for reservation impls? } - _ => unreachable!(), } res } @@ -793,7 +795,7 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { /// When this is done, suggest using `Self` instead. fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { let (trait_name, trait_def_id) = - match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) { + match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) { hir::Node::Item(item) => match item.kind { hir::ItemKind::Trait(..) => (item.ident, item.owner_id), _ => return, @@ -992,15 +994,6 @@ fn check_associated_item( }) } -fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> { - match kind { - ItemKind::Struct(..) => Some(AdtKind::Struct), - ItemKind::Union(..) => Some(AdtKind::Union), - ItemKind::Enum(..) => Some(AdtKind::Enum), - _ => None, - } -} - /// In a type definition, we check that to ensure that the types of the fields are well-formed. fn check_type_defn<'tcx>( tcx: TyCtxt<'tcx>, @@ -1019,7 +1012,7 @@ fn check_type_defn<'tcx>( for field in &variant.fields { let field_id = field.did.expect_local(); let hir::FieldDef { ty: hir_ty, .. } = - tcx.hir().get_by_def_id(field_id).expect_field(); + tcx.hir_node_by_def_id(field_id).expect_field(); let ty = wfcx.normalize( hir_ty.span, None, @@ -1057,7 +1050,7 @@ fn check_type_defn<'tcx>( let last = idx == variant.fields.len() - 1; let field_id = field.did.expect_local(); let hir::FieldDef { ty: hir_ty, .. } = - tcx.hir().get_by_def_id(field_id).expect_field(); + tcx.hir_node_by_def_id(field_id).expect_field(); let ty = wfcx.normalize( hir_ty.span, None, @@ -1068,9 +1061,14 @@ fn check_type_defn<'tcx>( hir_ty.span, wfcx.body_def_id, traits::FieldSized { - adt_kind: match item_adt_kind(&item.kind) { - Some(i) => i, - None => bug!(), + adt_kind: match &item.kind { + ItemKind::Struct(..) => AdtKind::Struct, + ItemKind::Union(..) => AdtKind::Union, + ItemKind::Enum(..) => AdtKind::Enum, + kind => span_bug!( + item.span, + "should be wfchecking an ADT, got {kind:?}" + ), }, span: hir_ty.span, last, @@ -1302,7 +1300,9 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id | GenericParamDefKind::Const { has_default, .. } => { has_default && def.index >= generics.parent_count as u32 } - GenericParamDefKind::Lifetime => unreachable!(), + GenericParamDefKind::Lifetime => { + span_bug!(tcx.def_span(def.def_id), "lifetime params can have no default") + } }; // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. @@ -1750,15 +1750,15 @@ fn check_variances_for_type_defn<'tcx>( } } ItemKind::TyAlias(..) => { - if tcx.type_alias_is_lazy(item.owner_id) { - if tcx.type_of(item.owner_id).skip_binder().references_error() { - return; - } - } else { - bug!(); + assert!( + tcx.type_alias_is_lazy(item.owner_id), + "should not be computing variance of non-weak type alias" + ); + if tcx.type_of(item.owner_id).skip_binder().references_error() { + return; } } - _ => bug!(), + kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"), } let ty_predicates = tcx.predicates_of(item.owner_id); @@ -1882,7 +1882,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // Match the existing behavior. if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) { let pred = self.normalize(span, None, pred); - let hir_node = tcx.hir().find_by_def_id(self.body_def_id); + let hir_node = tcx.opt_hir_node_by_def_id(self.body_def_id); // only use the span of the predicate clause (#90869) diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 9ad73eeffc6..36cb8f7a202 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -45,7 +45,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { item.hir_id(), path.span, msg, - |lint| lint, + |_| {}, ); } } diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 45100457629..88128d22a3d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -522,7 +522,7 @@ fn lint_auto_trait_impl<'tcx>( format!( "try using the same sequence of generic parameters as the {self_descr} definition", ), - ) + ); }, ); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index ae35d6ebd75..d176665e4c0 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -221,7 +221,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( // Check if parent is const or static let parent_id = tcx.hir().parent_id(hir_ty.hir_id); - let parent_node = tcx.hir().get(parent_id); + let parent_node = tcx.hir_node(parent_id); is_const_or_static = matches!( parent_node, @@ -354,7 +354,7 @@ impl<'tcx> ItemCtxt<'tcx> { } pub fn node(&self) -> hir::Node<'tcx> { - self.tcx.hir().get(self.hir_id()) + self.tcx.hir_node(self.hir_id()) } } @@ -835,9 +835,8 @@ fn convert_variant( fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { use rustc_hir::*; - let hir_id = tcx.local_def_id_to_hir_id(def_id); - let Node::Item(item) = tcx.hir().get(hir_id) else { - bug!(); + let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else { + bug!("expected ADT to be an item"); }; let repr = tcx.repr_options_of_def(def_id.to_def_id()); @@ -888,7 +887,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { (adt_kind, variants) } - _ => bug!(), + _ => bug!("{:?} is not an ADT", item.owner_id.def_id), }; tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr) } @@ -1105,7 +1104,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig< let icx = ItemCtxt::new(tcx, def_id); - let output = match tcx.hir().get(hir_id) { + let output = match tcx.hir_node(hir_id) { TraitItem(hir::TraitItem { kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)), generics, @@ -1551,7 +1550,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( } fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> { - match tcx.hir().get_by_def_id(def_id) { + match tcx.hir_node_by_def_id(def_id) { Node::Expr(&rustc_hir::Expr { kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }), .. @@ -1561,7 +1560,7 @@ fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineK } fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { - match tcx.hir().get_by_def_id(def_id) { + match tcx.hir_node_by_def_id(def_id) { Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => { matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }) } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 114c5147e11..3ee2822edd8 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -16,7 +16,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { let hir_id = tcx.local_def_id_to_hir_id(def_id); - let node = tcx.hir().get(hir_id); + let node = tcx.hir_node(hir_id); let parent_def_id = match node { Node::ImplItem(_) | Node::TraitItem(_) @@ -279,7 +279,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { param.hir_id, param.span, TYPE_DEFAULT_NOT_ALLOWED, - |lint| lint, + |_| {}, ); } Defaults::Deny => { diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 4d0fd2b691a..39ca1bba065 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -34,17 +34,14 @@ fn associated_type_bounds<'tcx>( let trait_def_id = tcx.local_parent(assoc_item_def_id); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id); - let bounds_from_parent = trait_predicates - .predicates - .iter() - .copied() - .filter(|(pred, _)| match pred.kind().skip_binder() { + let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { + match pred.kind().skip_binder() { ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty, ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty, ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty, _ => false, - }) - .map(|(clause, span)| (clause, span)); + } + }); let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent)); debug!( @@ -86,7 +83,7 @@ pub(super) fn explicit_item_bounds( // RPITIT's bounds are the same as opaque type bounds, but with // a projection self type. Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { - let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item(); + let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item(); let opaque_ty = item.expect_opaque_ty(); return ty::EarlyBinder::bind(opaque_type_bounds( tcx, @@ -100,13 +97,14 @@ pub(super) fn explicit_item_bounds( item.span, )); } - // These should have been fed! - Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(), + Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!( + tcx.def_span(def_id), + "item bounds for RPITIT in impl to be fed on def-id creation" + ), None => {} } - let hir_id = tcx.local_def_id_to_hir_id(def_id); - let bounds = match tcx.hir().get(hir_id) { + let bounds = match tcx.hir_node_by_def_id(def_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(bounds, _), span, @@ -132,7 +130,7 @@ pub(super) fn explicit_item_bounds( let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin else { - bug!() + span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}"); }; let args = GenericArgs::identity_for_item(tcx, def_id); let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ca9443225e2..41520718aa8 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -135,7 +135,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } let hir_id = tcx.local_def_id_to_hir_id(def_id); - let node = tcx.hir().get(hir_id); + let node = tcx.hir_node(hir_id); let mut is_trait = None; let mut is_default_impl_trait = None; @@ -296,7 +296,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen hir::GenericBound::Outlives(lt) => { (icx.astconv().ast_region_to_region(lt, None), lt.ident.span) } - _ => bug!(), + bound => { + span_bug!( + bound.span(), + "lifetime param bounds must be outlives, but found {bound:?}" + ) + } }; let pred = ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)) .to_predicate(tcx); @@ -337,7 +342,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // and the duplicated parameter, to ensure that they do not get out of sync. if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { let opaque_ty_id = tcx.hir().parent_id(hir_id); - let opaque_ty_node = tcx.hir().get(opaque_ty_id); + let opaque_ty_node = tcx.hir_node(opaque_ty_id); let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else { bug!("unexpected {opaque_ty_node:?}") }; @@ -413,7 +418,7 @@ fn const_evaluatable_predicates_of( } let hir_id = tcx.local_def_id_to_hir_id(def_id); - let node = tcx.hir().get(hir_id); + let node = tcx.hir_node(hir_id); let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() }; if let hir::Node::Item(item) = node @@ -633,7 +638,7 @@ pub(super) fn implied_predicates_with_filter( let trait_hir_id = tcx.local_def_id_to_hir_id(trait_def_id); - let Node::Item(item) = tcx.hir().get(trait_hir_id) else { + let Node::Item(item) = tcx.hir_node(trait_hir_id) else { bug!("trait_node_id {} is not an item", trait_hir_id); }; @@ -713,7 +718,7 @@ pub(super) fn type_param_predicates( let mut extend = None; let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id); - let ast_generics = match tcx.hir().get(item_hir_id) { + let ast_generics = match tcx.hir_node(item_hir_id) { Node::TraitItem(item) => item.generics, Node::ImplItem(item) => item.generics, 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 e939b7abd90..9f0742dade8 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -350,7 +350,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // Nested poly trait refs have the binders concatenated let mut full_binders = self.map.late_bound_vars.entry(*hir_id).or_default().clone(); - full_binders.extend(supertrait_bound_vars.into_iter()); + full_binders.extend(supertrait_bound_vars); break (full_binders, BinderScopeType::Concatenating); } } @@ -748,7 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } if let hir::Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy { .. }, .. - }) = self.tcx.hir().get(parent_id) + }) = self.tcx.hir_node(parent_id) { let mut err = self.tcx.sess.struct_span_err( lifetime.ident.span, @@ -925,7 +925,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { "you can use the `'static` lifetime directly, in place of `{}`", lifetime.ident, ); - lint.help(help) + lint.help(help); }, ); } @@ -938,32 +938,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } - fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) { - match bound { - hir::GenericBound::LangItemTrait(_, _, hir_id, _) => { - // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go - // through the regular poly trait ref code, so we don't get another - // chance to introduce a binder. For now, I'm keeping the existing logic - // of "if there isn't a Binder scope above us, add one", but I - // imagine there's a better way to go about this. - let (binders, scope_type) = self.poly_trait_ref_binder_info(); - - self.record_late_bound_vars(*hir_id, binders); - let scope = Scope::Binder { - hir_id: *hir_id, - bound_vars: FxIndexMap::default(), - s: self.scope, - scope_type, - where_bound_origin: None, - }; - self.with(scope, |this| { - intravisit::walk_param_bound(this, bound); - }); - } - _ => intravisit::walk_param_bound(self, bound), - } - } - fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) { self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow); } @@ -1004,7 +978,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { fn object_lifetime_default(tcx: TyCtxt<'_>, param_def_id: LocalDefId) -> ObjectLifetimeDefault { debug_assert_eq!(tcx.def_kind(param_def_id), DefKind::TyParam); - let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(param_def_id) else { + let hir::Node::GenericParam(param) = tcx.hir_node_by_def_id(param_def_id) else { bug!("expected GenericParam for object_lifetime_default"); }; match param.source { @@ -1300,12 +1274,16 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { what, }) } - _ => unreachable!(), + kind => span_bug!( + use_span, + "did not expect to resolve lifetime to {}", + kind.descr(param_def_id) + ), }; def = ResolvedArg::Error(guar); } else if let Some(body_id) = outermost_body { let fn_id = self.tcx.hir().body_owner(body_id); - match self.tcx.hir().get(fn_id) { + match self.tcx.hir_node(fn_id) { Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn(..), .. }) | Node::TraitItem(hir::TraitItem { owner_id, @@ -1441,7 +1419,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { what, }) } - _ => unreachable!(), + kind => span_bug!( + use_span, + "did not expect to resolve non-lifetime param to {}", + kind.descr(param_def_id.to_def_id()) + ), }; self.map.defs.insert(hir_id, ResolvedArg::Error(guar)); } else { @@ -2122,8 +2104,8 @@ pub fn deny_non_region_late_bound( let mut first = true; for (var, arg) in bound_vars { - let Node::GenericParam(param) = tcx.hir().get_by_def_id(*var) else { - bug!(); + let Node::GenericParam(param) = tcx.hir_node_by_def_id(*var) else { + span_bug!(tcx.def_span(*var), "expected bound-var def-id to resolve to param"); }; let what = match param.kind { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c4fc4dda069..174217d3b70 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -20,10 +20,16 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { use rustc_middle::ty::Ty; let hir_id = tcx.local_def_id_to_hir_id(def_id); - let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() }; + let node = tcx.hir_node(hir_id); + let Node::AnonConst(_) = node else { + span_bug!( + tcx.def_span(def_id), + "expected anon const in `anon_const_type_of`, got {node:?}" + ); + }; let parent_node_id = tcx.hir().parent_id(hir_id); - let parent_node = tcx.hir().get(parent_node_id); + let parent_node = tcx.hir_node(parent_node_id); let (generics, arg_idx) = match parent_node { // Easy case: arrays repeat expressions. @@ -61,7 +67,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { } Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) - if let Node::TraitRef(trait_ref) = tcx.hir().get(tcx.hir().parent_id(binding_id)) => + if let Node::TraitRef(trait_ref) = tcx.hir_node(tcx.hir().parent_id(binding_id)) => { let Some(trait_def_id) = trait_ref.trait_def_id() else { return Ty::new_error_with_message( @@ -354,7 +360,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty let icx = ItemCtxt::new(tcx, def_id); - let output = match tcx.hir().get(hir_id) { + let output = match tcx.hir_node(hir_id) { Node::TraitItem(item) => match item.kind { TraitItemKind::Fn(..) => { let args = ty::GenericArgs::identity_for_item(tcx, def_id); @@ -517,8 +523,7 @@ pub(super) fn type_of_opaque( if let Some(def_id) = def_id.as_local() { use rustc_hir::*; - let hir_id = tcx.local_def_id_to_hir_id(def_id); - Ok(ty::EarlyBinder::bind(match tcx.hir().get(hir_id) { + Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) { Node::Item(item) => match item.kind { ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias { .. }, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index f11a953536d..bf0d9d4856a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -50,8 +50,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local if scope == hir::CRATE_HIR_ID { tcx.hir().walk_toplevel_module(&mut locator); } else { - trace!("scope={:#?}", tcx.hir().get(scope)); - match tcx.hir().get(scope) { + trace!("scope={:#?}", tcx.hir_node(scope)); + match tcx.hir_node(scope) { // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods // This allows our visitor to process the defining item itself, causing // it to pick up any 'sibling' defining uses. @@ -95,7 +95,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local let reported = tcx.sess.emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), name: tcx.item_name(parent_def_id.to_def_id()), - what: match tcx.hir().get(scope) { + what: match tcx.hir_node(scope) { _ if scope == hir::CRATE_HIR_ID => "module", Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module", Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl", @@ -282,7 +282,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>( debug!(?scope); let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty }; - match tcx.hir().get(scope) { + match tcx.hir_node(scope) { Node::Item(it) => intravisit::walk_item(&mut locator, it), Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it), Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it), diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 4ed1377e7fc..78745fe47ab 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -122,7 +122,7 @@ fn diagnostic_hir_wf_check<'tcx>( // We will walk 'into' this type to try to find // a more precise span for our predicate. let tys = match loc { - WellFormedLoc::Ty(_) => match hir.get(hir_id) { + WellFormedLoc::Ty(_) => match tcx.hir_node(hir_id) { hir::Node::ImplItem(item) => match item.kind { hir::ImplItemKind::Type(ty) => vec![ty], hir::ImplItemKind::Const(ty, _) => vec![ty], diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index c065f6e7e88..9541e510702 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -41,7 +41,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau } } - match tcx.hir().get(id) { + match tcx.hir_node(id) { Node::Item(item) => match item.kind { hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => { let crate_map = tcx.inferred_outlives_crate(()); diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 76bd370a641..fab841e3679 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -137,10 +137,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { // is from the 'of_trait' field of the enclosing impl let parent = self.tcx.hir().get_parent(self.path_segment.hir_id); - let parent_item = self - .tcx - .hir() - .get_by_def_id(self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id); + let parent_item = self.tcx.hir_node_by_def_id( + self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id, + ); // Get the HIR id of the trait ref let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else { @@ -774,7 +773,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { ); if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id) - && let Some(parent_node) = self.tcx.hir().find(parent_node) + && let Some(parent_node) = self.tcx.opt_hir_node(parent_node) && let hir::Node::Expr(expr) = parent_node { match &expr.kind { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 8701626058d..21a50b94a37 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2003,18 +2003,14 @@ impl<'a> State<'a> { }); self.word("|"); - if let hir::FnRetTy::DefaultReturn(..) = decl.output { - return; - } - - self.space_if_not_bol(); - self.word_space("->"); match decl.output { hir::FnRetTy::Return(ty) => { + self.space_if_not_bol(); + self.word_space("->"); self.print_type(ty); self.maybe_print_comment(ty.span.lo()); } - hir::FnRetTy::DefaultReturn(..) => unreachable!(), + hir::FnRetTy::DefaultReturn(..) => {} } } @@ -2088,11 +2084,6 @@ impl<'a> State<'a> { } self.print_poly_trait_ref(tref); } - GenericBound::LangItemTrait(lang_item, span, ..) => { - self.word("#[lang = \""); - self.print_ident(Ident::new(lang_item.name(), *span)); - self.word("\"]"); - } GenericBound::Outlives(lt) => { self.print_lifetime(lt); } @@ -2179,7 +2170,7 @@ impl<'a> State<'a> { GenericBound::Outlives(lt) => { self.print_lifetime(lt); } - _ => panic!(), + _ => panic!("unexpected bound on lifetime param: {bound:?}"), } if i != 0 { @@ -2216,16 +2207,14 @@ impl<'a> State<'a> { } fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) { - if let hir::FnRetTy::DefaultReturn(..) = decl.output { - return; - } - - self.space_if_not_bol(); - self.ibox(INDENT_UNIT); - self.word_space("->"); match decl.output { - hir::FnRetTy::DefaultReturn(..) => unreachable!(), - hir::FnRetTy::Return(ty) => self.print_type(ty), + hir::FnRetTy::Return(ty) => { + self.space_if_not_bol(); + self.ibox(INDENT_UNIT); + self.word_space("->"); + self.print_type(ty); + } + hir::FnRetTy::DefaultReturn(..) => return, } self.end(); diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index e7cbbc71335..181de372840 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -238,8 +238,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // Next, make sure that we have no type expectation. - let Some(ret) = hir - .find_by_def_id(self.body_id) + let Some(ret) = self + .tcx + .opt_hir_node_by_def_id(self.body_id) .and_then(|owner| owner.fn_decl()) .map(|decl| decl.output.span()) else { @@ -317,7 +318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: hir::HirId, sp: Span, ) -> Option<(Span, String)> { - let node = self.tcx.hir().get(hir_id); + let node = self.tcx.hir_node(hir_id); if let hir::Node::Block(block) = node { // check that the body's parent is an fn let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id)); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 512946cc504..baca2be06e6 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -295,7 +295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let hir = self.tcx.hir(); let parent_hir_id = hir.parent_id(hir_id); - let parent_node = hir.get(parent_hir_id); + let parent_node = self.tcx.hir_node(parent_hir_id); if let ( hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, body, .. }), @@ -313,7 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. - }) = hir.get(async_closure) + }) = self.tcx.hir_node(async_closure) { fn_decl_span } else { @@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_expr: &'tcx hir::Expr<'tcx>, ) -> bool { let hir_id = self.tcx.hir().parent_id(call_expr.hir_id); - let parent_node = self.tcx.hir().get(hir_id); + let parent_node = self.tcx.hir_node(hir_id); if let ( hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }), hir::ExprKind::Tup(exp), diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index d89af297560..0de0365364c 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum CastError { ErrorGuaranteed(ErrorGuaranteed), @@ -271,7 +271,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { match e { CastError::NeedViaPtr => "a raw pointer", CastError::NeedViaThinPtr => "a thin pointer", - _ => bug!(), + e => unreachable!("control flow means we should never encounter a {e:?}"), } )); } @@ -288,13 +288,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.cast_ty, fcx, ) - .help(format!( - "cast through {} first", - match e { - CastError::NeedViaInt => "an integer", - _ => bug!(), - } - )) + .help("cast through an integer first") .emit(); } CastError::IllegalCast => { @@ -534,7 +528,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let unknown_cast_to = match e { CastError::UnknownCastPtrKind => true, CastError::UnknownExprPtrKind => false, - _ => bug!(), + e => unreachable!("control flow means we should never encounter a {e:?}"), }; let (span, sub) = if unknown_cast_to { (self.cast_span, errors::CastUnknownPointerSub::To(self.cast_span)) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index f0bb18df48c..7e43d67587b 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -141,7 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?sig, ?opt_kind); let closure_kind_ty = match opt_kind { - Some(kind) => kind.to_ty(self.tcx), + Some(kind) => Ty::from_closure_kind(self.tcx, kind), // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) @@ -483,8 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { body: &hir::Body<'_>, expected_sig: ExpectedSig<'tcx>, ) -> ClosureSignatures<'tcx> { - let hir = self.tcx.hir(); - let expr_map_node = hir.get_by_def_id(expr_def_id); + let expr_map_node = self.tcx.hir_node_by_def_id(expr_def_id); let expected_args: Vec<_> = expected_sig .sig .skip_binder() diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 0d3bb0f7e0c..61236c07135 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1019,7 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Returns false if the coercion creates any obligations that result in /// errors. pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool { - // FIXME(-Ztrait-solver=next): We need to structurally resolve both types here. + // FIXME(-Znext-solver): We need to structurally resolve both types here. let source = self.resolve_vars_with_obligations(expr_ty); debug!("coercion::can_with_predicates({:?} -> {:?})", source, target); @@ -1182,14 +1182,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Adjust::Pointer(PointerCoercion::ClosureFnPointer(a_sig.unsafety())) } ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer), - _ => unreachable!(), + _ => span_bug!(cause.span, "should not try to coerce a {prev_ty} to a fn pointer"), }; let next_adjustment = match new_ty.kind() { ty::Closure(..) => { Adjust::Pointer(PointerCoercion::ClosureFnPointer(b_sig.unsafety())) } ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer), - _ => unreachable!(), + _ => span_bug!(new.span, "should not try to coerce a {new_ty} to a fn pointer"), }; for expr in exprs.iter().map(|e| e.as_coercion_site()) { self.apply_adjustments( @@ -1694,14 +1694,14 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let ret_msg = "return a value for the case when the loop has zero elements to iterate on"; let ret_ty_msg = "otherwise consider changing the return type to account for that possibility"; - if let Some(node) = hir.find(item.into()) + if let Some(node) = tcx.opt_hir_node(item.into()) && let Some(body_id) = node.body_id() && let Some(sig) = node.fn_sig() && let hir::ExprKind::Block(block, _) = hir.body(body_id).value.kind && !ty.is_never() { let indentation = if let None = block.expr - && let [.., last] = &block.stmts[..] + && let [.., last] = &block.stmts { tcx.sess.source_map().indentation_before(last.span).unwrap_or_else(String::new) } else if let Some(expr) = block.expr { @@ -1710,7 +1710,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { String::new() }; if let None = block.expr - && let [.., last] = &block.stmts[..] + && let [.., last] = &block.stmts { err.span_suggestion_verbose( last.span.shrink_to_hi(), @@ -1750,7 +1750,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } } if let None = block.expr - && let [.., last] = &block.stmts[..] + && let [.., last] = &block.stmts { sugg.push((last.span.shrink_to_hi(), format!("\n{indentation}None"))); } else if let Some(expr) = block.expr { @@ -1776,7 +1776,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); let parent_id = fcx.tcx.hir().parent_id(id); - let parent = fcx.tcx.hir().get(parent_id); + let parent = fcx.tcx.hir_node(parent_id); if let Some(expr) = expression && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), @@ -1835,7 +1835,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } let parent_id = fcx.tcx.hir().get_parent_item(id); - let parent_item = fcx.tcx.hir().get_by_def_id(parent_id.def_id); + let parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id); if let (Some(expr), Some(_), Some((fn_id, fn_decl, _, _))) = (expression, blk_id, fcx.get_node_fn_decl(parent_item)) @@ -1918,7 +1918,7 @@ where impl AsCoercionSite for ! { fn as_coercion_site(&self) -> &hir::Expr<'_> { - unreachable!() + *self } } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 8f633834885..8b666c63425 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir::def::Res::Local(local_hir_id) = p.res else { return false; }; - let hir::Node::Pat(pat) = hir.get(local_hir_id) else { + let hir::Node::Pat(pat) = self.tcx.hir_node(local_hir_id) else { return false; }; let (init_ty_hir_id, init) = match hir.get_parent(pat.hir_id) { @@ -331,13 +331,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty_op: |ty| { if let ty::Infer(infer) = ty.kind() { match infer { - ty::InferTy::TyVar(_) => self.next_ty_var(TypeVariableOrigin { + ty::TyVar(_) => self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, }), - ty::InferTy::IntVar(_) => self.next_int_var(), - ty::InferTy::FloatVar(_) => self.next_float_var(), - _ => bug!(), + ty::IntVar(_) => self.next_int_var(), + ty::FloatVar(_) => self.next_float_var(), + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { + bug!("unexpected fresh ty outside of the trait solver") + } } } else { ty @@ -557,7 +559,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. }) | hir::Node::Block(hir::Block { expr: Some(&ref p), .. }) | hir::Node::Expr(&ref p), - ) = self.tcx.hir().find(parent_id) + ) = self.tcx.opt_hir_node(parent_id) else { break; }; @@ -570,7 +572,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut direct = false; loop { // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to. - let parent = match self.tcx.hir().find(parent_id) { + let parent = match self.tcx.opt_hir_node(parent_id) { Some(hir::Node::Expr(&ref parent)) => { parent_id = self.tcx.hir().parent_id(parent.hir_id); parent @@ -672,7 +674,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: Option<TypeError<'tcx>>, ) { let parent = self.tcx.hir().parent_id(expr.hir_id); - match (self.tcx.hir().find(parent), error) { + match (self.tcx.opt_hir_node(parent), error) { (Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })), _) if init.hir_id == expr.hir_id => { @@ -717,7 +719,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, hir::Path { res: hir::def::Res::Local(hir_id), .. }, )) => { - if let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(*hir_id) { + if let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id) { primary_span = pat.span; secondary_span = pat.span; match self.tcx.hir().find_parent(pat.hir_id) { @@ -790,7 +792,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. })) = - self.tcx.hir().find(parent) + self.tcx.opt_hir_node(parent) else { return; }; @@ -862,7 +864,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mutability, ), ), - match &args[..] { + match &args { [] => (base.span.shrink_to_hi().with_hi(deref.span.hi()), ")".to_string()), [first, ..] => (base.span.between(first.span), ", ".to_string()), }, @@ -1014,8 +1016,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Path { res: hir::def::Res::Local(bind_hir_id), .. }, )) = expr.kind { - let bind = self.tcx.hir().find(*bind_hir_id); - let parent = self.tcx.hir().find(self.tcx.hir().parent_id(*bind_hir_id)); + let bind = self.tcx.opt_hir_node(*bind_hir_id); + let parent = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*bind_hir_id)); if let Some(hir::Node::Pat(hir::Pat { kind: hir::PatKind::Binding(_, _hir_id, _, _), .. diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 74aec897f95..ff03cf16a27 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -573,13 +573,13 @@ impl rustc_errors::AddToDiagnostic for CastUnknownPointerSub { { match self { CastUnknownPointerSub::To(span) => { - let msg = f(diag, crate::fluent_generated::hir_typeck_label_to.into()); + let msg = f(diag, crate::fluent_generated::hir_typeck_label_to); diag.span_label(span, msg); - let msg = f(diag, crate::fluent_generated::hir_typeck_note.into()); + let msg = f(diag, crate::fluent_generated::hir_typeck_note); diag.note(msg); } CastUnknownPointerSub::From(span) => { - let msg = f(diag, crate::fluent_generated::hir_typeck_label_from.into()); + let msg = f(diag, crate::fluent_generated::hir_typeck_label_from); diag.span_label(span, msg); } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7c157c0eae0..80265cf31e6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -883,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { kind: hir::ImplItemKind::Fn(..), span: encl_fn_span, .. - })) = self.tcx.hir().find_by_def_id(encl_item_id.def_id) + })) = self.tcx.opt_hir_node_by_def_id(encl_item_id.def_id) { // We are inside a function body, so reporting "return statement // outside of function body" needs an explanation. @@ -997,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { then: impl FnOnce(&hir::Expr<'_>), ) { let mut parent = self.tcx.hir().parent_id(original_expr_id); - while let Some(node) = self.tcx.hir().find(parent) { + while let Some(node) = self.tcx.opt_hir_node(parent) { match node { hir::Node::Expr(hir::Expr { kind: @@ -2087,7 +2087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let names = names.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>(); format!("{} and `{last}` ", names.join(", ")) } - [] => unreachable!(), + [] => bug!("expected at least one private field to report"), }; err.note(format!( "{}private field{s} {names}that {were} not provided", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index df840aaa578..3bee42eb89c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { orig_span, custom_note .unwrap_or("any code following this expression is unreachable"), - ) + ); }, ) } @@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// version (resolve_vars_if_possible), this version will /// also select obligations if it seems useful, in an effort /// to get more type information. - // FIXME(-Ztrait-solver=next): A lot of the calls to this method should + // FIXME(-Znext-solver): A lot of the calls to this method should // probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead. #[instrument(skip(self), level = "debug", ret)] pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> { @@ -994,7 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or // `while` before reaching it, as block tail returns are not available in them. self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| { - let parent = self.tcx.hir().get(blk_id); + let parent = self.tcx.hir_node(blk_id); self.get_node_fn_decl(parent) .map(|(fn_id, fn_decl, _, is_main)| (fn_id, fn_decl, is_main)) }) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 9b5459529ff..76360239c45 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -94,7 +94,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let hir = self.tcx.hir(); - let (expr, qpath) = match hir.get(hir_id) { + let (expr, qpath) = match self.tcx.hir_node(hir_id) { hir::Node::Expr(expr) => { if self.closure_span_overlaps_error(error, expr.span) { return false; @@ -454,7 +454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .find_ancestor_in_same_ctxt(error.obligation.cause.span) .unwrap_or(arg.span); - if let hir::Node::Expr(arg_expr) = self.tcx.hir().get(arg.hir_id) { + if let hir::Node::Expr(arg_expr) = self.tcx.hir_node(arg.hir_id) { // This is more specific than pointing at the entire argument. self.blame_specific_expr_if_possible(error, arg_expr) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index bb9b849f03b..3f97b24aa59 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -993,7 +993,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) { match e { Error::Missing(expected_idx) => missing_idxs.push(expected_idx), - _ => unreachable!(), + _ => unreachable!( + "control flow ensures that we should always get an `Error::Missing`" + ), } } @@ -1734,7 +1736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn parent_item_span(&self, id: hir::HirId) -> Option<Span> { - let node = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(id).def_id); + let node = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(id).def_id); match node { Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => { @@ -1750,7 +1752,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise. fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> { - let parent = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id); + let parent = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id); self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident)) } @@ -2018,7 +2020,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let new_def_id = self.probe(|_| { let trait_ref = ty::TraitRef::new( self.tcx, - call_kind.to_def_id(self.tcx), + self.tcx.fn_trait_kind_to_def_id(call_kind)?, [ callee_ty, self.next_ty_var(TypeVariableOrigin { @@ -2084,7 +2086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let node = self .tcx .opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id)) - .and_then(|hir_id| self.tcx.hir().find(hir_id)); + .and_then(|hir_id| self.tcx.opt_hir_node(hir_id)); match node { Some(hir::Node::Item(item)) => call_finder.visit_item(item), Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 2c9942caab2..668e547571f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -677,7 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // can suggest Box::pin. let parent = self.tcx.hir().parent_id(expr.hir_id); let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) = - self.tcx.hir().find(parent) + self.tcx.opt_hir_node(parent) else { return false; }; @@ -824,10 +824,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind && let hir::Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(op_ty), .. - }) = self.tcx.hir().get(item_id.hir_id()) - && let [ - hir::GenericBound::LangItemTrait(hir::LangItem::Future, _, _, generic_args), - ] = op_ty.bounds + }) = self.tcx.hir_node(item_id.hir_id()) + && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds + && let Some(hir::PathSegment { args: Some(generic_args), .. }) = + trait_ref.trait_ref.path.segments.last() && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } = ty_binding.kind @@ -902,7 +902,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty::Param(expected_ty_as_param) = expected.kind() else { return }; - let fn_node = self.tcx.hir().find(fn_id); + let fn_node = self.tcx.opt_hir_node(fn_id); let Some(hir::Node::Item(hir::Item { kind: @@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let ty = self.normalize(expr.span, ty); if self.can_coerce(found, ty) { - if let Some(node) = self.tcx.hir().find(fn_id) + if let Some(node) = self.tcx.opt_hir_node(fn_id) && let Some(owner_node) = node.as_owner() && let Some(span) = expr.span.find_ancestor_inside(owner_node.span()) { @@ -1545,12 +1545,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn is_loop(&self, id: hir::HirId) -> bool { - let node = self.tcx.hir().get(id); + let node = self.tcx.hir_node(id); matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. })) } fn is_local_statement(&self, id: hir::HirId) -> bool { - let node = self.tcx.hir().get(id); + let node = self.tcx.hir_node(id); matches!(node, Node::Stmt(Stmt { kind: StmtKind::Local(..), .. })) } @@ -1677,11 +1677,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, hir::Path { segments: [_], res: crate::Res::Local(binding), .. }, )) => { - let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.hir().find(*binding) + let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.opt_hir_node(*binding) else { return expr; }; - let Some(parent) = self.tcx.hir().find(self.tcx.hir().parent_id(*hir_id)) else { + let Some(parent) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id)) else { return expr; }; @@ -1697,7 +1697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .. }) => { let Some(hir::Node::Local(hir::Local { init: Some(init), .. })) = - self.tcx.hir().find(self.tcx.hir().parent_id(*pat_hir_id)) + self.tcx.opt_hir_node(self.tcx.hir().parent_id(*pat_hir_id)) else { return expr; }; @@ -1730,8 +1730,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } = call_expr_path && let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = - self.tcx.hir().find(*binding) - && let Some(closure) = self.tcx.hir().find(self.tcx.hir().parent_id(*hir_id)) + self.tcx.opt_hir_node(*binding) + && let Some(closure) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id)) && let hir::Node::Local(hir::Local { init: Some(init), .. }) = closure && let Expr { kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }), @@ -1985,7 +1985,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(hir::Node::Block(&hir::Block { span: block_span, expr: Some(e), .. - })) = self.tcx.hir().find(parent) + })) = self.tcx.opt_hir_node(parent) { if e.hir_id == id { if let Some(span) = expr.span.find_ancestor_inside(block_span) { @@ -2072,8 +2072,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(CtorKind::Fn) => ("(".to_owned(), ")"), None => (format!(" {{ {field_name}: "), " }"), - // unit variants don't have fields - Some(CtorKind::Const) => unreachable!(), + Some(CtorKind::Const) => unreachable!("unit variants don't have fields"), }; // Suggest constructor as deep into the block tree as possible. @@ -2211,7 +2210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let local_parent = self.tcx.hir().parent_id(local_id); let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) = - self.tcx.hir().find(local_parent) + self.tcx.opt_hir_node(local_parent) else { return None; }; @@ -2221,13 +2220,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: expr_hir_id, kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }), .. - })) = self.tcx.hir().find(param_parent) + })) = self.tcx.opt_hir_node(param_parent) else { return None; }; let expr_parent = self.tcx.hir().parent_id(*expr_hir_id); - let hir = self.tcx.hir().find(expr_parent); + let hir = self.tcx.opt_hir_node(expr_parent); let closure_params_len = closure_fn_decl.inputs.len(); let ( Some(Node::Expr(hir::Expr { @@ -2667,7 +2666,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(Node::Expr(hir::Expr { kind: hir::ExprKind::If(_, _, Some(else_expr)), .. - })) = self.tcx.hir().find(parent_id) + })) = self.tcx.opt_hir_node(parent_id) { return else_expr.hir_id == expr.hir_id; } @@ -3057,7 +3056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; let parent = self.tcx.hir().parent_id(expr.hir_id); - if let Some(hir::Node::ExprField(_)) = self.tcx.hir().find(parent) { + if let Some(hir::Node::ExprField(_)) = self.tcx.opt_hir_node(parent) { // Ignore `Foo { field: a..Default::default() }` return; } @@ -3136,7 +3135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir::def::Res::Local(hir_id) = path.res else { return; }; - let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else { + let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else { return; }; let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) = diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 6ad7b301014..f1f893623f6 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -127,7 +127,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } if let Some(def_id) = def_id.as_local() { - primary_body_of(tcx.hir().get_by_def_id(def_id)).is_some() + primary_body_of(tcx.hir_node_by_def_id(def_id)).is_some() } else { false } @@ -166,7 +166,7 @@ fn typeck_with_fallback<'tcx>( } let id = tcx.local_def_id_to_hir_id(def_id); - let node = tcx.hir().get(id); + let node = tcx.hir_node(id); let span = tcx.hir().span(id); // Figure out what primary body this item has. @@ -201,7 +201,7 @@ fn typeck_with_fallback<'tcx>( span, })) } else if let Node::AnonConst(_) = node { - match tcx.hir().get(tcx.hir().parent_id(id)) { + match tcx.hir_node(tcx.hir().parent_id(id)) { Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. }) if anon_const.hir_id == id => { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index e7af7da205c..b2ead3cd40b 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -415,7 +415,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { ) .into() } - _ => unreachable!(), + (kind, arg) => { + bug!("mismatched method arg kind {kind:?} in turbofish: {arg:?}") + } } } diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 3f1dca5b1de..43d258de6ca 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -122,8 +122,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("disambiguate the method call with `({self_adjusted})`",), ); } - - lint }, ); } else { @@ -187,8 +185,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); } - - lint }, ); } @@ -307,8 +303,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), Applicability::MachineApplicable, ); - - lint }, ); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 4243bce377f..fe2d43a3c92 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -445,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { scope_expr_id, span, "type annotations needed", - |lint| lint, + |_| {}, ); } } else { @@ -1427,8 +1427,6 @@ impl<'tcx> Pick<'tcx> { )); } } - - lint }, ); } @@ -1548,9 +1546,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ); let candidate_obligations = impl_obligations - .chain(norm_obligations.into_iter()) + .chain(norm_obligations) .chain(ref_obligations.iter().cloned()) - .chain(normalization_obligations.into_iter()); + .chain(normalization_obligations); // Evaluate those obligations to see if they might possibly hold. for o in candidate_obligations { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index b38a6ebd501..8fb703fa7f5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind && let hir::def::Res::Local(hir_id) = path.res - && let Some(hir::Node::Pat(b)) = self.tcx.hir().find(hir_id) + && let Some(hir::Node::Pat(b)) = self.tcx.opt_hir_node(hir_id) && let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id) && let Some(node) = self.tcx.hir().find_parent(p.hir_id) && let Some(decl) = node.fn_decl() @@ -262,7 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty); + let mut file = None; + let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file); let mut err = struct_span_err!( self.tcx.sess, rcvr_expr.span, @@ -280,6 +281,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "a writer is needed before this format string", ); }; + if let Some(file) = file { + err.note(format!("the full type name has been written to '{}'", file.display())); + } err } @@ -299,11 +303,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); - let ((mut ty_str, ty_file), short_ty_str) = + let mut ty_file = None; + let (mut ty_str, short_ty_str) = if trait_missing_method && let ty::Dynamic(predicates, _, _) = rcvr_ty.kind() { - ((predicates.to_string(), None), with_forced_trimmed_paths!(predicates.to_string())) + (predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string())) } else { - (tcx.short_ty_string(rcvr_ty), with_forced_trimmed_paths!(rcvr_ty.to_string())) + ( + tcx.short_ty_string(rcvr_ty, &mut ty_file), + with_forced_trimmed_paths!(rcvr_ty.to_string()), + ) }; let is_method = mode == Mode::MethodCall; let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; @@ -605,16 +613,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (ty::Param(_), ty::PredicateKind::Clause(ty::ClauseKind::Trait(p))) = (self_ty.kind(), parent_pred.kind().skip_binder()) { - let hir = self.tcx.hir(); let node = match p.trait_ref.self_ty().kind() { ty::Param(_) => { // Account for `fn` items like in `issue-35677.rs` to // suggest restricting its type params. - Some(hir.get_by_def_id(self.body_id)) - } - ty::Adt(def, _) => { - def.did().as_local().map(|def_id| hir.get_by_def_id(def_id)) + Some(self.tcx.hir_node_by_def_id(self.body_id)) } + ty::Adt(def, _) => def + .did() + .as_local() + .map(|def_id| self.tcx.hir_node_by_def_id(def_id)), _ => None, }; if let Some(hir::Node::Item(hir::Item { kind, .. })) = node @@ -1952,7 +1960,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { visitor.visit_body(body); let parent = self.tcx.hir().parent_id(seg1.hir_id); - if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) + if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent) && let Some(expr) = visitor.result && let Some(self_ty) = self.node_ty_opt(expr.hir_id) { @@ -2869,11 +2877,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let id = item .def_id .as_local() - .map(|def_id| self.tcx.local_def_id_to_hir_id(def_id)); + .map(|def_id| self.tcx.hir_node_by_def_id(def_id)); if let Some(hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(fn_sig, method), .. - })) = id.map(|id| self.tcx.hir().get(id)) + })) = id { let self_first_arg = match method { hir::TraitFn::Required([ident, ..]) => { @@ -2963,7 +2971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Get the `hir::Param` to verify whether it already has any bounds. // We do this to avoid suggesting code that ends up as `T: FooBar`, // instead we suggest `T: Foo + Bar` in that case. - match hir.get(id) { + match self.tcx.hir_node(id) { Node::GenericParam(param) => { enum Introducer { Plus, @@ -3183,7 +3191,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let parent = self.tcx.hir().parent_id(expr.hir_id); - if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) + if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent) && let hir::ExprKind::MethodCall( hir::PathSegment { ident: method_name, .. }, self_expr, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b63bb1e00cb..56a420fab4f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -720,7 +720,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let PatKind::Binding(_, _, binding, ..) = inner.kind { let binding_parent_id = tcx.hir().parent_id(pat.hir_id); - let binding_parent = tcx.hir().get(binding_parent_id); + let binding_parent = tcx.hir_node(binding_parent_id); debug!(?inner, ?pat, ?binding_parent); let mutability = match mutbl { @@ -941,7 +941,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(_, _, body_id), .. - })) => match self.tcx.hir().get(body_id.hir_id) { + })) => match self.tcx.hir_node(body_id.hir_id) { hir::Node::Expr(expr) => { if hir::is_range_literal(expr) { let span = self.tcx.hir().span(body_id.hir_id); @@ -1820,7 +1820,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn joined_uncovered_patterns(witnesses: &[&Ident]) -> String { const LIMIT: usize = 3; match witnesses { - [] => bug!(), + [] => { + unreachable!( + "expected an uncovered pattern, otherwise why are we emitting an error?" + ) + } [witness] => format!("`{witness}`"), [head @ .., tail] if head.len() < LIMIT => { let head: Vec<_> = head.iter().map(<_>::to_string).collect(); @@ -1845,8 +1849,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint.note(format!( "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found", )); - - lint }); } diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs index 04d84102336..b9b3ed53dae 100644 --- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs +++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs @@ -69,12 +69,13 @@ pub fn resolve_rvalue_scopes<'a, 'tcx>( def_id: DefId, ) -> RvalueScopes { let tcx = &fcx.tcx; - let hir_map = tcx.hir(); let mut rvalue_scopes = RvalueScopes::new(); debug!("start resolving rvalue scopes, def_id={def_id:?}"); debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates); for (&hir_id, candidate) in &scope_tree.rvalue_candidates { - let Some(Node::Expr(expr)) = hir_map.find(hir_id) else { bug!("hir node does not exist") }; + let Some(Node::Expr(expr)) = tcx.opt_hir_node(hir_id) else { + bug!("hir node does not exist") + }; record_rvalue_scope(&mut rvalue_scopes, expr, candidate); } rvalue_scopes diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index c0a5818b9e5..69d6fb8e2ea 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -261,7 +261,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Unify the (as yet unbound) type variable in the closure // args with the kind we inferred. let closure_kind_ty = closure_args.as_closure().kind_ty(); - self.demand_eqtype(span, closure_kind.to_ty(self.tcx), closure_kind_ty); + self.demand_eqtype( + span, + Ty::from_closure_kind(self.tcx, closure_kind), + closure_kind_ty, + ); // If we have an origin, store it. if let Some(mut origin) = origin { @@ -315,11 +319,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let final_tupled_upvars_type = Ty::new_tup(self.tcx, &final_upvar_tys); self.demand_suptype(span, args.tupled_upvars_ty(), final_tupled_upvars_type); - let fake_reads = delegate - .fake_reads - .into_iter() - .map(|(place, cause, hir_id)| (place, cause, hir_id)) - .collect(); + let fake_reads = delegate.fake_reads; + self.typeck_results.borrow_mut().closure_fake_reads.insert(closure_def_id, fake_reads); if self.tcx.sess.opts.unstable_opts.profile_closures { @@ -853,7 +854,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Looks like a macro fragment. Try to find the real block. if let Some(hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Block(block, ..), .. - })) = self.tcx.hir().find(body_id.hir_id) { + })) = self.tcx.opt_hir_node(body_id.hir_id) { // If the body is a block (with `{..}`), we use the span of that block. // E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`. // Since we know it's a block, we know we can insert the `let _ = ..` without @@ -911,8 +912,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::HasPlaceholders ); } - - lint }, ); } @@ -1673,7 +1672,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>( fn drop_location_span(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> Span { let owner_id = tcx.hir().get_enclosing_scope(hir_id).unwrap(); - let owner_node = tcx.hir().get(owner_id); + let owner_node = tcx.hir_node(owner_id); let owner_span = match owner_node { hir::Node::Item(item) => match item.kind { hir::ItemKind::Fn(_, _, owner_id) => tcx.hir().span(owner_id.hir_id), diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 1609c036fbd..5e562d9453f 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -504,8 +504,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { if !errors_buffer.is_empty() { errors_buffer.sort_by_key(|diag| diag.span.primary_span()); - for mut diag in errors_buffer { - self.tcx().sess.diagnostic().emit_diagnostic(&mut diag); + for diag in errors_buffer { + self.tcx().sess.diagnostic().emit_diagnostic(diag); } } } diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 0f2194139df..8a7b97139ea 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -232,7 +232,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { /// Return all DepNode labels that should be asserted for this item. /// index=0 is the "name" used for error messages fn auto_labels(&mut self, item_id: LocalDefId, attr: &Attribute) -> (&'static str, Labels) { - let node = self.tcx.hir().get_by_def_id(item_id); + let node = self.tcx.hir_node_by_def_id(item_id); let (name, labels) = match node { HirNode::Item(item) => { match item.kind { diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 6a220243266..a0768fc7115 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -363,9 +363,7 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> { return false; }; - let hir_id = self.tcx.local_def_id_to_hir_id(anon_reg.def_id); - - let node = self.tcx.hir().get(hir_id); + let node = self.tcx.hir_node_by_def_id(anon_reg.def_id); let is_impl = matches!(&node, hir::Node::ImplItem(_)); let generics = match node { hir::Node::Item(&hir::Item { diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 473a3965885..5b00ef42211 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -35,36 +35,13 @@ impl<'tcx> InferCtxt<'tcx> { /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#canonicalizing-the-query pub fn canonicalize_query<V>( &self, - value: V, - query_state: &mut OriginalQueryValues<'tcx>, - ) -> Canonical<'tcx, V> - where - V: TypeFoldable<TyCtxt<'tcx>>, - { - Canonicalizer::canonicalize(value, self, self.tcx, &CanonicalizeAllFreeRegions, query_state) - } - - /// Like [Self::canonicalize_query], but preserves distinct universes. For - /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and - /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1` - /// in `U2`. - /// - /// This is used for Chalk integration. - pub fn canonicalize_query_preserving_universes<V>( - &self, - value: V, + value: ty::ParamEnvAnd<'tcx, V>, query_state: &mut OriginalQueryValues<'tcx>, - ) -> Canonical<'tcx, V> + ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>> where V: TypeFoldable<TyCtxt<'tcx>>, { - Canonicalizer::canonicalize( - value, - self, - self.tcx, - &CanonicalizeAllFreeRegionsPreservingUniverses, - query_state, - ) + self.canonicalize_query_with_mode(value, query_state, &CanonicalizeAllFreeRegions) } /// Canonicalizes a query *response* `V`. When we canonicalize a @@ -99,7 +76,7 @@ impl<'tcx> InferCtxt<'tcx> { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( value, - self, + Some(self), self.tcx, &CanonicalizeQueryResponse, &mut query_state, @@ -113,7 +90,7 @@ impl<'tcx> InferCtxt<'tcx> { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( value, - self, + Some(self), self.tcx, &CanonicalizeUserTypeAnnotation, &mut query_state, @@ -126,19 +103,53 @@ impl<'tcx> InferCtxt<'tcx> { /// handling of `'static` regions (e.g. trait evaluation). pub fn canonicalize_query_keep_static<V>( &self, - value: V, + value: ty::ParamEnvAnd<'tcx, V>, query_state: &mut OriginalQueryValues<'tcx>, - ) -> Canonical<'tcx, V> + ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>> where V: TypeFoldable<TyCtxt<'tcx>>, { - Canonicalizer::canonicalize( + self.canonicalize_query_with_mode( value, - self, - self.tcx, + query_state, &CanonicalizeFreeRegionsOtherThanStatic, + ) + } + + fn canonicalize_query_with_mode<V>( + &self, + value: ty::ParamEnvAnd<'tcx, V>, + query_state: &mut OriginalQueryValues<'tcx>, + canonicalize_region_mode: &dyn CanonicalizeMode, + ) -> Canonical<'tcx, ty::ParamEnvAnd<'tcx, V>> + where + V: TypeFoldable<TyCtxt<'tcx>>, + { + let (param_env, value) = value.into_parts(); + let base = self.tcx.canonical_param_env_cache.get_or_insert( + self.tcx, + param_env, + query_state, + |tcx, param_env, query_state| { + Canonicalizer::canonicalize( + param_env, + None, + tcx, + &CanonicalizeFreeRegionsOtherThanStatic, + query_state, + ) + }, + ); + + Canonicalizer::canonicalize_with_base( + base, + value, + Some(self), + self.tcx, + canonicalize_region_mode, query_state, ) + .unchecked_map(|(param_env, value)| param_env.and(value)) } } @@ -168,8 +179,22 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { fn canonicalize_free_region<'tcx>( &self, canonicalizer: &mut Canonicalizer<'_, 'tcx>, - r: ty::Region<'tcx>, + mut r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { + let infcx = canonicalizer.infcx.unwrap(); + + if let ty::ReVar(vid) = *r { + r = infcx + .inner + .borrow_mut() + .unwrap_region_constraints() + .opportunistic_resolve_var(canonicalizer.tcx, vid); + debug!( + "canonical: region var found with vid {vid:?}, \ + opportunistically resolved to {r:?}", + ); + }; + match *r { ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r, @@ -179,7 +204,8 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { ), ty::ReVar(vid) => { - let universe = canonicalizer.region_var_universe(vid); + let universe = + infcx.inner.borrow_mut().unwrap_region_constraints().var_universe(vid); canonicalizer.canonical_var_for_region( CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) }, r, @@ -264,30 +290,6 @@ impl CanonicalizeMode for CanonicalizeAllFreeRegions { } } -struct CanonicalizeAllFreeRegionsPreservingUniverses; - -impl CanonicalizeMode for CanonicalizeAllFreeRegionsPreservingUniverses { - fn canonicalize_free_region<'tcx>( - &self, - canonicalizer: &mut Canonicalizer<'_, 'tcx>, - r: ty::Region<'tcx>, - ) -> ty::Region<'tcx> { - let universe = canonicalizer.infcx.universe_of_region(r); - canonicalizer.canonical_var_for_region( - CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) }, - r, - ) - } - - fn any(&self) -> bool { - true - } - - fn preserve_universes(&self) -> bool { - true - } -} - struct CanonicalizeFreeRegionsOtherThanStatic; impl CanonicalizeMode for CanonicalizeFreeRegionsOtherThanStatic { @@ -309,7 +311,8 @@ impl CanonicalizeMode for CanonicalizeFreeRegionsOtherThanStatic { } struct Canonicalizer<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, + /// Set to `None` to disable the resolution of inference variables. + infcx: Option<&'cx InferCtxt<'tcx>>, tcx: TyCtxt<'tcx>, variables: SmallVec<[CanonicalVarInfo<'tcx>; 8]>, query_state: &'cx mut OriginalQueryValues<'tcx>, @@ -347,25 +350,12 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { } } - ty::ReVar(vid) => { - let resolved = self - .infcx - .inner - .borrow_mut() - .unwrap_region_constraints() - .opportunistic_resolve_var(self.tcx, vid); - debug!( - "canonical: region var found with vid {vid:?}, \ - opportunistically resolved to {resolved:?}", - ); - self.canonicalize_mode.canonicalize_free_region(self, resolved) - } - ty::ReStatic | ty::ReEarlyParam(..) | ty::ReError(_) | ty::ReLateParam(_) | ty::RePlaceholder(..) + | ty::ReVar(_) | ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r), } } @@ -376,14 +366,14 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { // We need to canonicalize the *root* of our ty var. // This is so that our canonical response correctly reflects // any equated inference vars correctly! - let root_vid = self.infcx.root_var(vid); + let root_vid = self.infcx.unwrap().root_var(vid); if root_vid != vid { - t = Ty::new_var(self.infcx.tcx, root_vid); + t = Ty::new_var(self.tcx, root_vid); vid = root_vid; } debug!("canonical: type var found with vid {:?}", vid); - match self.infcx.probe_ty_var(vid) { + match self.infcx.unwrap().probe_ty_var(vid) { // `t` could be a float / int variable; canonicalize that instead. Ok(t) => { debug!("(resolved to {:?})", t); @@ -408,7 +398,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { } ty::Infer(ty::IntVar(vid)) => { - let nt = self.infcx.opportunistic_resolve_int_var(vid); + let nt = self.infcx.unwrap().opportunistic_resolve_int_var(vid); if nt != t { return self.fold_ty(nt); } else { @@ -419,7 +409,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { } } ty::Infer(ty::FloatVar(vid)) => { - let nt = self.infcx.opportunistic_resolve_float_var(vid); + let nt = self.infcx.unwrap().opportunistic_resolve_float_var(vid); if nt != t { return self.fold_ty(nt); } else { @@ -490,14 +480,14 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { // We need to canonicalize the *root* of our const var. // This is so that our canonical response correctly reflects // any equated inference vars correctly! - let root_vid = self.infcx.root_const_var(vid); + let root_vid = self.infcx.unwrap().root_const_var(vid); if root_vid != vid { - ct = ty::Const::new_var(self.infcx.tcx, root_vid, ct.ty()); + ct = ty::Const::new_var(self.tcx, root_vid, ct.ty()); vid = root_vid; } debug!("canonical: const var found with vid {:?}", vid); - match self.infcx.probe_const_var(vid) { + match self.infcx.unwrap().probe_const_var(vid) { Ok(c) => { debug!("(resolved to {:?})", c); return self.fold_const(c); @@ -518,8 +508,8 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { } } ty::ConstKind::Infer(InferConst::EffectVar(vid)) => { - match self.infcx.probe_effect_var(vid) { - Some(value) => return self.fold_const(value.as_const(self.infcx.tcx)), + match self.infcx.unwrap().probe_effect_var(vid) { + Some(value) => return self.fold_const(value.as_const(self.tcx)), None => { return self.canonicalize_const_var( CanonicalVarInfo { kind: CanonicalVarKind::Effect }, @@ -562,7 +552,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// `canonicalize_query` and `canonicalize_response`. fn canonicalize<V>( value: V, - infcx: &InferCtxt<'tcx>, + infcx: Option<&InferCtxt<'tcx>>, tcx: TyCtxt<'tcx>, canonicalize_region_mode: &dyn CanonicalizeMode, query_state: &mut OriginalQueryValues<'tcx>, @@ -570,6 +560,33 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { where V: TypeFoldable<TyCtxt<'tcx>>, { + let base = Canonical { + max_universe: ty::UniverseIndex::ROOT, + variables: List::empty(), + value: (), + }; + Canonicalizer::canonicalize_with_base( + base, + value, + infcx, + tcx, + canonicalize_region_mode, + query_state, + ) + .unchecked_map(|((), val)| val) + } + + fn canonicalize_with_base<U, V>( + base: Canonical<'tcx, U>, + value: V, + infcx: Option<&InferCtxt<'tcx>>, + tcx: TyCtxt<'tcx>, + canonicalize_region_mode: &dyn CanonicalizeMode, + query_state: &mut OriginalQueryValues<'tcx>, + ) -> Canonical<'tcx, (U, V)> + where + V: TypeFoldable<TyCtxt<'tcx>>, + { let needs_canonical_flags = if canonicalize_region_mode.any() { TypeFlags::HAS_INFER | TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_FREE_REGIONS } else { @@ -578,12 +595,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { // Fast path: nothing that needs to be canonicalized. if !value.has_type_flags(needs_canonical_flags) { - let canon_value = Canonical { - max_universe: ty::UniverseIndex::ROOT, - variables: List::empty(), - value, - }; - return canon_value; + return base.unchecked_map(|b| (b, value)); } let mut canonicalizer = Canonicalizer { @@ -591,11 +603,20 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { tcx, canonicalize_mode: canonicalize_region_mode, needs_canonical_flags, - variables: SmallVec::new(), + variables: SmallVec::from_slice(base.variables), query_state, indices: FxHashMap::default(), binder_index: ty::INNERMOST, }; + if canonicalizer.query_state.var_values.spilled() { + canonicalizer.indices = canonicalizer + .query_state + .var_values + .iter() + .enumerate() + .map(|(i, &kind)| (kind, BoundVar::new(i))) + .collect(); + } let out_value = value.fold_with(&mut canonicalizer); // Once we have canonicalized `out_value`, it should not @@ -612,7 +633,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { .max() .unwrap_or(ty::UniverseIndex::ROOT); - Canonical { max_universe, variables: canonical_variables, value: out_value } + Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) } } /// Creates a canonical variable replacing `kind` from the input, @@ -761,11 +782,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { ) } - /// Returns the universe in which `vid` is defined. - fn region_var_universe(&self, vid: ty::RegionVid) -> ty::UniverseIndex { - self.infcx.inner.borrow_mut().unwrap_region_constraints().var_universe(vid) - } - /// Creates a canonical variable (with the given `info`) /// representing the region `r`; return a region referencing it. fn canonical_var_for_region( @@ -783,14 +799,9 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// *that*. Otherwise, create a new canonical variable for /// `ty_var`. fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> { - let infcx = self.infcx; - let bound_to = infcx.shallow_resolve(ty_var); - if bound_to != ty_var { - self.fold_ty(bound_to) - } else { - let var = self.canonical_var(info, ty_var.into()); - Ty::new_bound(self.tcx, self.binder_index, var.into()) - } + debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var))); + let var = self.canonical_var(info, ty_var.into()); + Ty::new_bound(self.tcx, self.binder_index, var.into()) } /// Given a type variable `const_var` of the given kind, first check @@ -802,13 +813,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { info: CanonicalVarInfo<'tcx>, const_var: ty::Const<'tcx>, ) -> ty::Const<'tcx> { - let infcx = self.infcx; - let bound_to = infcx.shallow_resolve(const_var); - if bound_to != const_var { - self.fold_const(bound_to) - } else { - let var = self.canonical_var(info, const_var.into()); - ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty())) - } + debug_assert!( + !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve(const_var)) + ); + let var = self.canonical_var(info, const_var.into()); + ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty())) } } diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 3c4c4644fe6..386fdb09ba5 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -101,7 +101,7 @@ impl<'tcx> InferCtxt<'tcx> { /// variable, then you'll get a new inference variable; if it is a /// universally quantified variable, you get a placeholder. /// - /// FIXME(-Ztrait-solver=next): This is public because it's used by the + /// FIXME(-Znext-solver): This is public because it's used by the /// new trait solver which has a different canonicalization routine. /// We should somehow deduplicate all of this. pub fn instantiate_canonical_var( diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index f368b30fbd1..e0b97bb160c 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable}; use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{self, TyCtxt}; -/// FIXME(-Ztrait-solver=next): This or public because it is shared with the +/// FIXME(-Znext-solver): This or public because it is shared with the /// new trait solver implementation. We should deduplicate canonicalization. pub trait CanonicalExt<'tcx, V> { /// Instantiate the wrapped value, replacing each canonical value diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 745c3d195ad..c118c405c20 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -891,7 +891,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } // don't suggest wrapping either blocks in `if .. {} else {}` let is_empty_arm = |id| { - let hir::Node::Block(blk) = self.tcx.hir().get(id) else { + let hir::Node::Block(blk) = self.tcx.hir_node(id) else { return false; }; if blk.expr.is_some() || !blk.stmts.is_empty() { @@ -1743,7 +1743,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - if let Some((expected, found, exp_p, found_p)) = expected_found { + if let Some((expected, found, path)) = expected_found { let (expected_label, found_label, exp_found) = match exp_found { Mismatch::Variable(ef) => ( ef.expected.prefix_string(self.tcx), @@ -1869,40 +1869,31 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } TypeError::Sorts(values) => { let extra = expected == found; - let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| { - let mut s = match (extra, ty.kind()) { - (true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => { - let sm = self.tcx.sess.source_map(); - let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); - format!( - " (opaque type at <{}:{}:{}>)", - sm.filename_for_diagnostics(&pos.file.name), - pos.line, - pos.col.to_usize() + 1, - ) - } - (true, ty::Alias(ty::Projection, proj)) - if self.tcx.is_impl_trait_in_trait(proj.def_id) => - { - let sm = self.tcx.sess.source_map(); - let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo()); - format!( - " (trait associated opaque type at <{}:{}:{}>)", - sm.filename_for_diagnostics(&pos.file.name), - pos.line, - pos.col.to_usize() + 1, - ) - } - (true, _) => format!(" ({})", ty.sort_string(self.tcx)), - (false, _) => "".to_string(), - }; - if let Some(path) = path { - s.push_str(&format!( - "\nthe full type name has been written to '{}'", - path.display(), - )); + let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) { + (true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => { + let sm = self.tcx.sess.source_map(); + let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); + format!( + " (opaque type at <{}:{}:{}>)", + sm.filename_for_diagnostics(&pos.file.name), + pos.line, + pos.col.to_usize() + 1, + ) } - s + (true, ty::Alias(ty::Projection, proj)) + if self.tcx.is_impl_trait_in_trait(proj.def_id) => + { + let sm = self.tcx.sess.source_map(); + let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo()); + format!( + " (trait associated opaque type at <{}:{}:{}>)", + sm.filename_for_diagnostics(&pos.file.name), + pos.line, + pos.col.to_usize() + 1, + ) + } + (true, _) => format!(" ({})", ty.sort_string(self.tcx)), + (false, _) => "".to_string(), }; if !(values.expected.is_simple_text(self.tcx) && values.found.is_simple_text(self.tcx)) @@ -1933,9 +1924,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { expected, &found_label, found, - &sort_string(values.expected, exp_p), - &sort_string(values.found, found_p), + &sort_string(values.expected), + &sort_string(values.found), ); + if let Some(path) = path { + diag.note(format!( + "the full type name has been written to '{}'", + path.display(), + )); + } } } } @@ -2007,7 +2004,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.span_note(span, "this closure does not fulfill the lifetime requirements"); self.suggest_for_all_lifetime_closure( span, - self.tcx.hir().get_by_def_id(def_id), + self.tcx.hir_node_by_def_id(def_id), &exp_found, diag, ); @@ -2101,7 +2098,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. }) | BlockTailExpression(.., source)) = code && let hir::MatchSource::TryDesugar(_) = source - && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values) + && let Some((expected_ty, found_ty, _)) = self.values_str(trace.values) { suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert { found: found_ty.content(), @@ -2121,7 +2118,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let TypeError::FixedArraySize(sz) = terr else { return None; }; - let tykind = match hir.find_by_def_id(trace.cause.body_id) { + let tykind = match self.tcx.opt_hir_node_by_def_id(trace.cause.body_id) { Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => { let body = hir.body(*body_id); struct LetVisitor<'v> { @@ -2219,8 +2216,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn values_str( &self, values: ValuePairs<'tcx>, - ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)> - { + ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> { match values { infer::Regions(exp_found) => self.expected_found_str(exp_found), infer::Terms(exp_found) => self.expected_found_str_term(exp_found), @@ -2233,7 +2229,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { found: exp_found.found.print_trait_sugared(), }; match self.expected_found_str(pretty_exp_found) { - Some((expected, found, _, _)) if expected == found => { + Some((expected, found, _)) if expected == found => { self.expected_found_str(exp_found) } ret => ret, @@ -2245,7 +2241,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return None; } let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found); - Some((exp, fnd, None, None)) + Some((exp, fnd, None)) } } } @@ -2253,8 +2249,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn expected_found_str_term( &self, exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>, - ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)> - { + ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { return None; @@ -2269,25 +2264,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let len = self.tcx.sess().diagnostic_width() + 40; let exp_s = exp.content(); let fnd_s = fnd.content(); - let mut exp_p = None; - let mut fnd_p = None; + let mut path = None; if exp_s.len() > len { - let (exp_s, exp_path) = self.tcx.short_ty_string(expected); + let exp_s = self.tcx.short_ty_string(expected, &mut path); exp = DiagnosticStyledString::highlighted(exp_s); - exp_p = exp_path; } if fnd_s.len() > len { - let (fnd_s, fnd_path) = self.tcx.short_ty_string(found); + let fnd_s = self.tcx.short_ty_string(found, &mut path); fnd = DiagnosticStyledString::highlighted(fnd_s); - fnd_p = fnd_path; } - (exp, fnd, exp_p, fnd_p) + (exp, fnd, path) } _ => ( DiagnosticStyledString::highlighted(exp_found.expected.to_string()), DiagnosticStyledString::highlighted(exp_found.found.to_string()), None, - None, ), }) } @@ -2296,8 +2287,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>( &self, exp_found: ty::error::ExpectedFound<T>, - ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)> - { + ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>)> { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { return None; @@ -2307,7 +2297,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { DiagnosticStyledString::highlighted(exp_found.expected.to_string()), DiagnosticStyledString::highlighted(exp_found.found.to_string()), None, - None, )) } @@ -2452,7 +2441,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if !suggs.is_empty() { err.multipart_suggestion_verbose( - format!("{msg}"), + msg, suggs, Applicability::MaybeIncorrect, // Issue #41966 ); @@ -2591,8 +2580,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let infer::Subtype(ref sup_trace) = sup_origin && let infer::Subtype(ref sub_trace) = sub_origin - && let Some((sup_expected, sup_found, _, _)) = self.values_str(sup_trace.values) - && let Some((sub_expected, sub_found, _, _)) = self.values_str(sub_trace.values) + && let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values) + && let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values) && sub_expected == sup_expected && sub_found == sup_found { @@ -2997,7 +2986,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Given a [`hir::HirId`] for a block, get the span of its last expression /// or statement, peeling off any inner blocks. pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span { - match self.tcx.hir().get(hir_id) { + match self.tcx.hir_node(hir_id) { hir::Node::Block(blk) => self.find_block_span(blk), // The parser was in a weird state if either of these happen, but // it's better not to panic. 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 8fe6c1b0d86..1caa9aa8cd6 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 @@ -232,7 +232,9 @@ fn ty_to_string<'tcx>( /// something users are familiar with. Directly printing the `fn_sig` of closures also /// doesn't work as they actually use the "rust-call" API. fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String { - let ty::Closure(_, args) = ty.kind() else { unreachable!() }; + let ty::Closure(_, args) = ty.kind() else { + bug!("cannot convert non-closure to fn str in `closure_as_fn_str`") + }; let fn_sig = args.as_closure().sig(); let args = fn_sig .inputs() diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index ab928232d74..4f74365d06c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -26,8 +26,7 @@ pub fn find_anon_type<'tcx>( br: &ty::BoundRegionKind, ) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> { let anon_reg = tcx.is_suitable_region(region)?; - let hir_id = tcx.local_def_id_to_hir_id(anon_reg.def_id); - let fn_sig = tcx.hir().get(hir_id).fn_sig()?; + let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?; fn_sig .decl diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 81154415c1e..01b43f7197d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -460,7 +460,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { if let Node::Item(Item { kind: ItemKind::Impl(hir::Impl { self_ty, .. }), .. - }) = tcx.hir().find_by_def_id(impl_did)? + }) = tcx.opt_hir_node_by_def_id(impl_did)? && trait_objects.iter().all(|did| { // FIXME: we should check `self_ty` against the receiver // type in the `UnifyReceiver` context, but for now, use diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 155c0356025..bfff00b948e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -50,11 +50,10 @@ pub fn find_param_with_region<'tcx>( let hir = &tcx.hir(); let def_id = id.as_local()?; - let hir_id = tcx.local_def_id_to_hir_id(def_id); // FIXME: use def_kind // Don't perform this on closures - match hir.get(hir_id) { + match tcx.hir_node_by_def_id(def_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { return None; } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index fed76cd65cf..1e365848e07 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -22,7 +22,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { span: trace.cause.span, requirement: ObligationCauseAsDiagArg(trace.cause.clone()), - expected_found: self.values_str(trace.values).map(|(e, f, _, _)| (e, f)), + expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)), } .add_to_diagnostic(err), infer::Reborrow(span) => { @@ -375,7 +375,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.span_note(span, "the lifetime requirement is introduced here"); err } else { - unreachable!() + unreachable!( + "control flow ensures we have a `BindingObligation` or `ExprBindingObligation` here..." + ) } } infer::Subtype(box trace) => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index b93fe02aaea..afb3c5c1e56 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -655,7 +655,7 @@ fn foo(&self) -> Self::T { String::new() } // When `body_owner` is an `impl` or `trait` item, look in its associated types for // `expected` and point at it. let parent_id = tcx.hir().get_parent_item(hir_id); - let item = tcx.hir().find_by_def_id(parent_id.def_id); + let item = tcx.opt_hir_node_by_def_id(parent_id.def_id); debug!("expected_projection parent item {:?}", item); diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index aa5fe6d3f56..bbe07b8ed72 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -42,7 +42,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ] .into_iter() .find_map(|(id, ty)| { - let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None }; + let hir::Node::Block(blk) = self.tcx.hir_node(id?) else { return None }; self.could_remove_semicolon(blk, ty) }); match remove_semicolon { @@ -62,7 +62,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut ret = None; for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] { if let Some(id) = id - && let hir::Node::Block(blk) = self.tcx.hir().get(id) + && let hir::Node::Block(blk) = self.tcx.hir_node(id) && let Some(diag) = self.consider_returning_binding_diag(blk, ty) { ret = Some(diag); @@ -668,26 +668,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ( hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }), hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }), - ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| { - match (left, right) { - ( - hir::GenericBound::Trait(tl, ml), - hir::GenericBound::Trait(tr, mr), - ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() + ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match ( + left, right, + ) { + (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr)) + if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() && ml == mr => - { - true - } - ( - hir::GenericBound::LangItemTrait(langl, _, _, argsl), - hir::GenericBound::LangItemTrait(langr, _, _, argsr), - ) if langl == langr => { - // FIXME: consider the bounds! - debug!("{:?} {:?}", argsl, argsr); - true - } - _ => false, + { + true } + _ => false, }) => { StatementAsExpression::NeedsBoxing diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 18231af2bed..3de269da22d 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -5,7 +5,7 @@ pub use self::BoundRegionConversionTime::*; pub use self::RegionVariableOrigin::*; pub use self::SubregionOrigin::*; pub use self::ValuePairs::*; -pub use combine::ObligationEmittingRelation; +pub use relate::combine::ObligationEmittingRelation; use rustc_data_structures::captures::Captures; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey}; @@ -43,7 +43,6 @@ use rustc_span::{Span, DUMMY_SP}; use std::cell::{Cell, RefCell}; use std::fmt; -use self::combine::CombineFields; use self::error_reporting::TypeErrCtxt; use self::free_regions::RegionRelations; use self::lexical_region_resolve::LexicalRegionResolutions; @@ -51,29 +50,23 @@ use self::region_constraints::{GenericKind, VarInfos, VerifyBound}; use self::region_constraints::{ RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot, }; +pub use self::relate::combine::CombineFields; +pub use self::relate::nll as nll_relate; use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; pub mod at; pub mod canonical; -mod combine; -mod equate; pub mod error_reporting; pub mod free_regions; mod freshen; mod fudge; -mod generalize; -mod glb; -mod higher_ranked; -pub mod lattice; mod lexical_region_resolve; -mod lub; -pub mod nll_relate; pub mod opaque_types; pub mod outlives; mod projection; pub mod region_constraints; +mod relate; pub mod resolve; -mod sub; pub mod type_variable; mod undo_log; @@ -381,17 +374,13 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> { self.probe_ty_var(vid).ok() } - fn root_lt_var(&self, vid: ty::RegionVid) -> ty::RegionVid { - self.root_region_var(vid) - } - - fn probe_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> { + fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> { let re = self .inner .borrow_mut() .unwrap_region_constraints() .opportunistic_resolve_var(self.tcx, vid); - if re.is_var() { None } else { Some(re) } + if *re == ty::ReVar(vid) { None } else { Some(re) } } fn root_ct_var(&self, vid: ConstVid) -> ConstVid { @@ -1367,10 +1356,6 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().type_variables().root_var(var) } - pub fn root_region_var(&self, var: ty::RegionVid) -> ty::RegionVid { - self.inner.borrow_mut().unwrap_region_constraints().root_var(var) - } - pub fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid { self.inner.borrow_mut().const_unification_table().find(var).vid } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 82ab1955053..a492c6bf9bb 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -683,8 +683,8 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi let res = hir_id == scope; trace!( "may_define_opaque_type(def={:?}, opaque_node={:?}) = {}", - tcx.hir().find(hir_id), - tcx.hir().get(opaque_hir_id), + tcx.opt_hir_node(hir_id), + tcx.hir_node(opaque_hir_id), res ); res diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index 45df22d44e8..47038cfd468 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -203,7 +203,9 @@ pub(super) fn compute_alias_components_recursive<'tcx>( out: &mut SmallVec<[Component<'tcx>; 4]>, visited: &mut SsoHashSet<GenericArg<'tcx>>, ) { - let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() }; + let ty::Alias(kind, alias_ty) = alias_ty.kind() else { + unreachable!("can only call `compute_alias_components_recursive` on an alias type") + }; let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] }; for (index, child) in alias_ty.args.iter().enumerate() { if opt_variances.get(index) == Some(&ty::Bivariant) { diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index ce619ae8a0d..bb578a482e4 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -130,12 +130,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // see the extensive comment in projection_must_outlive let recursive_bound = { let mut components = smallvec![]; - compute_alias_components_recursive( - self.tcx, - alias_ty_as_ty.into(), - &mut components, - visited, - ); + compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components, visited); self.bound_from_components(&components, visited) }; diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 5c043b1d3dd..cbd8040c9f1 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -623,11 +623,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } } - pub fn root_var(&mut self, vid: ty::RegionVid) -> ty::RegionVid { - let mut ut = self.unification_table_mut(); // FIXME(rust-lang/ena#42): unnecessary mut - ut.find(vid).vid - } - fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> { match t { Glb => &mut self.glbs, diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index bab21bc237a..dfaca3458d6 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -3,7 +3,7 @@ //! combining two instances of various things and yielding a new instance. //! These combiner methods always yield a `Result<T>`. To relate two //! types, you can use `infcx.at(cause, param_env)` which then allows -//! you to use the relevant methods of [At](super::at::At). +//! you to use the relevant methods of [At](crate::infer::at::At). //! //! Combiners mostly do their specific behavior and then hand off the //! bulk of the work to [InferCtxt::super_combine_tys] and @@ -23,11 +23,11 @@ //! this should be correctly updated. use super::equate::Equate; +use super::generalize::{self, CombineDelegate, Generalization}; use super::glb::Glb; use super::lub::Lub; use super::sub::Sub; -use super::{DefineOpaqueTypes, InferCtxt, TypeTrace}; -use crate::infer::generalize::{self, CombineDelegate, Generalization}; +use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue}; @@ -103,15 +103,19 @@ impl<'tcx> InferCtxt<'tcx> { } // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm. - ( - ty::Alias(..), - ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), - ) - | ( - ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), - ty::Alias(..), - ) if self.next_trait_solver() => { - bug!() + (ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..)) + if self.next_trait_solver() => + { + bug!( + "We do not expect to encounter `TyVar` this late in combine \ + -- they should have been handled earlier" + ) + } + (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))) + | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _) + if self.next_trait_solver() => + { + bug!("We do not expect to encounter `Fresh` variables in the new solver") } (_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => { @@ -172,7 +176,7 @@ impl<'tcx> InferCtxt<'tcx> { // two const param's types are able to be equal has to go through a canonical query with the actual logic // in `rustc_trait_selection`. let canonical = self.canonicalize_query( - (relation.param_env(), a.ty(), b.ty()), + relation.param_env().and((a.ty(), b.ty())), &mut OriginalQueryValues::default(), ); self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { @@ -548,7 +552,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { } pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { - self.obligations.extend(obligations.into_iter()); + self.obligations.extend(obligations); } pub fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>) { diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/relate/equate.rs index 5d929394eb0..9943c638a91 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/relate/equate.rs @@ -1,8 +1,6 @@ -use crate::infer::DefineOpaqueTypes; -use crate::traits::PredicateObligations; - use super::combine::{CombineFields, ObligationEmittingRelation}; -use super::Subtype; +use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; +use crate::traits::PredicateObligations; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::GenericArgsRef; @@ -133,7 +131,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { b: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?})", self.tag(), a, b); - let origin = Subtype(Box::new(self.fields.trace.clone())); + let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); self.fields .infcx .inner diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 383f3bdbe23..66f7b08ee12 100644 --- a/compiler/rustc_infer/src/infer/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -16,7 +16,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin}; /// Attempts to generalize `term` for the type variable `for_vid`. /// This checks for cycles -- that is, whether the type `term` /// references `for_vid`. -pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>( +pub fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>( infcx: &InferCtxt<'tcx>, delegate: &mut D, term: T, @@ -54,7 +54,7 @@ pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> /// Abstracts the handling of region vars between HIR and MIR/NLL typechecking /// in the generalizer code. -pub(super) trait GeneralizerDelegate<'tcx> { +pub trait GeneralizerDelegate<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx>; fn forbid_inference_vars() -> bool; @@ -64,7 +64,7 @@ pub(super) trait GeneralizerDelegate<'tcx> { fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>; } -pub(super) struct CombineDelegate<'cx, 'tcx> { +pub struct CombineDelegate<'cx, 'tcx> { pub infcx: &'cx InferCtxt<'tcx>, pub param_env: ty::ParamEnv<'tcx>, pub span: Span, @@ -515,7 +515,7 @@ where /// not only the generalized type, but also a bool flag /// indicating whether further WF checks are needed. #[derive(Debug)] -pub(super) struct Generalization<T> { +pub struct Generalization<T> { /// When generalizing `<?0 as Trait>::Assoc` or /// `<T as Bar<<?0 as Foo>::Assoc>>::Assoc` /// for `?0` generalization returns an inference @@ -524,7 +524,7 @@ pub(super) struct Generalization<T> { /// This has to be handled wotj care as it can /// otherwise very easily result in infinite /// recursion. - pub(super) value_may_be_infer: T, + pub value_may_be_infer: T, /// If true, then the generalized type may not be well-formed, /// even if the source type is well-formed, so we should add an @@ -551,5 +551,5 @@ pub(super) struct Generalization<T> { /// will force the calling code to check that `WF(Foo<?C, ?D>)` /// holds, which in turn implies that `?C::Item == ?D`. So once /// `?C` is constrained, that should suffice to restrict `?D`. - pub(super) needs_wf: bool, + pub needs_wf: bool, } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index 2f659d9a665..6a3413879c4 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -1,13 +1,12 @@ //! Greatest lower bound. See [`lattice`]. +use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; + use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; -use super::Subtype; -use super::{DefineOpaqueTypes, InferCtxt}; - +use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; use crate::traits::{ObligationCause, PredicateObligations}; -use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx, 'tcx> { @@ -68,7 +67,7 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { ) -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?})", self.tag(), a, b); - let origin = Subtype(Box::new(self.fields.trace.clone())); + let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); // GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8 Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions( self.tcx(), diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs index 510b1797d3c..440df8c8936 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs @@ -2,8 +2,8 @@ //! the end of the file for details. use super::combine::CombineFields; -use super::{HigherRankedType, InferCtxt}; use crate::infer::CombinedSnapshot; +use crate::infer::{HigherRankedType, InferCtxt}; use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable}; diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 9ef35429fe3..744e2dfa380 100644 --- a/compiler/rustc_infer/src/infer/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -18,10 +18,10 @@ //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) use super::combine::ObligationEmittingRelation; -use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use super::{DefineOpaqueTypes, InferCtxt}; - +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; + use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty}; diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index e41ec7e6c01..41cd98ed0cf 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -2,10 +2,9 @@ use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; -use super::Subtype; -use super::{DefineOpaqueTypes, InferCtxt}; - +use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; use crate::traits::{ObligationCause, PredicateObligations}; + use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; @@ -68,7 +67,7 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { ) -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?})", self.tag(), a, b); - let origin = Subtype(Box::new(self.fields.trace.clone())); + let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); // LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8 Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions( self.tcx(), diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs new file mode 100644 index 00000000000..f688c2b74a6 --- /dev/null +++ b/compiler/rustc_infer/src/infer/relate/mod.rs @@ -0,0 +1,12 @@ +//! This module contains the definitions of most `TypeRelation`s in the type system +//! (except for some relations used for diagnostics and heuristics in the compiler). + +pub(super) mod combine; +mod equate; +pub(super) mod generalize; +mod glb; +mod higher_ranked; +mod lattice; +mod lub; +pub mod nll; +mod sub; diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/relate/nll.rs index d707c30206d..afc2a8b2f62 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/relate/nll.rs @@ -30,8 +30,8 @@ use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; use rustc_span::{Span, Symbol}; use std::fmt::Debug; -use crate::infer::combine::ObligationEmittingRelation; -use crate::infer::generalize::{self, Generalization}; +use super::combine::ObligationEmittingRelation; +use super::generalize::{self, Generalization}; use crate::infer::InferCtxt; use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::traits::{Obligation, PredicateObligations}; @@ -247,7 +247,9 @@ where let (a, b) = match (a.kind(), b.kind()) { (&ty::Alias(ty::Opaque, ..), _) => (a, generalize(b, false)?), (_, &ty::Alias(ty::Opaque, ..)) => (generalize(a, true)?, b), - _ => unreachable!(), + _ => unreachable!( + "expected at least one opaque type in `relate_opaques`, got {a} and {b}." + ), }; let cause = ObligationCause::dummy_with_span(self.delegate.span()); let obligations = self @@ -707,7 +709,9 @@ where ), // FIXME(deferred_projection_equality): Implement this when we trigger it. // Probably just need to do nothing here. - ty::Variance::Bivariant => unreachable!(), + ty::Variance::Bivariant => { + unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)") + } })]); } } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/relate/sub.rs index 0c3bb633b53..5a623e48c93 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/relate/sub.rs @@ -1,7 +1,7 @@ use super::combine::CombineFields; -use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin}; - +use crate::infer::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin}; use crate::traits::{Obligation, PredicateObligations}; + use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::TyVar; diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index a26e676c521..b9be178916c 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -135,7 +135,7 @@ pub enum FulfillmentErrorCode<'tcx> { CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate CodeConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>), CodeAmbiguity { - /// Overflow reported from the new solver `-Ztrait-solver=next`, which will + /// Overflow reported from the new solver `-Znext-solver`, which will /// be reported as an regular error as opposed to a fatal error. overflow: bool, }, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index ce58b2ab061..d96b1ba88f5 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -6,10 +6,9 @@ use rustc_session::config::{ build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, - LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, OomStrategy, Options, - OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius, - ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, - WasiExecModel, + LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, NextSolverConfig, + OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius, + ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -748,6 +747,7 @@ fn test_unstable_options_tracking_hash() { tracked!(cross_crate_inline_threshold, InliningThreshold::Always); tracked!(debug_info_for_profiling, true); tracked!(debug_macros, true); + tracked!(default_hidden_visibility, Some(true)); tracked!(dep_info_omit_d_target, true); tracked!(dual_proc_macros, true); tracked!(dwarf_version, Some(5)); @@ -780,6 +780,10 @@ fn test_unstable_options_tracking_hash() { tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); + tracked!( + next_solver, + Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() }) + ); tracked!(no_generate_arange_section, true); tracked!(no_jump_tables, true); tracked!(no_link, true); @@ -821,7 +825,6 @@ fn test_unstable_options_tracking_hash() { tracked!(thir_unsafeck, true); tracked!(tiny_const_eval_limit, true); tracked!(tls_model, Some(TlsModel::GeneralDynamic)); - tracked!(trait_solver, TraitSolver::NextCoherence); tracked!(translate_remapped_path_to_local_path, false); tracked!(trap_unreachable, Some(false)); tracked!(treat_err_as_bug, NonZeroUsize::new(1)); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 32eb67ba3a1..045ff38c056 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2800,7 +2800,7 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { NAMED_ASM_LABELS, Some(target_spans), fluent::lint_builtin_asm_labels, - |lint| lint, + |_| {}, BuiltinLintDiagnostics::NamedAsmLabel( "only local labels of the form `<number>:` should be used in inline asm" .to_string(), diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 024e542d4af..c7a9d5e80ac 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -520,9 +520,6 @@ pub trait LintContext { /// Emit a lint at the appropriate level, with an optional associated span and an existing /// diagnostic. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed - /// explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn lookup_with_diagnostics( @@ -530,9 +527,7 @@ pub trait LintContext { lint: &'static Lint, span: Option<impl Into<MultiSpan>>, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), diagnostic: BuiltinLintDiagnostics, ) { // We first generate a blank diagnostic. @@ -706,9 +701,13 @@ pub trait LintContext { }, BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => { let possibilities: Vec<Symbol> = sess.parse_sess.check_config.expecteds.keys().copied().collect(); + let is_from_cargo = std::env::var_os("CARGO").is_some(); + let mut is_feature_cfg = name == sym::feature; + if is_feature_cfg && is_from_cargo { + db.help("consider defining some features in `Cargo.toml`"); // Suggest the most probable if we found one - if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) { + } else if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) { if let Some(ExpectedValues::Some(best_match_values)) = sess.parse_sess.check_config.expecteds.get(&best_match) { let mut possibilities = best_match_values.iter() @@ -741,8 +740,8 @@ pub trait LintContext { } else { db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect); } - } else if name == sym::feature && std::env::var_os("CARGO").is_some() { - db.help("consider defining some features in `Cargo.toml`"); + + is_feature_cfg |= best_match == sym::feature; } else if !possibilities.is_empty() { let mut possibilities = possibilities.iter() .map(Symbol::as_str) @@ -756,6 +755,23 @@ pub trait LintContext { // once. db.help_once(format!("expected names are: `{possibilities}`")); } + + let inst = if let Some((value, _value_span)) = value { + let pre = if is_from_cargo { "\\" } else { "" }; + format!("cfg({name}, values({pre}\"{value}{pre}\"))") + } else { + format!("cfg({name})") + }; + + if is_from_cargo { + if !is_feature_cfg { + db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`")); + } + db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration"); + } else { + db.help(format!("to expect this configuration use `--check-cfg={inst}`")); + db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration"); + } }, BuiltinLintDiagnostics::UnexpectedCfgValue((name, name_span), value) => { let Some(ExpectedValues::Some(values)) = &sess.parse_sess.check_config.expecteds.get(&name) else { @@ -767,6 +783,7 @@ pub trait LintContext { .copied() .flatten() .collect(); + let is_from_cargo = std::env::var_os("CARGO").is_some(); // Show the full list if all possible values for a given name, but don't do it // for names as the possibilities could be very long @@ -787,6 +804,8 @@ pub trait LintContext { db.span_suggestion(value_span, "there is a expected value with a similar name", format!("\"{best_match}\""), Applicability::MaybeIncorrect); } + } else if name == sym::feature && is_from_cargo { + db.help(format!("consider defining `{name}` as feature in `Cargo.toml`")); } else if let &[first_possibility] = &possibilities[..] { db.span_suggestion(name_span.shrink_to_hi(), "specify a config value", format!(" = \"{first_possibility}\""), Applicability::MaybeIncorrect); } @@ -796,6 +815,27 @@ pub trait LintContext { db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect); } } + + let inst = if let Some((value, _value_span)) = value { + let pre = if is_from_cargo { "\\" } else { "" }; + format!("cfg({name}, values({pre}\"{value}{pre}\"))") + } else { + format!("cfg({name})") + }; + + if is_from_cargo { + if name == sym::feature { + if let Some((value, _value_span)) = value { + db.help(format!("consider adding `{value}` as a feature in `Cargo.toml`")); + } + } else { + db.help(format!("consider using a Cargo feature instead or adding `println!(\"cargo:rustc-check-cfg={inst}\");` to the top of a `build.rs`")); + } + db.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration"); + } else { + db.help(format!("to expect this configuration use `--check-cfg={inst}`")); + db.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration"); + } }, BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(new_span, suggestion) => { db.multipart_suggestion( @@ -941,8 +981,6 @@ pub trait LintContext { // set the span in their `decorate` function (preferably using set_span). /// Emit a lint at the appropriate level, with an optional associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn lookup<S: Into<MultiSpan>>( @@ -950,9 +988,7 @@ pub trait LintContext { lint: &'static Lint, span: Option<S>, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ); /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, @@ -963,13 +999,13 @@ pub trait LintContext { span: S, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.lookup(lint, Some(span), decorator.msg(), |diag| decorator.decorate_lint(diag)); + self.lookup(lint, Some(span), decorator.msg(), |diag| { + decorator.decorate_lint(diag); + }); } /// Emit a lint at the appropriate level, with an associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn struct_span_lint<S: Into<MultiSpan>>( @@ -977,9 +1013,7 @@ pub trait LintContext { lint: &'static Lint, span: S, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { self.lookup(lint, Some(span), msg, decorate); } @@ -988,23 +1022,19 @@ pub trait LintContext { /// generated by `#[derive(LintDiagnostic)]`). fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) { self.lookup(lint, None as Option<Span>, decorator.msg(), |diag| { - decorator.decorate_lint(diag) + decorator.decorate_lint(diag); }); } /// Emit a lint at the appropriate level, with no associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] fn lint( &self, lint: &'static Lint, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { self.lookup(lint, None as Option<Span>, msg, decorate); } @@ -1068,9 +1098,7 @@ impl<'tcx> LintContext for LateContext<'tcx> { lint: &'static Lint, span: Option<S>, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let hir_id = self.last_node_with_lint_attrs; @@ -1097,9 +1125,7 @@ impl LintContext for EarlyContext<'_> { lint: &'static Lint, span: Option<S>, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate) } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 4c7f9eeff8c..b9add9e9f06 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -45,13 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { fn inlined_check_id(&mut self, id: ast::NodeId) { for early_lint in self.context.buffered.take(id) { let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint; - self.context.lookup_with_diagnostics( - lint_id.lint, - Some(span), - msg, - |lint| lint, - diagnostic, - ); + self.context.lookup_with_diagnostics(lint_id.lint, Some(span), msg, |_| {}, diagnostic); } } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 823ede1222c..53d99c7f7f3 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -34,7 +34,7 @@ declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]); impl LateLintPass<'_> for DefaultHashTypes { fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) { let Res::Def(rustc_hir::def::DefKind::Struct, def_id) = path.res else { return }; - if matches!(cx.tcx.hir().get(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) { + if matches!(cx.tcx.hir_node(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) { // don't lint imports, only actual usages return; } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index c1d4ed37627..8c8ff3fc650 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1077,7 +1077,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { GateIssue::Language, lint_from_cli, ); - lint }, ); return false; @@ -1094,8 +1093,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// Used to emit a lint-related diagnostic based on the current state of /// this lint context. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] #[track_caller] @@ -1104,9 +1101,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { lint: &'static Lint, span: Option<MultiSpan>, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, span, msg, decorate) @@ -1121,7 +1116,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { ) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| { - decorate.decorate_lint(lint) + decorate.decorate_lint(lint); }); } @@ -1129,7 +1124,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> DecorateLint<'a, ()>) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| { - decorate.decorate_lint(lint) + decorate.decorate_lint(lint); }); } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 83414ee702f..a4ab5527e3f 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -509,6 +509,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see PR #104616 \ <https://github.com/rust-lang/rust/pull/104616> for more information", ); + store.register_removed( + "implied_bounds_entailment", + "converted into hard error, see PR #117984 \ + <https://github.com/rust-lang/rust/pull/117984> for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index d0b895f7354..ca6408bdf3d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -134,12 +134,8 @@ pub struct BuiltinMissingDebugImpl<'a> { // Needed for def_path_str impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.set_arg("debug", self.tcx.def_path_str(self.def_id)); - diag } fn msg(&self) -> DiagnosticMessage { @@ -243,17 +239,13 @@ pub struct BuiltinUngatedAsyncFnTrackCaller<'a> { } impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.span_label(self.label, fluent::lint_label); rustc_session::parse::add_feature_diagnostics( diag, self.parse_sess, sym::async_fn_track_caller, ); - diag } fn msg(&self) -> DiagnosticMessage { @@ -433,10 +425,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> { } impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.set_arg("ty", self.ty); diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { @@ -447,7 +436,6 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> { ); } self.sub.add_to_diagnostic(diag); - diag } fn msg(&self) -> rustc_errors::DiagnosticMessage { @@ -1159,10 +1147,7 @@ pub struct NonFmtPanicUnused { // Used because of two suggestions based on one Option<Span> impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.set_arg("count", self.count); diag.note(fluent::lint_note); if let Some(span) = self.suggestion { @@ -1179,7 +1164,6 @@ impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused { Applicability::MachineApplicable, ); } - diag } fn msg(&self) -> rustc_errors::DiagnosticMessage { @@ -1358,12 +1342,9 @@ pub struct DropTraitConstraintsDiag<'a> { // Needed for def_path_str impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.set_arg("predicate", self.predicate); - diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id)) + diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id)); } fn msg(&self) -> rustc_errors::DiagnosticMessage { @@ -1378,11 +1359,8 @@ pub struct DropGlue<'a> { // Needed for def_path_str impl<'a> DecorateLint<'a, ()> for DropGlue<'_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { - diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id)) + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { + diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id)); } fn msg(&self) -> rustc_errors::DiagnosticMessage { @@ -1655,10 +1633,7 @@ pub struct ImproperCTypes<'a> { // Used because of the complexity of Option<DiagnosticMessage>, DiagnosticMessage, and Option<Span> impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.set_arg("ty", self.ty); diag.set_arg("desc", self.desc); diag.span_label(self.label, fluent::lint_label); @@ -1669,7 +1644,6 @@ impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> { if let Some(note) = self.span_note { diag.span_note(note, fluent::lint_note); } - diag } fn msg(&self) -> rustc_errors::DiagnosticMessage { @@ -1802,10 +1776,7 @@ pub enum UnusedDefSuggestion { // Needed because of def_path_str impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.set_arg("pre", self.pre); diag.set_arg("post", self.post); diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id)); @@ -1816,7 +1787,6 @@ impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> { if let Some(sugg) = self.suggestion { diag.subdiagnostic(sugg); } - diag } fn msg(&self) -> rustc_errors::DiagnosticMessage { @@ -1889,15 +1859,11 @@ pub struct AsyncFnInTraitDiag { } impl<'a> DecorateLint<'a, ()> for AsyncFnInTraitDiag { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.note(fluent::lint_note); if let Some(sugg) = self.sugg { diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect); } - diag } fn msg(&self) -> rustc_errors::DiagnosticMessage { diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index f0e415492ae..9fcd70ba0b5 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -126,7 +126,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc lint.note(fluent::lint_more_info_note); if !is_arg_inside_call(arg_span, span) { // No clue where this argument is coming from. - return lint; + return; } if arg_macro.is_some_and(|id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) { // A case of `panic!(format!(..))`. @@ -207,7 +207,6 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } } } - lint }); } diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 82483ac7dc0..96290288f07 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -37,59 +37,73 @@ declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]); impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else { - return; - }; - - let init = cx.expr_or_init(e); - - let Some(ty_has_interior_mutability) = is_cast_from_const_to_mut(cx, init) else { - return; - }; - let orig_cast = if init.span != e.span { Some(init.span) } else { None }; - let ty_has_interior_mutability = ty_has_interior_mutability.then_some(()); - - cx.emit_spanned_lint( - INVALID_REFERENCE_CASTING, - expr.span, - if is_assignment { - InvalidReferenceCastingDiag::AssignToRef { orig_cast, ty_has_interior_mutability } - } else { - InvalidReferenceCastingDiag::BorrowAsMut { orig_cast, ty_has_interior_mutability } - }, - ); + if let Some((e, pat)) = borrow_or_assign(cx, expr) { + if matches!(pat, PatternKind::Borrow { mutbl: Mutability::Mut } | PatternKind::Assign) { + let init = cx.expr_or_init(e); + + let Some(ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr(cx, init) else { + return; + }; + let orig_cast = if init.span != e.span { Some(init.span) } else { None }; + let ty_has_interior_mutability = ty_has_interior_mutability.then_some(()); + + cx.emit_spanned_lint( + INVALID_REFERENCE_CASTING, + expr.span, + if pat == PatternKind::Assign { + InvalidReferenceCastingDiag::AssignToRef { + orig_cast, + ty_has_interior_mutability, + } + } else { + InvalidReferenceCastingDiag::BorrowAsMut { + orig_cast, + ty_has_interior_mutability, + } + }, + ); + } + } } } -fn is_operation_we_care_about<'tcx>( +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum PatternKind { + Borrow { mutbl: Mutability }, + Assign, +} + +fn borrow_or_assign<'tcx>( cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>, -) -> Option<(bool, &'tcx Expr<'tcx>)> { - fn deref_assign_or_addr_of<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(bool, &'tcx Expr<'tcx>)> { - // &mut <expr> - let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind { - expr +) -> Option<(&'tcx Expr<'tcx>, PatternKind)> { + fn deref_assign_or_addr_of<'tcx>( + expr: &'tcx Expr<'tcx>, + ) -> Option<(&'tcx Expr<'tcx>, PatternKind)> { + // &(mut) <expr> + let (inner, pat) = if let ExprKind::AddrOf(_, mutbl, expr) = expr.kind { + (expr, PatternKind::Borrow { mutbl }) // <expr> = ... } else if let ExprKind::Assign(expr, _, _) = expr.kind { - expr + (expr, PatternKind::Assign) // <expr> += ... } else if let ExprKind::AssignOp(_, expr, _) = expr.kind { - expr + (expr, PatternKind::Assign) } else { return None; }; - if let ExprKind::Unary(UnOp::Deref, e) = &inner.kind { - Some((!matches!(expr.kind, ExprKind::AddrOf(..)), e)) - } else { - None - } + // *<inner> + let ExprKind::Unary(UnOp::Deref, e) = &inner.kind else { + return None; + }; + Some((e, pat)) } fn ptr_write<'tcx>( cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>, - ) -> Option<(bool, &'tcx Expr<'tcx>)> { + ) -> Option<(&'tcx Expr<'tcx>, PatternKind)> { if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() @@ -98,7 +112,7 @@ fn is_operation_we_care_about<'tcx>( Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned) ) { - Some((true, arg_ptr)) + Some((arg_ptr, PatternKind::Assign)) } else { None } @@ -107,13 +121,10 @@ fn is_operation_we_care_about<'tcx>( deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e)) } -fn is_cast_from_const_to_mut<'tcx>( +fn is_cast_from_ref_to_mut_ptr<'tcx>( cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>, ) -> Option<bool> { - let mut need_check_freeze = false; - let mut e = orig_expr; - let end_ty = cx.typeck_results().node_type(orig_expr.hir_id); // Bail out early if the end type is **not** a mutable pointer. @@ -121,6 +132,28 @@ fn is_cast_from_const_to_mut<'tcx>( return None; } + let (e, need_check_freeze) = peel_casts(cx, orig_expr); + + let start_ty = cx.typeck_results().node_type(e.hir_id); + if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() { + // If an UnsafeCell method is involved, we need to additionally check the + // inner type for the presence of the Freeze trait (ie does NOT contain + // an UnsafeCell), since in that case we would incorrectly lint on valid casts. + // + // Except on the presence of non concrete skeleton types (ie generics) + // since there is no way to make it safe for arbitrary types. + let inner_ty_has_interior_mutability = + !inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton(); + (!need_check_freeze || !inner_ty_has_interior_mutability) + .then_some(inner_ty_has_interior_mutability) + } else { + None + } +} + +fn peel_casts<'tcx>(cx: &LateContext<'tcx>, mut e: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, bool) { + let mut gone_trough_unsafe_cell_raw_get = false; + loop { e = e.peel_blocks(); // <expr> as ... @@ -145,27 +178,18 @@ fn is_cast_from_const_to_mut<'tcx>( ) { if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) { - need_check_freeze = true; + gone_trough_unsafe_cell_raw_get = true; } arg } else { - break; + let init = cx.expr_or_init(e); + if init.hir_id != e.hir_id { + init + } else { + break; + } }; } - let start_ty = cx.typeck_results().node_type(e.hir_id); - if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() { - // If an UnsafeCell method is involved we need to additionally check the - // inner type for the presence of the Freeze trait (ie does NOT contain - // an UnsafeCell), since in that case we would incorrectly lint on valid casts. - // - // We also consider non concrete skeleton types (ie generics) - // to be an issue since there is no way to make it safe for abitrary types. - let inner_ty_has_interior_mutability = - !inner_ty.is_freeze(cx.tcx, cx.param_env) && inner_ty.has_concrete_skeleton(); - (!need_check_freeze || !inner_ty_has_interior_mutability) - .then_some(inner_ty_has_interior_mutability) - } else { - None - } + (e, gone_trough_unsafe_cell_raw_get) } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 810d691d16a..6dade43a183 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -202,7 +202,7 @@ fn lint_overflowing_range_endpoint<'tcx>( ) -> bool { // Look past casts to support cases like `0..256 as u8` let (expr, lit_span) = if let Node::Expr(par_expr) = - cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id)) + cx.tcx.hir_node(cx.tcx.hir().parent_id(expr.hir_id)) && let ExprKind::Cast(_, _) = par_expr.kind { (par_expr, expr.span) @@ -213,7 +213,7 @@ fn lint_overflowing_range_endpoint<'tcx>( // We only want to handle exclusive (`..`) ranges, // which are represented as `ExprKind::Struct`. let par_id = cx.tcx.hir().parent_id(expr.hir_id); - let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false }; + let Node::ExprField(field) = cx.tcx.hir_node(par_id) else { return false }; let Node::Expr(struct_expr) = cx.tcx.hir().get_parent(field.hir_id) else { return false }; if !is_range_literal(struct_expr) { return false; @@ -498,7 +498,7 @@ fn lint_uint_literal<'tcx>( }; if lit_val < min || lit_val > max { let parent_id = cx.tcx.hir().parent_id(e.hir_id); - if let Node::Expr(par_e) = cx.tcx.hir().get(parent_id) { + if let Node::Expr(par_e) = cx.tcx.hir_node(parent_id) { match par_e.kind { hir::ExprKind::Cast(..) => { if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e6e445c54b1..f9b66239bf9 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -47,7 +47,6 @@ declare_lint_pass! { HIDDEN_GLOB_REEXPORTS, ILL_FORMED_ATTRIBUTE_INPUT, ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, - IMPLIED_BOUNDS_ENTAILMENT, INCOMPLETE_INCLUDE, INDIRECT_STRUCTURAL_MATCH, INEFFECTIVE_UNSTABLE_TRAIT_IMPL, @@ -4236,47 +4235,6 @@ declare_lint! { } declare_lint! { - /// The `implied_bounds_entailment` lint detects cases where the arguments of an impl method - /// have stronger implied bounds than those from the trait method it's implementing. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(implied_bounds_entailment)] - /// - /// trait Trait { - /// fn get<'s>(s: &'s str, _: &'static &'static ()) -> &'static str; - /// } - /// - /// impl Trait for () { - /// fn get<'s>(s: &'s str, _: &'static &'s ()) -> &'static str { - /// s - /// } - /// } - /// - /// let val = <() as Trait>::get(&String::from("blah blah blah"), &&()); - /// println!("{}", val); - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Neither the trait method, which provides no implied bounds about `'s`, nor the impl, - /// requires the main function to prove that 's: 'static, but the impl method is allowed - /// to assume that `'s: 'static` within its own body. - /// - /// This can be used to implement an unsound API if used incorrectly. - pub IMPLIED_BOUNDS_ENTAILMENT, - Deny, - "impl method assumes more implied bounds than its corresponding trait method", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #105572 <https://github.com/rust-lang/rust/issues/105572>", - }; -} - -declare_lint! { /// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field /// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or /// more built-in traits. diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 31ad9cdb216..cd61544f69d 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -175,9 +175,9 @@ impl<'a> LintDiagnosticDerive<'a> { fn decorate_lint<'__b>( self, #diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> - ) -> &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> { + ) { use rustc_errors::IntoDiagnosticArg; - #implementation + #implementation; } fn msg(&self) -> rustc_errors::DiagnosticMessage { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 143e439bd57..ad3fea65e82 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1144,7 +1144,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> let origin = tcx.opaque_type_origin(def_id); if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin - && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id) + && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { false @@ -1161,7 +1161,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> } } DefKind::TyParam => { - let hir::Node::GenericParam(param) = tcx.hir().get_by_def_id(def_id) else { bug!() }; + let hir::Node::GenericParam(param) = tcx.hir_node_by_def_id(def_id) else { bug!() }; let hir::GenericParamKind::Type { default, .. } = param.kind else { bug!() }; default.is_some() } @@ -1372,7 +1372,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // anonymous constants will not work on them and panic. It's not clear whether it // can cause any observable issues or not. let anon_const_without_hir = def_kind == DefKind::AnonConst - && tcx.hir().find(tcx.local_def_id_to_hir_id(local_id)).is_none(); + && tcx.opt_hir_node(tcx.local_def_id_to_hir_id(local_id)).is_none(); if should_encode_generics(def_kind) && !anon_const_without_hir { let g = tcx.generics_of(def_id); record!(self.tables.generics_of[def_id] <- g); diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 4af886a9718..598c26de23f 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -57,6 +57,10 @@ fn is_body_owner(node: Node<'_>, hir_id: HirId) -> bool { } } +// FIXME: the structure was necessary in the past but now it +// only serves as "namespace" for HIR-related methods, and can be +// removed if all the methods are reasonably renamed and moved to tcx +// (https://github.com/rust-lang/rust/pull/118256#issuecomment-1826442834). #[derive(Copy, Clone)] pub struct Map<'hir> { pub(super) tcx: TyCtxt<'hir>, @@ -128,6 +132,40 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> { } } +impl<'tcx> TyCtxt<'tcx> { + /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found. + pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> { + if id.local_id == ItemLocalId::from_u32(0) { + let owner = self.hir_owner(id.owner)?; + Some(owner.node.into()) + } else { + let owner = self.hir_owner_nodes(id.owner).as_owner()?; + let node = owner.nodes[id.local_id].as_ref()?; + Some(node.node) + } + } + + /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found. + #[inline] + pub fn opt_hir_node_by_def_id(self, id: LocalDefId) -> Option<Node<'tcx>> { + self.opt_hir_node(self.opt_local_def_id_to_hir_id(id)?) + } + + /// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found. + #[track_caller] + pub fn hir_node(self, id: HirId) -> Node<'tcx> { + self.opt_hir_node(id).unwrap_or_else(|| bug!("couldn't find HIR node for hir id {id:?}")) + } + + /// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found. + #[inline] + #[track_caller] + pub fn hir_node_by_def_id(self, id: LocalDefId) -> Node<'tcx> { + self.opt_hir_node_by_def_id(id) + .unwrap_or_else(|| bug!("couldn't find HIR node for def id {id:?}")) + } +} + impl<'hir> Map<'hir> { #[inline] pub fn krate(self) -> &'hir Crate<'hir> { @@ -191,46 +229,15 @@ impl<'hir> Map<'hir> { } pub fn get_parent(self, hir_id: HirId) -> Node<'hir> { - self.get(self.parent_id(hir_id)) + self.tcx.hir_node(self.parent_id(hir_id)) } pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> { - self.find(self.opt_parent_id(hir_id)?) - } - - /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. - pub fn find(self, id: HirId) -> Option<Node<'hir>> { - if id.local_id == ItemLocalId::from_u32(0) { - let owner = self.tcx.hir_owner(id.owner)?; - Some(owner.node.into()) - } else { - let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?; - let node = owner.nodes[id.local_id].as_ref()?; - Some(node.node) - } - } - - /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. - #[inline] - pub fn find_by_def_id(self, id: LocalDefId) -> Option<Node<'hir>> { - self.find(self.tcx.opt_local_def_id_to_hir_id(id)?) - } - - /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found. - #[track_caller] - pub fn get(self, id: HirId) -> Node<'hir> { - self.find(id).unwrap_or_else(|| bug!("couldn't find hir id {} in the HIR map", id)) - } - - /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found. - #[inline] - #[track_caller] - pub fn get_by_def_id(self, id: LocalDefId) -> Node<'hir> { - self.find_by_def_id(id).unwrap_or_else(|| bug!("couldn't find {:?} in the HIR map", id)) + self.tcx.opt_hir_node(self.opt_parent_id(hir_id)?) } pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> { - id.as_local().and_then(|id| self.find(self.tcx.opt_local_def_id_to_hir_id(id)?)) + id.as_local().and_then(|id| self.tcx.opt_hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?)) } pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> { @@ -264,7 +271,7 @@ impl<'hir> Map<'hir> { #[track_caller] pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> { - if let Some(node) = self.find(hir_id) { + if let Some(node) = self.tcx.opt_hir_node(hir_id) { node.fn_decl() } else { bug!("no node for hir_id `{}`", hir_id) @@ -273,7 +280,7 @@ impl<'hir> Map<'hir> { #[track_caller] pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> { - if let Some(node) = self.find(hir_id) { + if let Some(node) = self.tcx.opt_hir_node(hir_id) { node.fn_sig() } else { bug!("no node for hir_id `{}`", hir_id) @@ -296,19 +303,22 @@ impl<'hir> Map<'hir> { /// item (possibly associated), a closure, or a `hir::AnonConst`. pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId { let parent = self.parent_id(hir_id); - assert!(self.find(parent).is_some_and(|n| is_body_owner(n, hir_id)), "{hir_id:?}"); + assert!( + self.tcx.opt_hir_node(parent).is_some_and(|n| is_body_owner(n, hir_id)), + "{hir_id:?}" + ); parent } pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId { let parent = self.parent_id(hir_id); - associated_body(self.get(parent)).unwrap().0 + associated_body(self.tcx.hir_node(parent)).unwrap().0 } /// Given a `LocalDefId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<BodyId> { - let node = self.find_by_def_id(id)?; + let node = self.tcx.opt_hir_node_by_def_id(id)?; let (_, body_id) = associated_body(node)?; Some(body_id) } @@ -548,7 +558,7 @@ impl<'hir> Map<'hir> { /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> { - self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?))) + self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.tcx.opt_hir_node(id)?))) } /// Returns an iterator for the nodes in the ancestor tree of the `current_id` @@ -600,7 +610,7 @@ impl<'hir> Map<'hir> { pub fn get_return_block(self, id: HirId) -> Option<HirId> { let mut iter = self.parent_iter(id).peekable(); let mut ignore_tail = false; - if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.find(id) { + if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.tcx.opt_hir_node(id) { // When dealing with `return` statements, we don't care about climbing only tail // expressions. ignore_tail = true; @@ -708,7 +718,7 @@ impl<'hir> Map<'hir> { let mut scope = id; loop { scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID); - if scope == CRATE_HIR_ID || !matches!(self.get(scope), Node::Block(_)) { + if scope == CRATE_HIR_ID || !matches!(self.tcx.hir_node(scope), Node::Block(_)) { return scope; } } @@ -764,7 +774,7 @@ impl<'hir> Map<'hir> { } pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> { - match self.find(id) { + match self.tcx.opt_hir_node(id) { Some(Node::Variant(variant)) => variant, _ => bug!("expected variant, found {}", self.node_to_string(id)), } @@ -783,7 +793,7 @@ impl<'hir> Map<'hir> { } pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> { - match self.find(id) { + match self.tcx.opt_hir_node(id) { Some(Node::Expr(expr)) => expr, _ => bug!("expected expr, found {}", self.node_to_string(id)), } @@ -791,7 +801,7 @@ impl<'hir> Map<'hir> { #[inline] fn opt_ident(self, id: HirId) -> Option<Ident> { - match self.find(id)? { + match self.tcx.opt_hir_node(id)? { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::opt_span`. @@ -860,7 +870,7 @@ impl<'hir> Map<'hir> { } } - let span = match self.find(hir_id)? { + let span = match self.tcx.opt_hir_node(hir_id)? { // Function-like. Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. }) | Node::TraitItem(TraitItem { @@ -950,7 +960,7 @@ impl<'hir> Map<'hir> { /// Like `hir.span()`, but includes the body of items /// (instead of just the item header) pub fn span_with_body(self, hir_id: HirId) -> Span { - match self.get(hir_id) { + match self.tcx.hir_node(hir_id) { Node::Param(param) => param.span, Node::Item(item) => item.span, Node::ForeignItem(foreign_item) => foreign_item.span, @@ -1045,7 +1055,7 @@ impl<'hir> Map<'hir> { impl<'hir> intravisit::Map<'hir> for Map<'hir> { fn find(&self, hir_id: HirId) -> Option<Node<'hir>> { - (*self).find(hir_id) + self.tcx.opt_hir_node(hir_id) } fn body(&self, id: BodyId) -> &'hir Body<'hir> { @@ -1159,7 +1169,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); - match map.find(id) { + match map.tcx.opt_hir_node(id) { Some(Node::Item(item)) => { let item_str = match item.kind { ItemKind::ExternCrate(..) => "extern crate", diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index a16317a0c67..af99c7d55c3 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -195,7 +195,7 @@ pub fn provide(providers: &mut Providers) { | Node::ForeignItem(&ForeignItem { kind: ForeignItemKind::Fn(_, idents, _), .. - }) = hir.get(hir_id) + }) = tcx.hir_node(hir_id) { idents } else { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index ef5a1caadb7..e544c2a26e8 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -21,17 +21,20 @@ //! //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lock; use rustc_macros::HashStable; use rustc_type_ir::Canonical as IrCanonical; use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo; pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind}; use smallvec::SmallVec; +use std::collections::hash_map::Entry; use std::ops::Index; use crate::infer::MemberConstraint; use crate::mir::ConstraintCategory; use crate::ty::GenericArg; -use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt}; +use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; pub type Canonical<'tcx, V> = IrCanonical<TyCtxt<'tcx>, V>; @@ -291,3 +294,62 @@ impl<'tcx> Index<BoundVar> for CanonicalVarValues<'tcx> { &self.var_values[value.as_usize()] } } + +#[derive(Default)] +pub struct CanonicalParamEnvCache<'tcx> { + map: Lock< + FxHashMap< + ty::ParamEnv<'tcx>, + (Canonical<'tcx, ty::ParamEnv<'tcx>>, &'tcx [GenericArg<'tcx>]), + >, + >, +} + +impl<'tcx> CanonicalParamEnvCache<'tcx> { + /// Gets the cached canonical form of `key` or executes + /// `canonicalize_op` and caches the result if not present. + /// + /// `canonicalize_op` is intentionally not allowed to be a closure to + /// statically prevent it from capturing `InferCtxt` and resolving + /// inference variables, which invalidates the cache. + pub fn get_or_insert( + &self, + tcx: TyCtxt<'tcx>, + key: ty::ParamEnv<'tcx>, + state: &mut OriginalQueryValues<'tcx>, + canonicalize_op: fn( + TyCtxt<'tcx>, + ty::ParamEnv<'tcx>, + &mut OriginalQueryValues<'tcx>, + ) -> Canonical<'tcx, ty::ParamEnv<'tcx>>, + ) -> Canonical<'tcx, ty::ParamEnv<'tcx>> { + if !key.has_type_flags( + TypeFlags::HAS_INFER | TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_FREE_REGIONS, + ) { + return Canonical { + max_universe: ty::UniverseIndex::ROOT, + variables: List::empty(), + value: key, + }; + } + + assert_eq!(state.var_values.len(), 0); + assert_eq!(state.universe_map.len(), 1); + debug_assert_eq!(&*state.universe_map, &[ty::UniverseIndex::ROOT]); + + match self.map.borrow().entry(key) { + Entry::Occupied(e) => { + let (canonical, var_values) = e.get(); + state.var_values.extend_from_slice(var_values); + *canonical + } + Entry::Vacant(e) => { + let canonical = canonicalize_op(tcx, key, state); + let OriginalQueryValues { var_values, universe_map } = state; + assert_eq!(universe_map.len(), 1); + e.insert((canonical, tcx.arena.alloc_slice(var_values))); + canonical + } + } + } +} diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index eada116f896..4c4f38d1ad8 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -253,29 +253,10 @@ pub fn explain_lint_level_source( /// - [`TyCtxt::struct_lint_node`] /// - `LintContext::lookup` /// -/// ## `decorate` signature +/// ## `decorate` /// -/// The return value of `decorate` is ignored by this function. So what is the -/// point of returning `&'b mut DiagnosticBuilder<'a, ()>`? -/// -/// There are 2 reasons for this signature. -/// -/// First of all, it prevents accidental use of `.emit()` -- it's clear that the -/// builder will be later used and shouldn't be emitted right away (this is -/// especially important because the old API expected you to call `.emit()` in -/// the closure). -/// -/// Second of all, it makes the most common case of adding just a single label -/// /suggestion much nicer, since [`DiagnosticBuilder`] methods return -/// `&mut DiagnosticBuilder`, you can just chain methods, without needed -/// awkward `{ ...; }`: -/// ```ignore pseudo-code -/// struct_lint_level( -/// ..., -/// |lint| lint.span_label(sp, "lbl") -/// // ^^^^^^^^^^^^^^^^^^^^^ returns `&mut DiagnosticBuilder` by default -/// ) -/// ``` +/// It is not intended to call `emit`/`cancel` on the `DiagnosticBuilder` passed +/// in the `decorate` callback. #[track_caller] pub fn struct_lint_level( sess: &Session, @@ -284,9 +265,7 @@ pub fn struct_lint_level( src: LintLevelSource, span: Option<MultiSpan>, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to // the "real" work. @@ -298,12 +277,7 @@ pub fn struct_lint_level( src: LintLevelSource, span: Option<MultiSpan>, msg: impl Into<DiagnosticMessage>, - decorate: Box< - dyn '_ - + for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, - >, + decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>)>, ) { // Check for future incompatibility lints and issue a stronger warning. let future_incompatible = lint.future_incompatible; diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 9a633e04ce7..2899e629d79 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -36,6 +36,17 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Given a [`ty::ClosureKind`], get the [`DefId`] of its corresponding `Fn`-family + /// trait, if it is defined. + pub fn fn_trait_kind_to_def_id(self, kind: ty::ClosureKind) -> Option<DefId> { + let items = self.lang_items(); + match kind { + ty::ClosureKind::Fn => items.fn_trait(), + ty::ClosureKind::FnMut => items.fn_mut_trait(), + ty::ClosureKind::FnOnce => items.fn_once_trait(), + } + } + /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits. pub fn is_fn_trait(self, id: DefId) -> bool { self.fn_trait_kind_from_def_id(id).is_some() diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 30f13afff9a..3f6dc2b9f12 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -180,7 +180,7 @@ impl Scope { }; let span = tcx.hir().span(hir_id); if let ScopeData::Remainder(first_statement_index) = self.data { - if let Node::Block(blk) = tcx.hir().get(hir_id) { + if let Node::Block(blk) = tcx.hir_node(hir_id) { // Want span for scope starting after the // indexed statement and ending at end of // `blk`; reuse span of `blk` and shift `lo` diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 27d82f5fefc..0cba6d5b52a 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -219,11 +219,10 @@ fn late_report_deprecation( } let method_span = method_span.unwrap_or(span); tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| { - if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { + if let hir::Node::Expr(_) = tcx.hir_node(hir_id) { let kind = tcx.def_descr(def_id); deprecation_suggestion(diag, kind, suggestion, method_span); } - diag }); } @@ -587,7 +586,7 @@ impl<'tcx> TyCtxt<'tcx> { unmarked: impl FnOnce(Span, DefId), ) -> bool { let soft_handler = |lint, span, msg: String| { - self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |lint| lint) + self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {}) }; let eval_result = self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 34068a9da37..092b59deeff 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -113,7 +113,7 @@ impl<'tcx> TyCtxt<'tcx> { self.local_def_id_to_hir_id(local_def_id), self.def_span(ct.def), "cannot use constants which depend on generic parameters in types", - |err| err, + |_| {}, ) } } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index ea6b44d62b0..93a9bbf64c9 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -15,7 +15,6 @@ TrivialTypeTraversalImpls! { UserTypeAnnotationIndex, BorrowKind, CastKind, - hir::Movability, BasicBlock, SwitchTargets, CoroutineKind, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 03f3ceb8d17..a69bff6ed8c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2177,7 +2177,9 @@ rustc_queries! { /// Used in `super_combine_consts` to ICE if the type of the two consts are definitely not going to end up being /// equal to eachother. This might return `Ok` even if the types are not equal, but will never return `Err` if /// the types might be equal. - query check_tys_might_be_eq(arg: Canonical<'tcx, (ty::ParamEnv<'tcx>, Ty<'tcx>, Ty<'tcx>)>) -> Result<(), NoSolution> { + query check_tys_might_be_eq( + arg: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>> + ) -> Result<(), NoSolution> { desc { "check whether two const param are definitely not equal to eachother"} } diff --git a/compiler/rustc_middle/src/traits/solve/cache.rs b/compiler/rustc_middle/src/traits/solve/cache.rs index e9e9cc418a6..4f90af0a27c 100644 --- a/compiler/rustc_middle/src/traits/solve/cache.rs +++ b/compiler/rustc_middle/src/traits/solve/cache.rs @@ -5,7 +5,7 @@ use rustc_data_structures::sync::Lock; use rustc_query_system::cache::WithDepNode; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_session::Limit; -/// The trait solver cache used by `-Ztrait-solver=next`. +/// The trait solver cache used by `-Znext-solver`. /// /// FIXME(@lcnr): link to some official documentation of how /// this works. diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index eaf5da130dd..8c29bc5a428 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -7,14 +7,13 @@ use std::fmt::Write; use crate::query::Providers; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, LangItem}; +use rustc_hir as hir; +use rustc_hir::def_id::LocalDefId; use rustc_span::def_id::LocalDefIdMap; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; -use super::{Ty, TyCtxt}; +use super::TyCtxt; use self::BorrowKind::*; @@ -73,72 +72,6 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureLis /// Part of `MinCaptureInformationMap`; List of `CapturePlace`s. pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>; -/// Represents the various closure traits in the language. This -/// will determine the type of the environment (`self`, in the -/// desugaring) argument that the closure expects. -/// -/// You can get the environment type of a closure using -/// `tcx.closure_env_ty()`. -#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable)] -pub enum ClosureKind { - // Warning: Ordering is significant here! The ordering is chosen - // because the trait Fn is a subtrait of FnMut and so in turn, and - // hence we order it so that Fn < FnMut < FnOnce. - Fn, - FnMut, - FnOnce, -} - -impl ClosureKind { - /// This is the initial value used when doing upvar inference. - pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn; - - pub const fn as_str(self) -> &'static str { - match self { - ClosureKind::Fn => "Fn", - ClosureKind::FnMut => "FnMut", - ClosureKind::FnOnce => "FnOnce", - } - } - - /// Returns `true` if a type that impls this closure kind - /// must also implement `other`. - pub fn extends(self, other: ty::ClosureKind) -> bool { - self <= other - } - - /// Converts `self` to a [`DefId`] of the corresponding trait. - /// - /// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`]. - pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId { - tcx.require_lang_item( - match self { - ClosureKind::Fn => LangItem::Fn, - ClosureKind::FnMut => LangItem::FnMut, - ClosureKind::FnOnce => LangItem::FnOnce, - }, - None, - ) - } - - /// Returns the representative scalar type for this closure kind. - /// See `Ty::to_opt_closure_kind` for more details. - pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - match self { - ClosureKind::Fn => tcx.types.i8, - ClosureKind::FnMut => tcx.types.i16, - ClosureKind::FnOnce => tcx.types.i32, - } - } -} - -impl IntoDiagnosticArg for ClosureKind { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(self.as_str().into()) - } -} - /// A composite describing a `Place` that is captured by a closure. #[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index b99e5a4f813..2d3ee33489e 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -59,7 +59,7 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn kind(self) -> ConstKind<'tcx> { - self.0.kind.clone() + self.0.kind } #[inline] @@ -167,7 +167,7 @@ impl<'tcx> Const<'tcx> { /// becomes `Unevaluated`. #[instrument(skip(tcx), level = "debug")] pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { - let body_id = match tcx.hir().get_by_def_id(def) { + let body_id = match tcx.hir_node_by_def_id(def) { hir::Node::AnonConst(ac) => ac.body, _ => span_bug!( tcx.def_span(def.to_def_id()), @@ -443,7 +443,7 @@ impl<'tcx> Const<'tcx> { } pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Const<'_>> { - let default_def_id = match tcx.hir().get_by_def_id(def_id) { + let default_def_id = match tcx.hir_node_by_def_id(def_id) { hir::Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { default: Some(ac), .. }, .. diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 9d99344d5bd..310cf113b11 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -71,7 +71,7 @@ impl std::fmt::Debug for ConstInt { (4, _) => write!(fmt, "_i32")?, (8, _) => write!(fmt, "_i64")?, (16, _) => write!(fmt, "_i128")?, - _ => bug!(), + (sz, _) => bug!("unexpected int size i{sz}"), } } Ok(()) @@ -105,7 +105,7 @@ impl std::fmt::Debug for ConstInt { (4, _) => write!(fmt, "_u32")?, (8, _) => write!(fmt, "_u64")?, (16, _) => write!(fmt, "_u128")?, - _ => bug!(), + (sz, _) => bug!("unexpected unsigned int size u{sz}"), } } Ok(()) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index eb6fde83fcc..6a6ed59fabf 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -6,7 +6,7 @@ pub mod tls; use crate::arena::Arena; use crate::dep_graph::{DepGraph, DepKindStruct}; -use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; +use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos}; use crate::lint::struct_lint_level; use crate::metadata::ModChild; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; @@ -28,7 +28,7 @@ use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind, ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, - TypeAndMut, Visibility, + Visibility, }; use crate::ty::{GenericArg, GenericArgs, GenericArgsRef}; use rustc_ast::{self as ast, attr}; @@ -88,7 +88,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Term = ty::Term<'tcx>; type Binder<T> = Binder<'tcx, T>; - type TypeAndMut = TypeAndMut<'tcx>; type CanonicalVars = CanonicalVarInfos<'tcx>; type Ty = Ty<'tcx>; @@ -128,12 +127,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type CoercePredicate = ty::CoercePredicate<'tcx>; type ClosureKind = ty::ClosureKind; - fn ty_and_mut_to_parts( - TypeAndMut { ty, mutbl }: TypeAndMut<'tcx>, - ) -> (Self::Ty, ty::Mutability) { - (ty, mutbl) - } - fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars { self.mk_canonical_var_infos(infos) } @@ -653,6 +646,8 @@ pub struct GlobalCtxt<'tcx> { pub new_solver_evaluation_cache: solve::EvaluationCache<'tcx>, pub new_solver_coherence_evaluation_cache: solve::EvaluationCache<'tcx>, + pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>, + /// Data layout specification for the current target. pub data_layout: TargetDataLayout, @@ -817,6 +812,7 @@ impl<'tcx> TyCtxt<'tcx> { evaluation_cache: Default::default(), new_solver_evaluation_cache: Default::default(), new_solver_coherence_evaluation_cache: Default::default(), + canonical_param_env_cache: Default::default(), data_layout, alloc_map: Lock::new(interpret::AllocMap::new()), } @@ -1174,7 +1170,7 @@ impl<'tcx> TyCtxt<'tcx> { break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into()))); }; - let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) { + let is_impl_item = match self.opt_hir_node_by_def_id(suitable_region_binding_scope) { Some(Node::Item(..) | Node::TraitItem(..)) => false, Some(Node::ImplItem(..)) => { self.is_bound_region_in_impl_item(suitable_region_binding_scope) @@ -1217,8 +1213,8 @@ impl<'tcx> TyCtxt<'tcx> { None, hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind && let Some(local_id) = def_id.as_local() - && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias - && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics() + && let Some(alias_ty) = self.hir_node_by_def_id(local_id).alias_ty() // it is type alias + && let Some(alias_generics) = self.hir_node_by_def_id(local_id).generics() { v.visit_ty(alias_ty); if !v.0.is_empty() { @@ -2034,14 +2030,12 @@ impl<'tcx> TyCtxt<'tcx> { let msg = decorator.msg(); let (level, src) = self.lint_level_at_node(lint, hir_id); struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| { - decorator.decorate_lint(diag) + decorator.decorate_lint(diag); }) } /// Emit a lint at the appropriate level for a hir node, with an associated span. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] #[track_caller] @@ -2051,9 +2045,7 @@ impl<'tcx> TyCtxt<'tcx> { hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, hir_id); struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); @@ -2068,13 +2060,13 @@ impl<'tcx> TyCtxt<'tcx> { id: HirId, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag)) + self.struct_lint_node(lint, id, decorator.msg(), |diag| { + decorator.decorate_lint(diag); + }) } /// Emit a lint at the appropriate level for a hir node. /// - /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. - /// /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature #[rustc_lint_diagnostics] #[track_caller] @@ -2083,9 +2075,7 @@ impl<'tcx> TyCtxt<'tcx> { lint: &'static Lint, id: HirId, msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()>, + decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, id); struct_lint_level(self.sess, lint, level, src, None, msg, decorate); @@ -2137,7 +2127,7 @@ impl<'tcx> TyCtxt<'tcx> { loop { let parent = self.local_parent(rpit_lifetime_param_def_id); let hir::OpaqueTy { lifetime_mapping, .. } = - self.hir().get_by_def_id(parent).expect_item().expect_opaque_ty(); + self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty(); let Some((lifetime, _)) = lifetime_mapping .iter() @@ -2221,8 +2211,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Whether the trait impl is marked const. This does not consider stability or feature gates. pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { let Some(local_def_id) = def_id.as_local() else { return false }; - let hir_id = self.local_def_id_to_hir_id(local_def_id); - let node = self.hir().get(hir_id); + let node = self.hir_node_by_def_id(local_def_id); matches!( node, @@ -2238,15 +2227,11 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn next_trait_solver_globally(self) -> bool { - self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next + self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally) } pub fn next_trait_solver_in_coherence(self) -> bool { - matches!( - self.sess.opts.unstable_opts.trait_solver, - rustc_session::config::TraitSolver::Next - | rustc_session::config::TraitSolver::NextCoherence - ) + self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence) } pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 469593fe663..0e44878524b 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -345,33 +345,35 @@ impl<'tcx> TyCtxt<'tcx> { short } - pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { + pub fn short_ty_string(self, ty: Ty<'tcx>, path: &mut Option<PathBuf>) -> String { let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { cx.pretty_print_type(ty) }) .expect("could not write to `String`"); if !self.sess.opts.unstable_opts.write_long_types_to_disk { - return (regular, None); + return regular; } let width = self.sess.diagnostic_width(); let length_limit = width.saturating_sub(30); if regular.len() <= width { - return (regular, None); + return regular; } let short = self.ty_string_with_limit(ty, length_limit); if regular == short { - return (regular, None); + return regular; } - // Multiple types might be shortened in a single error, ensure we create a file for each. + // Ensure we create an unique file for the type passed in when we create a file. let mut s = DefaultHasher::new(); ty.hash(&mut s); let hash = s.finish(); - let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None); - match std::fs::write(&path, ®ular) { - Ok(_) => (short, Some(path)), - Err(_) => (regular, None), + *path = Some(path.take().unwrap_or_else(|| { + self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None) + })); + match std::fs::write(path.as_ref().unwrap(), &format!("{regular}\n")) { + Ok(_) => short, + Err(_) => regular, } } } diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index f95ceeff150..38a9cabca97 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -62,7 +62,7 @@ pub enum TreatParams { /// /// N.B. during deep rejection, this acts identically to `ForLookup`. /// - /// FIXME(-Ztrait-solver=next): Remove this variant and cleanup + /// FIXME(-Znext-solver): Remove this variant and cleanup /// the code. NextSolverLookup, } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 71ff7021ca5..febab23ea35 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -75,7 +75,7 @@ pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; pub use self::closure::{ is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo, - CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList, + CapturedPlace, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList, RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL, }; pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree}; @@ -473,7 +473,7 @@ impl<'tcx> IntoKind for Ty<'tcx> { type Kind = TyKind<'tcx>; fn kind(self) -> TyKind<'tcx> { - self.kind().clone() + *self.kind() } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 39adfac55ce..8e045397b0f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1680,7 +1680,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.wrap_binder(&sig, |sig, cx| { define_scoped_cx!(cx); - p!(print(kind), "("); + p!(write("{kind}(")); for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() { if i > 0 { p!(", "); @@ -2754,6 +2754,10 @@ forward_display_to_print! { define_print! { (self, cx): + ty::TypeAndMut<'tcx> { + p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) + } + ty::ClauseKind<'tcx> { match *self { ty::ClauseKind::Trait(ref data) => { @@ -2799,10 +2803,6 @@ define_print_and_forward_display! { p!("{{", comma_sep(self.iter()), "}}") } - ty::TypeAndMut<'tcx> { - p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) - } - ty::ExistentialTraitRef<'tcx> { // Use a type that can't appear in defaults of type parameters. let dummy_self = Ty::new_fresh(cx.tcx(),0); @@ -2943,10 +2943,6 @@ define_print_and_forward_display! { } } - ty::ClosureKind { - p!(write("{}", self.as_str())) - } - ty::Predicate<'tcx> { p!(print(self.kind())) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 0cff6b77eb6..1c75d73e552 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -440,7 +440,6 @@ TrivialTypeTraversalImpls! { // interners). TrivialTypeTraversalAndLiftImpls! { ::rustc_hir::def_id::DefId, - ::rustc_hir::Mutability, ::rustc_hir::Unsafety, ::rustc_target::spec::abi::Abi, crate::ty::ClosureKind, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 50a1b85b169..a0debc8a165 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -15,7 +15,9 @@ use hir::def::DefKind; use polonius_engine::Atom; use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; -use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan}; +use rustc_errors::{ + DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; @@ -42,23 +44,18 @@ use rustc_type_ir::PredicateKind as IrPredicateKind; use rustc_type_ir::RegionKind as IrRegionKind; use rustc_type_ir::TyKind as IrTyKind; use rustc_type_ir::TyKind::*; +use rustc_type_ir::TypeAndMut as IrTypeAndMut; use super::GenericParamDefKind; -// Re-export the `TyKind` from `rustc_type_ir` here for convenience +// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here #[rustc_diagnostic_item = "TyKind"] pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>; pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>; pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>; pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>; pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>; - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct TypeAndMut<'tcx> { - pub ty: Ty<'tcx>, - pub mutbl: hir::Mutability, -} +pub type TypeAndMut<'tcx> = IrTypeAndMut<TyCtxt<'tcx>>; #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] #[derive(HashStable)] @@ -2005,7 +2002,7 @@ impl<'tcx> Ty<'tcx> { pub fn new_error_with_message<S: Into<MultiSpan>>( tcx: TyCtxt<'tcx>, span: S, - msg: impl Into<String>, + msg: impl Into<DiagnosticMessage>, ) -> Ty<'tcx> { let reported = tcx.sess.span_delayed_bug(span, msg); Ty::new(tcx, Error(reported)) @@ -2816,6 +2813,15 @@ impl<'tcx> Ty<'tcx> { } } + /// Inverse of [`Ty::to_opt_closure_kind`]. + pub fn from_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> { + match kind { + ty::ClosureKind::Fn => tcx.types.i8, + ty::ClosureKind::FnMut => tcx.types.i16, + ty::ClosureKind::FnOnce => tcx.types.i32, + } + } + /// Fast path helper for testing if a type is `Sized`. /// /// Returning true means the type is known to be sized. Returning diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 8b1d33848ea..8b2b76764e6 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -421,13 +421,10 @@ impl<'tcx> TyCtxt<'tcx> { let impl_args = match *self.type_of(impl_def_id).instantiate_identity().kind() { ty::Adt(def_, args) if def_ == def => args, - _ => bug!(), + _ => span_bug!(self.def_span(impl_def_id), "expected ADT for self type of `Drop` impl"), }; - let item_args = match *self.type_of(def.did()).instantiate_identity().kind() { - ty::Adt(def_, args) if def_ == def => args, - _ => bug!(), - }; + let item_args = ty::GenericArgs::identity_for_item(self, def.did()); let result = iter::zip(item_args, impl_args) .filter(|&(_, k)| { diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 8ccd3c1aba0..3224f2f26df 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -154,8 +154,9 @@ pub fn recursive_type_error( let (_, field_id) = item_and_field_ids[i]; let (next_item_id, _) = item_and_field_ids[(i + 1) % cycle_len]; // Find the span(s) that contain the next item in the cycle - let hir_id = tcx.local_def_id_to_hir_id(field_id); - let hir::Node::Field(field) = tcx.hir().get(hir_id) else { bug!("expected field") }; + let hir::Node::Field(field) = tcx.hir_node_by_def_id(field_id) else { + bug!("expected field") + }; let mut found = Vec::new(); find_item_ty_spans(tcx, field.ty, next_item_id, &mut found, representable_ids); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 19b6496b102..dae83d4b41b 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -572,7 +572,7 @@ fn construct_const<'a, 'tcx>( let hir_id = tcx.local_def_id_to_hir_id(def); // Figure out what primary body this item has. - let (span, const_ty_span) = match tcx.hir().get(hir_id) { + let (span, const_ty_span) = match tcx.hir_node(hir_id) { Node::Item(hir::Item { kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _, _), span, @@ -640,7 +640,9 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - } DefKind::Closure if coroutine_kind.is_some() => { let coroutine_ty = tcx.type_of(def_id).instantiate_identity(); - let ty::Coroutine(_, args, _) = coroutine_ty.kind() else { bug!() }; + let ty::Coroutine(_, args, _) = coroutine_ty.kind() else { + bug!("expected type of coroutine-like closure to be a coroutine") + }; let args = args.as_coroutine(); let yield_ty = args.yield_ty(); let return_ty = args.return_ty(); @@ -648,7 +650,9 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - } DefKind::Closure => { let closure_ty = tcx.type_of(def_id).instantiate_identity(); - let ty::Closure(_, args) = closure_ty.kind() else { bug!() }; + let ty::Closure(_, args) = closure_ty.kind() else { + bug!("expected type of closure to be a closure") + }; let args = args.as_closure(); let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), args.sig()); let self_ty = match args.kind() { diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 8c4f0257da3..a776e917de5 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -1,7 +1,6 @@ //! Construction of MIR from HIR. //! //! This crate also contains the match exhaustiveness and usefulness checking. -#![allow(rustc::potential_query_instability)] #![feature(assert_matches)] #![feature(associated_type_bounds)] #![feature(box_patterns)] diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 31874b29bb3..ab88463826a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -782,7 +782,7 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) }, hir::ExprKind::Yield(v, _) => ExprKind::Yield { value: self.mirror_expr(v) }, - hir::ExprKind::Err(_) => unreachable!(), + hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"), }; Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 4eba7103c0c..fa3dd2afa85 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -110,7 +110,7 @@ impl<'tcx> Cx<'tcx> { #[instrument(level = "debug", skip(self))] fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Box<Pat<'tcx>> { - let p = match self.tcx.hir().get(p.hir_id) { + let p = match self.tcx.hir_node(p.hir_id) { Node::Pat(p) => p, node => bug!("pattern became {:?}", node), }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 09e0b30a5c7..792a443c908 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -9,7 +9,7 @@ use crate::errors::*; use rustc_arena::TypedArena; use rustc_ast::Mutability; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; @@ -948,7 +948,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( err.note(format!("the matched value is of type `{}`", scrut_ty)); if !is_empty_match { - let mut non_exhaustive_tys = FxHashSet::default(); + let mut non_exhaustive_tys = FxIndexSet::default(); // Look at the first witness. collect_non_exhaustive_tys(cx, &witnesses[0], &mut non_exhaustive_tys); @@ -1104,7 +1104,7 @@ fn joined_uncovered_patterns<'p, 'tcx>( fn collect_non_exhaustive_tys<'tcx>( cx: &MatchCheckCtxt<'_, 'tcx>, pat: &WitnessPat<'tcx>, - non_exhaustive_tys: &mut FxHashSet<Ty<'tcx>>, + non_exhaustive_tys: &mut FxIndexSet<Ty<'tcx>>, ) { if matches!(pat.ctor(), Constructor::NonExhaustive) { non_exhaustive_tys.insert(pat.ty()); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 391d65b338d..a7f23772193 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -492,8 +492,9 @@ impl<'tcx> ConstToPat<'tcx> { PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } } ty::FnPtr(..) => { - // Valtree construction would never succeed for these, so this is unreachable. - unreachable!() + unreachable!( + "Valtree construction would never succeed for FnPtr, so this is unreachable." + ) } _ => { let err = InvalidPattern { span, non_sm_ty: ty }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index af0dab4ebc7..c7762f8ce4e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -174,7 +174,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { span: Span, ) -> 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"); + let msg = "found twice-open range pattern (`..`) outside of error recovery"; return Err(self.tcx.sess.span_delayed_bug(span, msg)); } diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 071024a0fa3..2802f5491be 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -956,11 +956,7 @@ impl Map { // The local is not tracked at all, so it does not alias anything. return; }; - let elems = place - .projection - .iter() - .map(|&elem| elem.try_into()) - .chain(tail_elem.map(Ok).into_iter()); + let elems = place.projection.iter().map(|&elem| elem.try_into()).chain(tail_elem.map(Ok)); for elem in elems { // A field aliases the parent place. if let Some(vi) = self.places[index].value_index { diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 796150f9315..65a0924f1c9 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -13,7 +13,6 @@ use self::spans::CoverageSpans; use crate::MirPass; -use rustc_data_structures::sync::Lrc; use rustc_middle::hir; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::coverage::*; @@ -22,9 +21,9 @@ use rustc_middle::mir::{ TerminatorKind, }; use rustc_middle::ty::TyCtxt; -use rustc_span::def_id::DefId; +use rustc_span::def_id::LocalDefId; use rustc_span::source_map::SourceMap; -use rustc_span::{ExpnKind, SourceFile, Span, Symbol}; +use rustc_span::{ExpnKind, Span, Symbol}; /// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected /// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen @@ -39,31 +38,19 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage { fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) { let mir_source = mir_body.source; - // If the InstrumentCoverage pass is called on promoted MIRs, skip them. - // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601 - if mir_source.promoted.is_some() { - trace!( - "InstrumentCoverage skipped for {:?} (already promoted for Miri evaluation)", - mir_source.def_id() - ); - return; - } + // This pass runs after MIR promotion, but before promoted MIR starts to + // be transformed, so it should never see promoted MIR. + assert!(mir_source.promoted.is_none()); + + let def_id = mir_source.def_id().expect_local(); - let is_fn_like = - tcx.hir().get_by_def_id(mir_source.def_id().expect_local()).fn_kind().is_some(); - - // Only instrument functions, methods, and closures (not constants since they are evaluated - // at compile time by Miri). - // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const - // expressions get coverage spans, we will probably have to "carve out" space for const - // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might - // be tricky if const expressions have no corresponding statements in the enclosing MIR. - // Closures are carved out by their initial `Assign` statement.) - if !is_fn_like { - trace!("InstrumentCoverage skipped for {:?} (not an fn-like)", mir_source.def_id()); + if !is_eligible_for_coverage(tcx, def_id) { + trace!("InstrumentCoverage skipped for {def_id:?} (not eligible)"); return; } + // An otherwise-eligible function is still skipped if its start block + // is known to be unreachable. match mir_body.basic_blocks[mir::START_BLOCK].terminator().kind { TerminatorKind::Unreachable => { trace!("InstrumentCoverage skipped for unreachable `START_BLOCK`"); @@ -72,21 +59,15 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage { _ => {} } - let codegen_fn_attrs = tcx.codegen_fn_attrs(mir_source.def_id()); - if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_COVERAGE) { - return; - } - - trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); + trace!("InstrumentCoverage starting for {def_id:?}"); Instrumentor::new(tcx, mir_body).inject_counters(); - trace!("InstrumentCoverage done for {:?}", mir_source.def_id()); + trace!("InstrumentCoverage done for {def_id:?}"); } } struct Instrumentor<'a, 'tcx> { tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>, - source_file: Lrc<SourceFile>, fn_sig_span: Span, body_span: Span, function_source_hash: u64, @@ -96,37 +77,17 @@ struct Instrumentor<'a, 'tcx> { impl<'a, 'tcx> Instrumentor<'a, 'tcx> { fn new(tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self { - let source_map = tcx.sess.source_map(); - let def_id = mir_body.source.def_id(); - let (some_fn_sig, hir_body) = fn_sig_and_body(tcx, def_id); + let hir_info @ ExtractedHirInfo { function_source_hash, fn_sig_span, body_span } = + extract_hir_info(tcx, mir_body.source.def_id().expect_local()); - let body_span = get_body_span(tcx, hir_body, mir_body); + debug!(?hir_info, "instrumenting {:?}", mir_body.source.def_id()); - let source_file = source_map.lookup_source_file(body_span.lo()); - let fn_sig_span = match some_fn_sig.filter(|fn_sig| { - fn_sig.span.eq_ctxt(body_span) - && Lrc::ptr_eq(&source_file, &source_map.lookup_source_file(fn_sig.span.lo())) - }) { - Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()), - None => body_span.shrink_to_lo(), - }; - - debug!( - "instrumenting {}: {:?}, fn sig span: {:?}, body span: {:?}", - if tcx.is_closure(def_id) { "closure" } else { "function" }, - def_id, - fn_sig_span, - body_span - ); - - let function_source_hash = hash_mir_source(tcx, hir_body); let basic_coverage_blocks = CoverageGraph::from_mir(mir_body); let coverage_counters = CoverageCounters::new(&basic_coverage_blocks); Self { tcx, mir_body, - source_file, fn_sig_span, body_span, function_source_hash, @@ -136,15 +97,12 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { } fn inject_counters(&'a mut self) { - let fn_sig_span = self.fn_sig_span; - let body_span = self.body_span; - //////////////////////////////////////////////////// // Compute coverage spans from the `CoverageGraph`. let coverage_spans = CoverageSpans::generate_coverage_spans( self.mir_body, - fn_sig_span, - body_span, + self.fn_sig_span, + self.body_span, &self.basic_coverage_blocks, ); @@ -177,9 +135,10 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let source_map = self.tcx.sess.source_map(); let body_span = self.body_span; + let source_file = source_map.lookup_source_file(body_span.lo()); use rustc_session::RemapFileNameExt; let file_name = - Symbol::intern(&self.source_file.name.for_codegen(self.tcx.sess).to_string_lossy()); + Symbol::intern(&source_file.name.for_codegen(self.tcx.sess).to_string_lossy()); let mut mappings = Vec::new(); @@ -325,27 +284,75 @@ fn make_code_region( } } -fn fn_sig_and_body( - tcx: TyCtxt<'_>, - def_id: DefId, -) -> (Option<&rustc_hir::FnSig<'_>>, &rustc_hir::Body<'_>) { +fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + // Only instrument functions, methods, and closures (not constants since they are evaluated + // at compile time by Miri). + // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const + // expressions get coverage spans, we will probably have to "carve out" space for const + // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might + // be tricky if const expressions have no corresponding statements in the enclosing MIR. + // Closures are carved out by their initial `Assign` statement.) + if !tcx.def_kind(def_id).is_fn_like() { + trace!("InstrumentCoverage skipped for {def_id:?} (not an fn-like)"); + return false; + } + + if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_COVERAGE) { + return false; + } + + true +} + +/// Function information extracted from HIR by the coverage instrumentor. +#[derive(Debug)] +struct ExtractedHirInfo { + function_source_hash: u64, + fn_sig_span: Span, + body_span: Span, +} + +fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHirInfo { // FIXME(#79625): Consider improving MIR to provide the information needed, to avoid going back // to HIR for it. - let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local"); + + let hir_node = tcx.hir_node_by_def_id(def_id); let (_, fn_body_id) = hir::map::associated_body(hir_node).expect("HIR node is a function with body"); - (hir_node.fn_sig(), tcx.hir().body(fn_body_id)) + let hir_body = tcx.hir().body(fn_body_id); + + let body_span = get_body_span(tcx, hir_body, def_id); + + // The actual signature span is only used if it has the same context and + // filename as the body, and precedes the body. + let maybe_fn_sig_span = hir_node.fn_sig().map(|fn_sig| fn_sig.span); + let fn_sig_span = maybe_fn_sig_span + .filter(|&fn_sig_span| { + let source_map = tcx.sess.source_map(); + let file_idx = |span: Span| source_map.lookup_source_file_idx(span.lo()); + + fn_sig_span.eq_ctxt(body_span) + && fn_sig_span.hi() <= body_span.lo() + && file_idx(fn_sig_span) == file_idx(body_span) + }) + // If so, extend it to the start of the body span. + .map(|fn_sig_span| fn_sig_span.with_hi(body_span.lo())) + // Otherwise, create a dummy signature span at the start of the body. + .unwrap_or_else(|| body_span.shrink_to_lo()); + + let function_source_hash = hash_mir_source(tcx, hir_body); + + ExtractedHirInfo { function_source_hash, fn_sig_span, body_span } } fn get_body_span<'tcx>( tcx: TyCtxt<'tcx>, hir_body: &rustc_hir::Body<'tcx>, - mir_body: &mut mir::Body<'tcx>, + def_id: LocalDefId, ) -> Span { let mut body_span = hir_body.value.span; - let def_id = mir_body.source.def_id(); - if tcx.is_closure(def_id) { + if tcx.is_closure(def_id.to_def_id()) { // If the MIR function is a closure, and if the closure body span // starts from a macro, but it's content is not in that macro, try // to find a non-macro callsite, and instrument the spans there diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 261d9dd448d..5f01b841867 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -22,6 +22,18 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return false; } + // This just reproduces the logic from Instance::requires_inline. + match tcx.def_kind(def_id) { + DefKind::Ctor(..) | DefKind::Closure => return true, + DefKind::Fn | DefKind::AssocFn => {} + _ => return false, + } + + // From this point on, it is valid to return true or false. + if tcx.sess.opts.unstable_opts.cross_crate_inline_threshold == InliningThreshold::Always { + return true; + } + // Obey source annotations first; this is important because it means we can use // #[inline(never)] to force code generation. match codegen_fn_attrs.inline { @@ -30,13 +42,6 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { _ => {} } - // This just reproduces the logic from Instance::requires_inline. - match tcx.def_kind(def_id) { - DefKind::Ctor(..) | DefKind::Closure => return true, - DefKind::Fn | DefKind::AssocFn => {} - _ => return false, - } - // Don't do any inference when incremental compilation is enabled; the additional inlining that // inference permits also creates more work for small edits. if tcx.sess.opts.incremental.is_some() { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 146cc33e8c6..ad12bce9b02 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -496,7 +496,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { FlatSet::Elem(scalar) => { let ty = op.ty(self.local_decls, self.tcx); self.tcx.layout_of(self.param_env.and(ty)).map_or(FlatSet::Top, |layout| { - FlatSet::Elem(ImmTy::from_scalar(scalar.into(), layout)) + FlatSet::Elem(ImmTy::from_scalar(scalar, layout)) }) } FlatSet::Bottom => FlatSet::Bottom, diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 2358661738a..928db471298 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -65,7 +65,7 @@ pub(crate) struct RequiresUnsafe { impl<'sess> IntoDiagnostic<'sess> for RequiresUnsafe { #[track_caller] fn into_diagnostic(self, handler: &'sess Handler) -> DiagnosticBuilder<'sess, ErrorGuaranteed> { - let mut diag = handler.struct_diagnostic(fluent::mir_transform_requires_unsafe); + let mut diag = handler.struct_err(fluent::mir_transform_requires_unsafe); diag.code(rustc_errors::DiagnosticId::Error("E0133".to_string())); diag.set_span(self.span); diag.span_label(self.span, self.details.label()); @@ -180,10 +180,7 @@ pub(crate) struct UnsafeOpInUnsafeFn { impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { #[track_caller] - fn decorate_lint<'b>( - self, - diag: &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, ()>) { let handler = diag.handler().expect("lint should not yet be emitted"); let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter()); diag.set_arg("details", desc); @@ -198,8 +195,6 @@ impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { Applicability::MaybeIncorrect, ); } - - diag } fn msg(&self) -> DiagnosticMessage { @@ -213,10 +208,7 @@ pub(crate) enum AssertLint<P> { } impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> { - fn decorate_lint<'b>( - self, - diag: &'b mut DiagnosticBuilder<'a, ()>, - ) -> &'b mut DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, ()>) { let span = self.span(); let assert_kind = self.panic(); let message = assert_kind.diagnostic_message(); @@ -224,8 +216,6 @@ impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> { diag.set_arg(name, value); }); diag.span_label(span, message); - - diag } fn msg(&self) -> DiagnosticMessage { @@ -284,10 +274,7 @@ pub(crate) struct MustNotSupend<'tcx, 'a> { // Needed for def_path_str impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> { - fn decorate_lint<'b>( - self, - diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, - ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) { diag.span_label(self.yield_sp, fluent::_subdiag::label); if let Some(reason) = self.reason { diag.subdiagnostic(reason); @@ -296,7 +283,6 @@ impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> { diag.set_arg("pre", self.pre); diag.set_arg("def_path", self.tcx.def_path_str(self.def_id)); diag.set_arg("post", self.post); - diag } fn msg(&self) -> rustc_errors::DiagnosticMessage { diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 36a15f47276..a41d8e21245 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -649,7 +649,7 @@ impl OpportunitySet { // `succ` must be a successor of `current`. If it is not, this means this TO is not // satisfiable and a previous TO erased this edge, so we bail out. - if basic_blocks[current].terminator().successors().find(|s| *s == succ).is_none() { + if !basic_blocks[current].terminator().successors().any(|s| s == succ) { debug!("impossible"); return; } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 71b3754fac8..feceff10f95 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -176,6 +176,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Location}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; +use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, AssocKind, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, @@ -923,6 +924,21 @@ fn visit_instance_use<'tcx>( return; } + // The intrinsics assert_inhabited, assert_zero_valid, and assert_mem_uninitialized_valid will + // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any + // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to + // codegen a call to that function without generating code for the function itself. + if let ty::InstanceDef::Intrinsic(def_id) = instance.def { + let name = tcx.item_name(def_id); + if let Some(_requirement) = ValidityRequirement::from_intrinsic(name) { + let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap(); + let panic_instance = Instance::mono(tcx, def_id); + if should_codegen_locally(tcx, &panic_instance) { + output.push(create_fn_mono_item(tcx, panic_instance, source)); + } + } + } + match instance.def { ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(_) => { if !is_direct_call { diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index c2b307910e4..d47d3e5e7d3 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -212,11 +212,17 @@ where let cgu_name_cache = &mut FxHashMap::default(); for mono_item in mono_items { - // Handle only root items directly here. Inlined items are handled at - // the bottom of the loop based on reachability. + // Handle only root (GloballyShared) items directly here. Inlined (LocalCopy) items + // are handled at the bottom of the loop based on reachability, with one exception. + // The #[lang = "start"] item is the program entrypoint, so there are no calls to it in MIR. + // So even if its mode is LocalCopy, we need to treat it like a root. match mono_item.instantiation_mode(cx.tcx) { InstantiationMode::GloballyShared { .. } => {} - InstantiationMode::LocalCopy => continue, + InstantiationMode::LocalCopy => { + if Some(mono_item.def_id()) != cx.tcx.lang_items().start_fn() { + continue; + } + } } let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item); @@ -883,7 +889,7 @@ fn mono_item_visibility<'tcx>( } fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility { - if !tcx.sess.target.default_hidden_visibility { + if !tcx.sess.default_hidden_visibility() { return Visibility::Default; } diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index cb1f328577d..ac2e8960b06 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -242,16 +242,10 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> ty::ReVar(vid) => { assert_eq!( - self.infcx.root_lt_var(vid), - vid, - "region vid should have been resolved fully before canonicalization" - ); - assert_eq!( - self.infcx.probe_lt_var(vid), + self.infcx.opportunistic_resolve_lt_var(vid), None, "region vid should have been resolved fully before canonicalization" ); - match self.canonicalize_mode { CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { .. } => { diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index bc53ab83439..c51a5c095ee 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1046,7 +1046,7 @@ impl<'a> IntoDiagnostic<'a> for ExpectedIdentifier { ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { let token_descr = TokenDescription::from_token(&self.token); - let mut diag = handler.struct_diagnostic(match token_descr { + let mut diag = handler.struct_err(match token_descr { Some(TokenDescription::ReservedIdentifier) => { fluent::parse_expected_identifier_found_reserved_identifier_str } @@ -1103,7 +1103,7 @@ impl<'a> IntoDiagnostic<'a> for ExpectedSemi { ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { let token_descr = TokenDescription::from_token(&self.token); - let mut diag = handler.struct_diagnostic(match token_descr { + let mut diag = handler.struct_err(match token_descr { Some(TokenDescription::ReservedIdentifier) => { fluent::parse_expected_semi_found_reserved_identifier_str } diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index bbfb160ebf7..0dc60688955 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -350,8 +350,7 @@ pub(super) fn check_for_substitution( let Some((_, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(s, _, _)| s == ascii_str) else { let msg = format!("substitution character not found for '{ch}'"); - reader.sess.span_diagnostic.span_bug_no_panic(span, msg); - return (None, None); + reader.sess.span_diagnostic.span_bug(span, msg); }; // special help suggestion for "directed" double quotes diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 95352dbdc13..9887a85e6a4 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -51,8 +51,8 @@ macro_rules! panictry_buffer { match $e { Ok(e) => e, Err(errs) => { - for mut e in errs { - $handler.emit_diagnostic(&mut e); + for e in errs { + $handler.emit_diagnostic(e); } FatalError.raise() } @@ -165,8 +165,8 @@ fn try_file_to_source_file( fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) -> Lrc<SourceFile> { match try_file_to_source_file(sess, path, spanopt) { Ok(source_file) => source_file, - Err(mut d) => { - sess.span_diagnostic.emit_diagnostic(&mut d); + Err(d) => { + sess.span_diagnostic.emit_diagnostic(d); FatalError.raise(); } } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 5295172b25e..221fc70d9ff 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -249,8 +249,8 @@ impl<'a> Parser<'a> { self.diagnostic().struct_span_err(sp, m) } - pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: impl Into<String>) -> ! { - self.diagnostic().span_bug(sp, m) + pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! { + self.diagnostic().span_bug(sp, msg) } pub(super) fn diagnostic(&self) -> &'a Handler { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5b0011e9f70..509cef9826b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1440,21 +1440,23 @@ impl<'a> Parser<'a> { } else if this.eat_keyword(kw::Underscore) { Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore)) } else if this.token.uninterpolated_span().at_least_rust_2018() { - // `Span:.at_least_rust_2018()` is somewhat expensive; don't get it repeatedly. - if this.check_keyword(kw::Async) { + // `Span::at_least_rust_2018()` is somewhat expensive; don't get it repeatedly. + if this.token.uninterpolated_span().at_least_rust_2024() + // check for `gen {}` and `gen move {}` + // or `async gen {}` and `async gen move {}` + && (this.is_gen_block(kw::Gen, 0) + || (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1))) + { + // FIXME: (async) gen closures aren't yet parsed. + this.parse_gen_block() + } else if this.check_keyword(kw::Async) { // FIXME(gen_blocks): Parse `gen async` and suggest swap if this.is_gen_block(kw::Async, 0) { // Check for `async {` and `async move {`, - // or `async gen {` and `async gen move {`. this.parse_gen_block() } else { this.parse_expr_closure() } - } else if this.token.uninterpolated_span().at_least_rust_2024() - && (this.is_gen_block(kw::Gen, 0) - || (this.check_keyword(kw::Async) && this.is_gen_block(kw::Gen, 1))) - { - this.parse_gen_block() } else if this.eat_keyword_noexpect(kw::Await) { this.recover_incorrect_await_syntax(lo, this.prev_token.span) } else { @@ -3227,9 +3229,16 @@ impl<'a> Parser<'a> { if self.eat_keyword(kw::Gen) { GenBlockKind::AsyncGen } else { GenBlockKind::Async } } else { assert!(self.eat_keyword(kw::Gen)); - self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.token.span)); GenBlockKind::Gen }; + match kind { + GenBlockKind::Async => { + // `async` blocks are stable + } + GenBlockKind::Gen | GenBlockKind::AsyncGen => { + self.sess.gated_spans.gate(sym::gen_blocks, lo.to(self.prev_token.span)); + } + } let capture_clause = self.parse_capture_clause()?; let (attrs, body) = self.parse_inner_attrs_and_block()?; let kind = ExprKind::Gen(capture_clause, body, kind); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 89919247e82..fd7dad36c9d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -923,7 +923,7 @@ impl<'a> Parser<'a> { ); let where_predicates_split = before_where_clause.predicates.len(); let mut predicates = before_where_clause.predicates; - predicates.extend(after_where_clause.predicates.into_iter()); + predicates.extend(after_where_clause.predicates); let where_clause = WhereClause { has_where_token: before_where_clause.has_where_token || after_where_clause.has_where_token, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 81055431f64..d10c8c92257 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -215,7 +215,7 @@ fn emit_malformed_attribute( } else { "the following are the possible correct uses" }, - suggestions.into_iter(), + suggestions, Applicability::HasPlaceholders, ) .emit(); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4910d63010c..c5073048be3 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -604,7 +604,7 @@ impl CheckAttrVisitor<'_> { && !self.tcx.sess.target.is_like_wasm && !self.tcx.sess.opts.actually_rustdoc { - let hir::Node::Item(item) = self.tcx.hir().get(hir_id) else { + let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else { unreachable!(); }; let hir::ItemKind::Fn(sig, _, _) = item.kind else { @@ -820,7 +820,7 @@ impl CheckAttrVisitor<'_> { self.doc_attr_str_error(meta, "keyword"); return false; } - match self.tcx.hir().find(hir_id).and_then(|node| match node { + match self.tcx.opt_hir_node(hir_id).and_then(|node| match node { hir::Node::Item(item) => Some(&item.kind), _ => None, }) { @@ -846,7 +846,7 @@ impl CheckAttrVisitor<'_> { } fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool { - match self.tcx.hir().find(hir_id).and_then(|node| match node { + match self.tcx.opt_hir_node(hir_id).and_then(|node| match node { hir::Node::Item(item) => Some(&item.kind), _ => None, }) { @@ -1387,7 +1387,7 @@ impl CheckAttrVisitor<'_> { /// Checks if `#[link]` is applied to an item other than a foreign module. fn check_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { if target == Target::ForeignMod - && let hir::Node::Item(item) = self.tcx.hir().get(hir_id) + && let hir::Node::Item(item) = self.tcx.hir_node(hir_id) && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item && !matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) { @@ -1456,7 +1456,7 @@ impl CheckAttrVisitor<'_> { } fn is_impl_item(&self, hir_id: HirId) -> bool { - matches!(self.tcx.hir().get(hir_id), hir::Node::ImplItem(..)) + matches!(self.tcx.hir_node(hir_id), hir::Node::ImplItem(..)) } /// Checks if `#[export_name]` is applied to a function or static. Returns `true` if valid. @@ -2074,7 +2074,7 @@ impl CheckAttrVisitor<'_> { && let hir::Node::Item(Item { kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. }, .. - }) = hir.get(parent) + }) = self.tcx.hir_node(parent) { return true; } @@ -2222,7 +2222,7 @@ impl CheckAttrVisitor<'_> { } else { // special case when `#[macro_export]` is applied to a macro 2.0 let (macro_definition, _) = - self.tcx.hir().find(hir_id).unwrap().expect_item().expect_macro(); + self.tcx.opt_hir_node(hir_id).unwrap().expect_item().expect_macro(); let is_decl_macro = !macro_definition.macro_rules; if is_decl_macro { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 7d1cc81e21f..d270794978b 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -32,7 +32,7 @@ use crate::errors::{ // may need to be marked as live. fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { matches!( - tcx.hir().find_by_def_id(def_id), + tcx.opt_hir_node_by_def_id(def_id), Some( Node::Item(..) | Node::ImplItem(..) @@ -297,7 +297,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { // tuple struct constructor function let id = self.struct_constructors.get(&id).copied().unwrap_or(id); - if let Some(node) = self.tcx.hir().find_by_def_id(id) { + if let Some(node) = self.tcx.opt_hir_node_by_def_id(id) { // When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement // by declaring fn calls, statics, ... within said items as live, as well as // the item itself, although technically this is not the case. diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index d8b9f4fae87..5f767c9acaa 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -83,6 +83,9 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems { // Collect diagnostic items in other crates. for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) { + // We are collecting many DiagnosticItems hash maps into one + // DiagnosticItems hash map. The iteration order does not matter. + #[allow(rustc::potential_query_instability)] for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id { collect_item(tcx, &mut items, name, def_id); } diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 2629b281756..7667fc21eee 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -126,7 +126,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, { // non-local main imports are handled below if let Some(def_id) = def_id.as_local() - && matches!(tcx.hir().find_by_def_id(def_id), Some(Node::ForeignItem(_))) + && matches!(tcx.opt_hir_node_by_def_id(def_id), Some(Node::ForeignItem(_))) { tcx.sess.emit_err(ExternMain { span: tcx.def_span(def_id) }); return None; diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 28354ab0986..c2392620cb2 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -121,6 +121,8 @@ impl<'k> StatCollector<'k> { } fn print(&self, title: &str, prefix: &str) { + // We will soon sort, so the initial order does not matter. + #[allow(rustc::potential_query_instability)] let mut nodes: Vec<_> = self.nodes.iter().collect(); nodes.sort_by_key(|(_, node)| node.stats.count * node.stats.size); @@ -147,6 +149,8 @@ impl<'k> StatCollector<'k> { to_readable_str(node.stats.size) ); if !node.subnodes.is_empty() { + // We will soon sort, so the initial order does not matter. + #[allow(rustc::potential_query_instability)] let mut subnodes: Vec<_> = node.subnodes.iter().collect(); subnodes.sort_by_key(|(_, subnode)| subnode.count * subnode.size); @@ -425,7 +429,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) { record_variants!( (self, b, b, Id::None, hir, GenericBound, GenericBound), - [Trait, LangItemTrait, Outlives] + [Trait, Outlives] ); hir_visit::walk_param_bound(self, b) } diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index d0b782ba4ca..6d14a14096d 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -7,18 +7,18 @@ //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`. //! * Functions called by the compiler itself. -use crate::check_attr::target_from_impl_item; use crate::errors::{ DuplicateLangItem, IncorrectTarget, LangItemOnIncorrectTarget, UnknownLangItem, }; use crate::weak_lang_items; -use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_ast as ast; +use rustc_ast::visit; +use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::{extract, GenericRequirement}; -use rustc_hir::{LangItem, LanguageItems, Target}; -use rustc_middle::ty::TyCtxt; +use rustc_hir::{LangItem, LanguageItems, MethodKind, Target}; +use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_session::cstore::ExternCrate; use rustc_span::symbol::kw::Empty; use rustc_span::Span; @@ -31,28 +31,55 @@ pub(crate) enum Duplicate { CrateDepends, } -struct LanguageItemCollector<'tcx> { +struct LanguageItemCollector<'ast, 'tcx> { items: LanguageItems, tcx: TyCtxt<'tcx>, + resolver: &'ast ResolverAstLowering, + // FIXME(#118552): We should probably feed def_span eagerly on def-id creation + // so we can avoid constructing this map for local def-ids. + item_spans: FxHashMap<DefId, Span>, + parent_item: Option<&'ast ast::Item>, } -impl<'tcx> LanguageItemCollector<'tcx> { - fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> { - LanguageItemCollector { tcx, items: LanguageItems::new() } +impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { + fn new( + tcx: TyCtxt<'tcx>, + resolver: &'ast ResolverAstLowering, + ) -> LanguageItemCollector<'ast, 'tcx> { + LanguageItemCollector { + tcx, + resolver, + items: LanguageItems::new(), + item_spans: FxHashMap::default(), + parent_item: None, + } } - fn check_for_lang(&mut self, actual_target: Target, def_id: LocalDefId) { - let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); - if let Some((name, span)) = extract(attrs) { + fn check_for_lang( + &mut self, + actual_target: Target, + def_id: LocalDefId, + attrs: &'ast [ast::Attribute], + item_span: Span, + generics: Option<&'ast ast::Generics>, + ) { + if let Some((name, attr_span)) = extract(attrs) { match LangItem::from_name(name) { // Known lang item with attribute on correct target. Some(lang_item) if actual_target == lang_item.target() => { - self.collect_item_extended(lang_item, def_id, span); + self.collect_item_extended( + lang_item, + def_id, + item_span, + attr_span, + generics, + actual_target, + ); } // Known lang item with attribute on incorrect target. Some(lang_item) => { self.tcx.sess.emit_err(LangItemOnIncorrectTarget { - span, + span: attr_span, name, expected_target: lang_item.target(), actual_target, @@ -60,127 +87,131 @@ impl<'tcx> LanguageItemCollector<'tcx> { } // Unknown lang item. _ => { - self.tcx.sess.emit_err(UnknownLangItem { span, name }); + self.tcx.sess.emit_err(UnknownLangItem { span: attr_span, name }); } } } } - fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId) { + fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId, item_span: Option<Span>) { // Check for duplicates. - if let Some(original_def_id) = self.items.get(lang_item) { - if original_def_id != item_def_id { - let local_span = self.tcx.hir().span_if_local(item_def_id); - let lang_item_name = lang_item.name(); - let crate_name = self.tcx.crate_name(item_def_id.krate); - let mut dependency_of = Empty; - let is_local = item_def_id.is_local(); - let path = if is_local { - String::new() - } else { - self.tcx - .crate_extern_paths(item_def_id.krate) - .iter() - .map(|p| p.display().to_string()) - .collect::<Vec<_>>() - .join(", ") - }; - let first_defined_span = self.tcx.hir().span_if_local(original_def_id); - let mut orig_crate_name = Empty; - let mut orig_dependency_of = Empty; - let orig_is_local = original_def_id.is_local(); - let orig_path = if orig_is_local { - String::new() - } else { - self.tcx - .crate_extern_paths(original_def_id.krate) - .iter() - .map(|p| p.display().to_string()) - .collect::<Vec<_>>() - .join(", ") - }; - if first_defined_span.is_none() { - orig_crate_name = self.tcx.crate_name(original_def_id.krate); - if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) = - self.tcx.extern_crate(original_def_id) - { - orig_dependency_of = self.tcx.crate_name(*inner_dependency_of); - } + if let Some(original_def_id) = self.items.get(lang_item) + && original_def_id != item_def_id + { + let lang_item_name = lang_item.name(); + let crate_name = self.tcx.crate_name(item_def_id.krate); + let mut dependency_of = Empty; + let is_local = item_def_id.is_local(); + let path = if is_local { + String::new() + } else { + self.tcx + .crate_extern_paths(item_def_id.krate) + .iter() + .map(|p| p.display().to_string()) + .collect::<Vec<_>>() + .join(", ") + }; + + let first_defined_span = self.item_spans.get(&original_def_id).copied(); + let mut orig_crate_name = Empty; + let mut orig_dependency_of = Empty; + let orig_is_local = original_def_id.is_local(); + let orig_path = if orig_is_local { + String::new() + } else { + self.tcx + .crate_extern_paths(original_def_id.krate) + .iter() + .map(|p| p.display().to_string()) + .collect::<Vec<_>>() + .join(", ") + }; + + if first_defined_span.is_none() { + orig_crate_name = self.tcx.crate_name(original_def_id.krate); + if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) = + self.tcx.extern_crate(original_def_id) + { + orig_dependency_of = self.tcx.crate_name(*inner_dependency_of); } + } - let duplicate = if local_span.is_some() { - Duplicate::Plain - } else { - match self.tcx.extern_crate(item_def_id) { - Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => { - dependency_of = self.tcx.crate_name(*inner_dependency_of); - Duplicate::CrateDepends - } - _ => Duplicate::Crate, + let duplicate = if item_span.is_some() { + Duplicate::Plain + } else { + match self.tcx.extern_crate(item_def_id) { + Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => { + dependency_of = self.tcx.crate_name(*inner_dependency_of); + Duplicate::CrateDepends } - }; - - self.tcx.sess.emit_err(DuplicateLangItem { - local_span, - lang_item_name, - crate_name, - dependency_of, - is_local, - path, - first_defined_span, - orig_crate_name, - orig_dependency_of, - orig_is_local, - orig_path, - duplicate, - }); + _ => Duplicate::Crate, + } + }; + + self.tcx.sess.emit_err(DuplicateLangItem { + local_span: item_span, + lang_item_name, + crate_name, + dependency_of, + is_local, + path, + first_defined_span, + orig_crate_name, + orig_dependency_of, + orig_is_local, + orig_path, + duplicate, + }); + } else { + // Matched. + self.items.set(lang_item, item_def_id); + // Collect span for error later + if let Some(item_span) = item_span { + self.item_spans.insert(item_def_id, item_span); } } - - // Matched. - self.items.set(lang_item, item_def_id); } // Like collect_item() above, but also checks whether the lang item is declared // with the right number of generic arguments. - fn collect_item_extended(&mut self, lang_item: LangItem, item_def_id: LocalDefId, span: Span) { + fn collect_item_extended( + &mut self, + lang_item: LangItem, + item_def_id: LocalDefId, + item_span: Span, + attr_span: Span, + generics: Option<&'ast ast::Generics>, + target: Target, + ) { let name = lang_item.name(); - // Now check whether the lang_item has the expected number of generic - // arguments. Generally speaking, binary and indexing operations have - // one (for the RHS/index), unary operations have none, the closure - // traits have one for the argument list, coroutines have one for the - // resume argument, and ordering/equality relations have one for the RHS - // Some other types like Box and various functions like drop_in_place - // have minimum requirements. + if let Some(generics) = generics { + // Now check whether the lang_item has the expected number of generic + // arguments. Generally speaking, binary and indexing operations have + // one (for the RHS/index), unary operations have none, the closure + // traits have one for the argument list, coroutines have one for the + // resume argument, and ordering/equality relations have one for the RHS + // Some other types like Box and various functions like drop_in_place + // have minimum requirements. - if let hir::Node::Item(hir::Item { kind, span: item_span, .. }) = - self.tcx.hir().get_by_def_id(item_def_id) - { - let (actual_num, generics_span) = match kind.generics() { - Some(generics) => ( - generics - .params - .iter() - .filter(|p| { - !matches!( - p.kind, - hir::GenericParamKind::Const { is_host_effect: true, .. } - ) - }) - .count(), - generics.span, - ), - None => (0, *item_span), - }; + // FIXME: This still doesn't count, e.g., elided lifetimes and APITs. + let mut actual_num = generics.params.len(); + if target.is_associated_item() { + actual_num += self + .parent_item + .unwrap() + .opt_generics() + .map_or(0, |generics| generics.params.len()); + } let mut at_least = false; let required = match lang_item.required_generics() { GenericRequirement::Exact(num) if num != actual_num => Some(num), GenericRequirement::Minimum(num) if actual_num < num => { at_least = true; - Some(num)} - , + Some(num) + } // If the number matches, or there is no requirement, handle it normally _ => None, }; @@ -190,10 +221,10 @@ impl<'tcx> LanguageItemCollector<'tcx> { // item kind of the target is correct, the target is still wrong // because of the wrong number of generic arguments. self.tcx.sess.emit_err(IncorrectTarget { - span, - generics_span, + span: attr_span, + generics_span: generics.span, name: name.as_str(), - kind: kind.descr(), + kind: target.name(), num, actual_num, at_least, @@ -204,58 +235,117 @@ impl<'tcx> LanguageItemCollector<'tcx> { } } - self.collect_item(lang_item, item_def_id.to_def_id()); + self.collect_item(lang_item, item_def_id.to_def_id(), Some(item_span)); } } /// Traverses and collects all the lang items in all crates. fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { + let resolver = tcx.resolver_for_lowering(()).borrow(); + let (resolver, krate) = &*resolver; + // Initialize the collector. - let mut collector = LanguageItemCollector::new(tcx); + let mut collector = LanguageItemCollector::new(tcx, resolver); // Collect lang items in other crates. for &cnum in tcx.crates(()).iter() { for &(def_id, lang_item) in tcx.defined_lang_items(cnum).iter() { - collector.collect_item(lang_item, def_id); + collector.collect_item(lang_item, def_id, None); } } - // Collect lang items in this crate. - let crate_items = tcx.hir_crate_items(()); + // Collect lang items local to this crate. + visit::Visitor::visit_crate(&mut collector, krate); - for id in crate_items.items() { - collector - .check_for_lang(Target::from_def_kind(tcx.def_kind(id.owner_id)), id.owner_id.def_id); + // Find all required but not-yet-defined lang items. + weak_lang_items::check_crate(tcx, &mut collector.items, krate); - if matches!(tcx.def_kind(id.owner_id), DefKind::Enum) { - let item = tcx.hir().item(id); - if let hir::ItemKind::Enum(def, ..) = &item.kind { - for variant in def.variants { - collector.check_for_lang(Target::Variant, variant.def_id); - } - } - } - } + // Return all the lang items that were found. + collector.items +} + +impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { + fn visit_item(&mut self, i: &'ast ast::Item) { + let target = match &i.kind { + ast::ItemKind::ExternCrate(_) => Target::ExternCrate, + ast::ItemKind::Use(_) => Target::Use, + ast::ItemKind::Static(_) => Target::Static, + ast::ItemKind::Const(_) => Target::Const, + ast::ItemKind::Fn(_) => Target::Fn, + ast::ItemKind::Mod(_, _) => Target::Mod, + ast::ItemKind::ForeignMod(_) => Target::ForeignFn, + ast::ItemKind::GlobalAsm(_) => Target::GlobalAsm, + ast::ItemKind::TyAlias(_) => Target::TyAlias, + ast::ItemKind::Enum(_, _) => Target::Enum, + ast::ItemKind::Struct(_, _) => Target::Struct, + ast::ItemKind::Union(_, _) => Target::Union, + ast::ItemKind::Trait(_) => Target::Trait, + ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias, + ast::ItemKind::Impl(_) => Target::Impl, + ast::ItemKind::MacroDef(_) => Target::MacroDef, + ast::ItemKind::MacCall(_) => unreachable!("macros should have been expanded"), + }; - // FIXME: avoid calling trait_item() when possible - for id in crate_items.trait_items() { - let item = tcx.hir().trait_item(id); - collector.check_for_lang(Target::from_trait_item(item), item.owner_id.def_id) + self.check_for_lang( + target, + self.resolver.node_id_to_def_id[&i.id], + &i.attrs, + i.span, + i.opt_generics(), + ); + + let parent_item = self.parent_item.replace(i); + visit::walk_item(self, i); + self.parent_item = parent_item; } - // FIXME: avoid calling impl_item() when possible - for id in crate_items.impl_items() { - let item = tcx.hir().impl_item(id); - collector.check_for_lang(target_from_impl_item(tcx, item), item.owner_id.def_id) + fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef) { + for variant in &enum_definition.variants { + self.check_for_lang( + Target::Variant, + self.resolver.node_id_to_def_id[&variant.id], + &variant.attrs, + variant.span, + None, + ); + } + + visit::walk_enum_def(self, enum_definition); } - // Extract out the found lang items. - let LanguageItemCollector { mut items, .. } = collector; + fn visit_assoc_item(&mut self, i: &'ast ast::AssocItem, ctxt: visit::AssocCtxt) { + let (target, generics) = match &i.kind { + ast::AssocItemKind::Fn(fun) => ( + match &self.parent_item.unwrap().kind { + ast::ItemKind::Impl(i) => { + if i.of_trait.is_some() { + Target::Method(MethodKind::Trait { body: fun.body.is_some() }) + } else { + Target::Method(MethodKind::Inherent) + } + } + ast::ItemKind::Trait(_) => { + Target::Method(MethodKind::Trait { body: fun.body.is_some() }) + } + _ => unreachable!(), + }, + &fun.generics, + ), + ast::AssocItemKind::Const(ct) => (Target::AssocConst, &ct.generics), + ast::AssocItemKind::Type(ty) => (Target::AssocTy, &ty.generics), + ast::AssocItemKind::MacCall(_) => unreachable!("macros should have been expanded"), + }; - // Find all required but not-yet-defined lang items. - weak_lang_items::check_crate(tcx, &mut items); + self.check_for_lang( + target, + self.resolver.node_id_to_def_id[&i.id], + &i.attrs, + i.span, + Some(generics), + ); - items + visit::walk_assoc_item(self, i, ctxt); + } } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 4c4d5e58232..c969867e871 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -4,7 +4,6 @@ //! //! This API is completely unstable and subject to change. -#![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(rustdoc_internals)] diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 8e6d5805275..bfaf4a5a957 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -4,7 +4,6 @@ use rustc_hir as hir; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Destination, Movability, Node}; -use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; @@ -30,16 +29,16 @@ enum Context { } #[derive(Copy, Clone)] -struct CheckLoopVisitor<'a, 'hir> { +struct CheckLoopVisitor<'a, 'tcx> { sess: &'a Session, - hir_map: Map<'hir>, + tcx: TyCtxt<'tcx>, cx: Context, } fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { tcx.hir().visit_item_likes_in_module( module_def_id, - &mut CheckLoopVisitor { sess: tcx.sess, hir_map: tcx.hir(), cx: Normal }, + &mut CheckLoopVisitor { sess: tcx.sess, tcx, cx: Normal }, ); } @@ -51,7 +50,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { type NestedFilter = nested_filter::OnlyBodies; fn nested_visit_map(&mut self) -> Self::Map { - self.hir_map + self.tcx.hir() } fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) { @@ -136,13 +135,13 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { Err(hir::LoopIdError::UnresolvedLabel) => None, }; - if let Some(Node::Block(_)) = loop_id.and_then(|id| self.hir_map.find(id)) { + if let Some(Node::Block(_)) = loop_id.and_then(|id| self.tcx.opt_hir_node(id)) { return; } if let Some(break_expr) = opt_expr { let (head, loop_label, loop_kind) = if let Some(loop_id) = loop_id { - match self.hir_map.expect_expr(loop_id).kind { + match self.tcx.hir().expect_expr(loop_id).kind { hir::ExprKind::Loop(_, label, source, sp) => { (Some(sp), label, Some(source)) } @@ -188,7 +187,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { match destination.target_id { Ok(loop_id) => { - if let Node::Block(block) = self.hir_map.find(loop_id).unwrap() { + if let Node::Block(block) = self.tcx.opt_hir_node(loop_id).unwrap() { self.sess.emit_err(ContinueLabeledBlock { span: e.span, block_span: block.span, diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index bd73fa78442..25637f935fb 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -35,7 +35,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { continue; } - let (fn_header, body_id) = match tcx.hir().get_by_def_id(def_id) { + let (fn_header, body_id) = match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) | hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index f89c1b0e47c..f46f831ddd7 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -115,7 +115,7 @@ impl<'tcx> ReachableContext<'tcx> { return false; }; - match self.tcx.hir().find_by_def_id(def_id) { + match self.tcx.opt_hir_node_by_def_id(def_id) { Some(Node::Item(item)) => match item.kind { hir::ItemKind::Fn(..) => item_might_be_inlined(self.tcx, def_id.into()), _ => false, @@ -146,7 +146,7 @@ impl<'tcx> ReachableContext<'tcx> { continue; } - if let Some(ref item) = self.tcx.hir().find_by_def_id(search_item) { + if let Some(ref item) = self.tcx.opt_hir_node_by_def_id(search_item) { self.propagate_node(item, search_item); } } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 26bd52f55d4..676622cef45 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -1048,6 +1048,9 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { tcx.sess.emit_err(errors::UnknownFeature { span, feature: *feature }); } + // We only use the hash map contents to emit errors, and the order of + // emitted errors do not affect query stability. + #[allow(rustc::potential_query_instability)] for (implied_by, feature) in remaining_implications { let local_defined_features = tcx.lib_features(LOCAL_CRATE); let span = local_defined_features diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 9a6fb88c281..b226c65e96c 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -1,5 +1,7 @@ //! Validity checking for weak lang items +use rustc_ast as ast; +use rustc_ast::visit; use rustc_data_structures::fx::FxHashSet; use rustc_hir::lang_items::{self, LangItem}; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; @@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem} /// Checks the crate for usage of weak lang items, returning a vector of all the /// language items required by this crate, but not defined yet. -pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) { +pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) { // These are never called by user code, they're generated by the compiler. // They will never implicitly be added to the `missing` array unless we do // so here. @@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) { items.missing.push(LangItem::EhCatchTypeinfo); } - let crate_items = tcx.hir_crate_items(()); - for id in crate_items.foreign_items() { - let attrs = tcx.hir().attrs(id.hir_id()); - if let Some((lang_item, _)) = lang_items::extract(attrs) { + visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate); + + verify(tcx, items); +} + +struct WeakLangItemVisitor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + items: &'a mut lang_items::LanguageItems, +} + +impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> { + fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) { + if let Some((lang_item, _)) = lang_items::extract(&i.attrs) { if let Some(item) = LangItem::from_name(lang_item) && item.is_weak() { - if items.get(item).is_none() { - items.missing.push(item); + if self.items.get(item).is_none() { + self.items.missing.push(item); } } else { - let span = tcx.def_span(id.owner_id); - tcx.sess.emit_err(UnknownExternLangItem { span, lang_item }); + self.tcx.sess.emit_err(UnknownExternLangItem { span: i.span, lang_item }); } } } - - verify(tcx, items); } fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) { diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index 716ccdd4dcd..6486ad8b483 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -923,7 +923,7 @@ impl ConstructorSet { } ConstructorSet::Integers { range_1, range_2 } => { let seen_ranges: Vec<_> = - seen.iter().map(|ctor| ctor.as_int_range().unwrap().clone()).collect(); + seen.iter().map(|ctor| *ctor.as_int_range().unwrap()).collect(); for (seen, splitted_range) in range_1.split(seen_ranges.iter().cloned()) { match seen { Presence::Unseen => missing.push(IntRange(splitted_range)), @@ -979,7 +979,8 @@ impl ConstructorSet { && !(pcx.is_top_level && matches!(self, Self::NoConstructors)) { // Treat all missing constructors as nonempty. - missing.extend(missing_empty.drain(..)); + // This clears `missing_empty`. + missing.append(&mut missing_empty); } SplitConstructorSet { present, missing, missing_empty } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e49282e638a..6a8e23d9a8f 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1783,7 +1783,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility { Some(vis) => *vis, None => { let hir_id = tcx.local_def_id_to_hir_id(def_id); - match tcx.hir().get(hir_id) { + match tcx.hir_node(hir_id) { // Unique types created for closures participate in type privacy checking. // They have visibilities inherited from the module they are defined in. Node::Expr(hir::Expr { kind: hir::ExprKind::Closure{..}, .. }) @@ -1800,7 +1800,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility { // Visibilities of trait impl items are inherited from their traits // and are not filled in resolve. Node::ImplItem(impl_item) => { - match tcx.hir().get_by_def_id(tcx.hir().get_parent_item(hir_id).def_id) { + match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(hir_id).def_id) { Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }), .. diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index bc09972185a..3b8ccb67bbe 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -926,8 +926,8 @@ impl<D: Deps> DepGraphData<D> { let handle = qcx.dep_context().sess().diagnostic(); - for mut diagnostic in side_effects.diagnostics { - handle.emit_diagnostic(&mut diagnostic); + for diagnostic in side_effects.diagnostics { + handle.emit_diagnostic(diagnostic); } } } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index a70f4138cfb..504763f6cdb 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -70,7 +70,7 @@ const DEP_NODE_PAD: usize = DEP_NODE_SIZE - 1; const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2; /// Data for use when recompiling the **current crate**. -#[derive(Debug)] +#[derive(Debug, Default)] pub struct SerializedDepGraph { /// The set of all DepNodes in the graph nodes: IndexVec<SerializedDepNodeIndex, DepNode>, @@ -89,18 +89,6 @@ pub struct SerializedDepGraph { index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>, } -impl Default for SerializedDepGraph { - fn default() -> Self { - SerializedDepGraph { - nodes: Default::default(), - fingerprints: Default::default(), - edge_list_indices: Default::default(), - edge_list_data: Default::default(), - index: Default::default(), - } - } -} - impl SerializedDepGraph { #[inline] pub fn edge_targets_from( diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index e601ceaa50c..39e82da6d9d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1063,12 +1063,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { initial_binding.res() }); let res = binding.res(); - let has_ambiguity_error = this - .ambiguity_errors - .iter() - .filter(|error| !error.warning) - .next() - .is_some(); + let has_ambiguity_error = + this.ambiguity_errors.iter().any(|error| !error.warning); if res == Res::Err || has_ambiguity_error { this.tcx .sess diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 61c7846ea61..d767ed74139 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1829,13 +1829,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ) .iter() .filter_map(|candidate| candidate.did) - .filter(|did| { + .find(|did| { self.r .tcx .get_attrs(*did, sym::rustc_diagnostic_item) .any(|attr| attr.value_str() == Some(sym::Default)) - }) - .next(); + }); let Some(default_trait) = default_trait else { return; }; @@ -1880,11 +1879,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }; fields.is_some_and(|fields| { - fields - .iter() - .filter(|vis| !self.r.is_accessible_from(**vis, self.parent_scope.module)) - .next() - .is_some() + fields.iter().any(|vis| !self.r.is_accessible_from(*vis, self.parent_scope.module)) }) } @@ -2178,7 +2173,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { let (span, text) = match path.segments.first() { Some(seg) if let Some(name) = seg.ident.as_str().strip_prefix("let") => { // a special case for #117894 - let name = name.strip_prefix("_").unwrap_or(name); + let name = name.strip_prefix('_').unwrap_or(name); (ident_span, format!("let {name}")) } _ => (ident_span.shrink_to_lo(), "let ".to_string()), diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index f95c0acd750..4ff4ccf5e98 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -407,8 +407,7 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> { doc, main_body_opts(), Some(&mut broken_link_callback), - ) - .into_iter(); + ); let mut links = Vec::new(); while let Some(event) = event_iter.next() { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8dc9a29c2ad..20d18fa4b83 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -755,13 +755,14 @@ pub enum PrintKind { } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum TraitSolver { - /// Classic trait solver in `rustc_trait_selection::traits::select` - Classic, - /// Experimental trait solver in `rustc_trait_selection::solve` - Next, - /// Use the new trait solver during coherence - NextCoherence, +pub struct NextSolverConfig { + /// Whether the new trait solver should be enabled in coherence. + pub coherence: bool, + /// Whether the new trait solver should be enabled everywhere. + /// This is only `true` if `coherence` is also enabled. + pub globally: bool, + /// Whether to dump proof trees after computing a proof tree. + pub dump_tree: DumpSolverProofTree, } #[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -1485,10 +1486,12 @@ impl CheckCfg { ins!(sym::sanitizer_cfi_generalize_pointers, no_values); ins!(sym::sanitizer_cfi_normalize_integers, no_values); - // rustc_codegen_ssa has a list of known target features and their - // stability, but we should allow any target feature as a new target or - // rustc version may introduce new target features. - ins!(sym::target_feature, || ExpectedValues::Any); + ins!(sym::target_feature, empty_values).extend( + rustc_target::target_features::all_known_features() + .map(|(f, _sb)| f) + .chain(rustc_target::target_features::RUSTC_SPECIFIC_FEATURES.iter().cloned()) + .map(Symbol::intern), + ); // sym::target_* { @@ -1576,7 +1579,7 @@ impl CheckCfg { pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg { // Combine the configuration requested by the session (command line) with // some default and generated configuration items. - user_cfg.extend(default_configuration(sess).into_iter()); + user_cfg.extend(default_configuration(sess)); user_cfg } @@ -3220,10 +3223,10 @@ pub(crate) mod dep_tracking { use super::{ BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, - LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, - OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, - SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths, - WasiExecModel, + LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel, + OutFileName, OutputType, OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, + SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, + TrimmedDefPaths, WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3326,7 +3329,7 @@ pub(crate) mod dep_tracking { BranchProtection, OomStrategy, LanguageIdentifier, - TraitSolver, + NextSolverConfig, Polonius, InliningThreshold, FunctionReturn, diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 7eed59709c8..aab7595ef6e 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -19,7 +19,7 @@ impl<'a> IntoDiagnostic<'a> for FeatureGateError { self, handler: &'a rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { - let mut diag = handler.struct_diagnostic(self.explain); + let mut diag = handler.struct_err(self.explain); diag.set_span(self.span); diag.code(error_code!(E0658)); diag diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d666c5d4d70..e8ca556aa42 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -396,8 +396,7 @@ mod desc { pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; - pub const parse_trait_solver: &str = - "one of the supported solver modes (`classic`, `next`, or `next-coherence`)"; + pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error"; pub const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = @@ -429,7 +428,6 @@ mod desc { "a `,` separated combination of `bti`, `b-key`, `pac-ret`, or `leaf`"; pub const parse_proc_macro_execution_strategy: &str = "one of supported execution strategies (`same-thread`, or `cross-thread`)"; - pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`"; pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`"; pub const parse_inlining_threshold: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number"; @@ -1032,15 +1030,48 @@ mod parse { } } - pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool { - match v { - Some("classic") => *slot = TraitSolver::Classic, - Some("next") => *slot = TraitSolver::Next, - Some("next-coherence") => *slot = TraitSolver::NextCoherence, - // default trait solver is subject to change.. - Some("default") => *slot = TraitSolver::Classic, - _ => return false, + pub(crate) fn parse_next_solver_config( + slot: &mut Option<NextSolverConfig>, + v: Option<&str>, + ) -> bool { + if let Some(config) = v { + let mut coherence = false; + let mut globally = true; + let mut dump_tree = None; + for c in config.split(',') { + match c { + "globally" => globally = true, + "coherence" => { + globally = false; + coherence = true; + } + "dump-tree" => { + if dump_tree.replace(DumpSolverProofTree::Always).is_some() { + return false; + } + } + "dump-tree-on-error" => { + if dump_tree.replace(DumpSolverProofTree::OnError).is_some() { + return false; + } + } + _ => return false, + } + } + + *slot = Some(NextSolverConfig { + coherence: coherence || globally, + globally, + dump_tree: dump_tree.unwrap_or_default(), + }); + } else { + *slot = Some(NextSolverConfig { + coherence: true, + globally: true, + dump_tree: Default::default(), + }); } + true } @@ -1305,19 +1336,6 @@ mod parse { true } - pub(crate) fn parse_dump_solver_proof_tree( - slot: &mut DumpSolverProofTree, - v: Option<&str>, - ) -> bool { - match v { - None | Some("always") => *slot = DumpSolverProofTree::Always, - Some("never") => *slot = DumpSolverProofTree::Never, - Some("on-error") => *slot = DumpSolverProofTree::OnError, - _ => return false, - }; - true - } - pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool { match v { Some("always" | "yes") => { @@ -1552,6 +1570,8 @@ options! { "compress debug info sections (none, zlib, zstd, default: none)"), deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED], "deduplicate identical diagnostics (default: yes)"), + default_hidden_visibility: Option<bool> = (None, parse_opt_bool, [TRACKED], + "overrides the `default_hidden_visibility` setting of the target"), dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], "in dep-info output, omit targets for tracking dependencies of the dep-info files \ themselves (default: no)"), @@ -1589,9 +1609,6 @@ options! { "output statistics about monomorphization collection"), dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED], "the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"), - dump_solver_proof_tree: DumpSolverProofTree = (DumpSolverProofTree::Never, parse_dump_solver_proof_tree, [UNTRACKED], - "dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it - then it defaults to `always`. If the flag is not specified at all it defaults to `on-request`."), dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED], "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"), dylib_lto: bool = (false, parse_bool, [UNTRACKED], @@ -1720,6 +1737,8 @@ options! { "the size at which the `large_assignments` lint starts to be emitted"), mutable_noalias: bool = (true, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: yes)"), + next_solver: Option<NextSolverConfig> = (None, parse_next_solver_config, [TRACKED], + "enable and configure the next generation trait solver used by rustc"), nll_facts: bool = (false, parse_bool, [UNTRACKED], "dump facts from NLL analysis into side files (default: no)"), nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED], @@ -1920,8 +1939,6 @@ written to standard error output)"), "for every macro invocation, print its name and arguments (default: no)"), track_diagnostics: bool = (false, parse_bool, [UNTRACKED], "tracks where in rustc a diagnostic was emitted"), - trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED], - "specify the trait solver mode used by rustc (default: classic)"), // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 881e1de6755..525f00f5cd0 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -14,7 +14,7 @@ use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, Handler}; use rustc_errors::{ fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, - EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey, + ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -390,13 +390,4 @@ impl ParseSess { pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> { self.span_diagnostic.struct_fatal(msg) } - - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_diagnostic<G: EmissionGuarantee>( - &self, - msg: impl Into<DiagnosticMessage>, - ) -> DiagnosticBuilder<'_, G> { - self.span_diagnostic.struct_diagnostic(msg) - } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 24c7459392a..08a9b3d9fa0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -632,7 +632,7 @@ impl Session { pub fn span_delayed_bug<S: Into<MultiSpan>>( &self, sp: S, - msg: impl Into<String>, + msg: impl Into<DiagnosticMessage>, ) -> ErrorGuaranteed { self.diagnostic().span_delayed_bug(sp, msg) } @@ -961,6 +961,14 @@ impl Session { termize::dimensions().map_or(default_column_width, |(w, _)| w) } } + + /// Whether the default visibility of symbols should be "hidden" rather than "default". + pub fn default_hidden_visibility(&self) -> bool { + self.opts + .unstable_opts + .default_hidden_visibility + .unwrap_or(self.target.options.default_hidden_visibility) + } } // JUSTIFICATION: defn of the suggested wrapper fns diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 4ec5e2a5387..3a8289f38bd 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -5,7 +5,9 @@ use rustc_middle::ty; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; -use rustc_middle::ty::{GenericPredicates, Instance, ParamEnv, ScalarInt, ValTree}; +use rustc_middle::ty::{ + GenericPredicates, Instance, ParamEnv, ScalarInt, TypeVisitableExt, ValTree, +}; use rustc_span::def_id::LOCAL_CRATE; use stable_mir::compiler_interface::Context; use stable_mir::mir::alloc::GlobalAlloc; @@ -156,8 +158,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let crate_name = tables.tcx.crate_name(*crate_num).to_string(); (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num)) }) - .into_iter() - .filter_map(|c| c) + .flatten() .collect(); crates } @@ -324,7 +325,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; - instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables) + assert!(!instance.has_non_region_param(), "{instance:?} needs further substitution"); + instance.ty(tables.tcx, ParamEnv::reveal_all()).stable(&mut *tables) } fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 0cea3fcc7f7..41ab4007a67 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -36,6 +36,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { .collect(), self.arg_count, self.var_debug_info.iter().map(|info| info.stable(tables)).collect(), + self.spread_arg.stable(tables), ) } } @@ -707,7 +708,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { let id = tables.intern_const(*self); Const::new(kind, ty, id) } - mir::Const::Val(val, ty) if matches!(val, mir::ConstValue::ZeroSized) => { + mir::Const::Val(mir::ConstValue::ZeroSized, ty) => { let ty = ty.stable(tables); let id = tables.intern_const(*self); Const::new(ConstantKind::ZeroSized, ty, id) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs index 7d8339ab503..7021bdda735 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs @@ -57,7 +57,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { stable_mir::mir::CoroutineKind::Gen(source.stable(tables)) } CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine, - CoroutineKind::AsyncGen(_) => todo!(), + CoroutineKind::AsyncGen(source) => { + stable_mir::mir::CoroutineKind::AsyncGen(source.stable(tables)) + } } } } diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index e49d134659e..3d673f2f1ec 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -364,7 +364,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { // _ZTSFvu27NvNtC1234_5crate6Trait13fooIu22NtC1234_5crate7Struct1Iu3i32ES_EE // // The reason for not using v0's extended form of paths is to use a consistent and simpler - // encoding, as the reasoning for using it isn't relevand for type metadata identifiers (i.e., + // encoding, as the reasoning for using it isn't relevant for type metadata identifiers (i.e., // keep symbol names close to how methods are represented in error messages). See // https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html#methods. let mut s = String::new(); diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index e17b81d4652..257c6777996 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -35,6 +35,7 @@ pub mod abi; pub mod asm; pub mod json; pub mod spec; +pub mod target_features; #[cfg(test)] mod tests; diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index f32cb06d68f..afd60b40c3b 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -1,8 +1,8 @@ use std::{borrow::Cow, env}; use crate::spec::{add_link_args, add_link_args_iter}; -use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs}; -use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, Target, TargetOptions}; +use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs, LinkerFlavor, Lld}; +use crate::spec::{SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions}; #[cfg(test)] mod tests; @@ -81,6 +81,14 @@ impl Arch { Arm64_sim => "apple-a12", } } + + fn stack_probes(self) -> StackProbeType { + match self { + Armv7k | Armv7s => StackProbeType::None, + Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h | X86_64_sim + | X86_64_macabi | Arm64_macabi | Arm64_sim => StackProbeType::Inline, + } + } } fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { @@ -147,6 +155,7 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, eh_frame_header: false, + stack_probes: arch.stack_probes(), debuginfo_kind: DebuginfoKind::DwarfDsym, // The historical default for macOS targets is to run `dsymutil` which diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 24893bda9e7..a78df69f187 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2094,7 +2094,11 @@ pub struct TargetOptions { pub no_builtins: bool, /// The default visibility for symbols in this target should be "hidden" - /// rather than "default" + /// rather than "default". + /// + /// This value typically shouldn't be accessed directly, but through + /// the `rustc_session::Session::default_hidden_visibility` method, which + /// allows `rustc` users to override this setting using cmdline flags. pub default_hidden_visibility: bool, /// Whether a .debug_gdb_scripts section will be added to the output object file diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs index bbaa870ec2e..739a9e4a3dc 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu.rs @@ -1,5 +1,5 @@ use crate::abi::Endian; -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -10,6 +10,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v8a,+outline-atomics".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, mcount: "\u{1}_mcount".into(), endian: Endian::Big, ..base::linux_gnu::opts() diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs index 7536e507b3d..1b87c09e3fe 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_linux_gnu_ilp32.rs @@ -1,5 +1,5 @@ use crate::abi::Endian; -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::linux_gnu::opts(); @@ -13,6 +13,7 @@ pub fn target() -> Target { options: TargetOptions { abi: "ilp32".into(), features: "+v8a,+outline-atomics".into(), + stack_probes: StackProbeType::Inline, mcount: "\u{1}_mcount".into(), endian: Endian::Big, ..base diff --git a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs index 21de8a71a0d..02e156f19de 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_be_unknown_netbsd.rs @@ -1,5 +1,5 @@ use crate::abi::Endian; -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -10,6 +10,7 @@ pub fn target() -> Target { options: TargetOptions { mcount: "__mcount".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, endian: Endian::Big, ..base::netbsd::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs index e5e22fd1ee2..5b4ffc08a57 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, RelocModel, Target, TargetOptions}; +use crate::spec::{base, RelocModel, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let base = base::solid::opts("asp3"); @@ -13,6 +13,7 @@ pub fn target() -> Target { relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, ..base }, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs index 7c6fed7ab99..db9a1808560 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, SanitizerSet, Target, TargetOptions}; +use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions}; // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a // for target ABI requirements. @@ -14,6 +14,7 @@ pub fn target() -> Target { // As documented in https://developer.android.com/ndk/guides/cpu-features.html // the neon (ASIMD) and FP must exist on all android aarch64 targets. features: "+v8a,+neon,+fp-armv8".into(), + stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::CFI | SanitizerSet::HWADDRESS | SanitizerSet::MEMTAG diff --git a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs index 02fcc2bb43e..5a92225c496 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs @@ -1,4 +1,6 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, Target, TargetOptions}; +use crate::spec::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, StackProbeType, Target, TargetOptions, +}; const LINKER_SCRIPT: &str = include_str!("./aarch64_nintendo_switch_freestanding_linker_script.ld"); @@ -16,6 +18,7 @@ pub fn target() -> Target { link_script: Some(LINKER_SCRIPT.into()), os: "horizon".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, position_independent_executables: true, dynamic_linking: true, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs index 0f95984a31f..0ba91a54f1d 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, SanitizerSet, Target, TargetOptions}; +use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,6 +9,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v8a".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs index cacc6ea235a..430a1c5e7f1 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, SanitizerSet, Target, TargetOptions}; +use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,6 +9,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v8a".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::SHADOWCALLSTACK, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs index 3839e0b9c46..50813b81b8d 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,6 +9,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v8a,+strict-align,+neon,+fp-armv8".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, ..base::hermit::opts() }, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs index c0b07db3818..5b3a2ffa599 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, SanitizerSet, Target, TargetOptions}; +use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -10,6 +10,7 @@ pub fn target() -> Target { features: "+v8a,+outline-atomics".into(), mcount: "\u{1}_mcount".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs index d4c6271b241..0ff5c8651e6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu_ilp32.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -10,6 +10,7 @@ pub fn target() -> Target { abi: "ilp32".into(), features: "+v8a,+outline-atomics".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, mcount: "\u{1}_mcount".into(), ..base::linux_gnu::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs index 364df677e44..d16ccd803a9 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs @@ -1,10 +1,11 @@ -use crate::spec::{base, SanitizerSet, Target, TargetOptions}; +use crate::spec::{base, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::linux_musl::opts(); base.max_atomic_width = Some(128); base.supports_xray = true; base.features = "+v8a".into(); + base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs index 5f3bef63aa6..1be27a51108 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs @@ -1,5 +1,5 @@ use crate::spec::SanitizerSet; -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::linux_ohos::opts(); @@ -14,6 +14,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+reserve-x18".into(), mcount: "\u{1}_mcount".into(), + stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs index 3194d16ff47..32a0816cf81 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -10,6 +10,7 @@ pub fn target() -> Target { features: "+v8a".into(), mcount: "__mcount".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, ..base::netbsd::opts() }, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs index 63a8144f69f..518597b3811 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs @@ -7,7 +7,8 @@ // For example, `-C target-cpu=cortex-a53`. use crate::spec::{ - Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, Target, TargetOptions, + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target, + TargetOptions, }; pub fn target() -> Target { @@ -24,6 +25,7 @@ pub fn target() -> Target { relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, ..Default::default() }; diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs index 48b79b0b9ba..d56fbdbbe90 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs @@ -6,7 +6,9 @@ // // For example, `-C target-cpu=cortex-a53`. -use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; +use crate::spec::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, StackProbeType, Target, TargetOptions, +}; pub fn target() -> Target { let opts = TargetOptions { @@ -17,6 +19,7 @@ pub fn target() -> Target { relocation_model: RelocModel::Static, disable_redzone: true, max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, panic_strategy: PanicStrategy::Abort, ..Default::default() }; diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs index e3f5aafc7d4..d5fca5c31a6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,6 +9,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v8a".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, ..base::openbsd::opts() }, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs index de875e29ffd..844fed472a2 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs @@ -1,8 +1,9 @@ -use crate::spec::{base, Target}; +use crate::spec::{base, StackProbeType, Target}; pub fn target() -> Target { let mut base = base::redox::opts(); base.max_atomic_width = Some(128); + base.stack_probes = StackProbeType::Inline; base.features = "+v8a".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs index b490e80258c..204e9b061ce 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs @@ -1,9 +1,10 @@ -use crate::spec::{base, Target}; +use crate::spec::{base, StackProbeType, Target}; pub fn target() -> Target { let mut base = base::teeos::opts(); base.features = "+strict-align,+neon,+fp-armv8".into(); base.max_atomic_width = Some(128); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "aarch64-unknown-none".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs index 29f61d85778..48e142347d7 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Target, TargetOptions}; +use crate::spec::{base, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,6 +9,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v8a".into(), max_atomic_width: Some(128), + stack_probes: StackProbeType::Inline, ..base::vxworks::opts() }, } diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs index ce0d604f57c..13f8b6b5a0a 100644 --- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs @@ -1,5 +1,5 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; -use crate::spec::{StackProbeType, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::I386; @@ -14,10 +14,6 @@ pub fn target() -> Target { f64:32:64-f80:128-n8:16:32-S128" .into(), arch: arch.target_arch(), - options: TargetOptions { - max_atomic_width: Some(64), - stack_probes: StackProbeType::Inline, - ..opts("ios", arch) - }, + options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch) }, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs index c4c9023419d..59069fe4e3a 100644 --- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs @@ -1,5 +1,5 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { // ld64 only understands i386 and not i686 @@ -7,7 +7,6 @@ pub fn target() -> Target { let mut base = opts("macos", arch); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); - base.stack_probes = StackProbeType::Inline; base.frame_pointer = FramePointer::Always; Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs index 81173a16f96..59df3937ea6 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs @@ -1,6 +1,6 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; -use crate::spec::{StackProbeType, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64; @@ -8,7 +8,6 @@ pub fn target() -> Target { base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); - base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs index 221635526d1..d0e2ac44a2a 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs @@ -1,5 +1,5 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; -use crate::spec::{SanitizerSet, StackProbeType, Target, TargetOptions}; +use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64_sim; @@ -12,10 +12,6 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), arch: arch.target_arch(), - options: TargetOptions { - max_atomic_width: Some(128), - stack_probes: StackProbeType::Inline, - ..base - }, + options: TargetOptions { max_atomic_width: Some(128), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs index 5f6b4b500d0..8ef4b88b8b1 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs @@ -1,5 +1,5 @@ use crate::spec::base::apple::{opts, Arch}; -use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let llvm_target = "x86_64-apple-ios14.0-macabi"; @@ -15,10 +15,6 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), arch: arch.target_arch(), - options: TargetOptions { - max_atomic_width: Some(128), - stack_probes: StackProbeType::Inline, - ..base - }, + options: TargetOptions { max_atomic_width: Some(128), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs index a7d5f28e0e5..17efd437f2f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs @@ -1,5 +1,5 @@ use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch}; -use crate::spec::{StackProbeType, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64_sim; @@ -9,10 +9,6 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), arch: arch.target_arch(), - options: TargetOptions { - max_atomic_width: Some(128), - stack_probes: StackProbeType::Inline, - ..opts("tvos", arch) - }, + options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch) }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs index 3c5bf30ef5f..b1f72ee2f21 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs @@ -1,5 +1,5 @@ use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch}; -use crate::spec::{StackProbeType, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64_sim; @@ -9,10 +9,6 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" .into(), arch: arch.target_arch(), - options: TargetOptions { - max_atomic_width: Some(128), - stack_probes: StackProbeType::Inline, - ..opts("watchos", arch) - }, + options: TargetOptions { max_atomic_width: Some(128), ..opts("watchos", arch) }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs index 32d15c18678..0c731e369eb 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs @@ -1,6 +1,6 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; -use crate::spec::{StackProbeType, Target, TargetOptions}; +use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64h; @@ -8,7 +8,6 @@ pub fn target() -> Target { base.max_atomic_width = Some(128); base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); - base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs new file mode 100644 index 00000000000..5f5de57dd1d --- /dev/null +++ b/compiler/rustc_target/src/target_features.rs @@ -0,0 +1,429 @@ +use rustc_span::symbol::sym; +use rustc_span::symbol::Symbol; + +/// Features that control behaviour of rustc, rather than the codegen. +pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"]; + +/// Stability information for target features. +#[derive(Debug, Clone, Copy)] +pub enum Stability { + /// This target feature is stable, it can be used in `#[target_feature]` and + /// `#[cfg(target_feature)]`. + Stable, + /// This target feature is unstable; using it in `#[target_feature]` or `#[cfg(target_feature)]` + /// requires enabling the given nightly feature. + Unstable(Symbol), +} +use Stability::*; + +impl Stability { + pub fn as_feature_name(self) -> Option<Symbol> { + match self { + Stable => None, + Unstable(s) => Some(s), + } + } + + pub fn is_stable(self) -> bool { + matches!(self, Stable) + } +} + +// Here we list target features that rustc "understands": they can be used in `#[target_feature]` +// and `#[cfg(target_feature)]`. They also do not trigger any warnings when used with +// `-Ctarget-feature`. +// +// When adding features to the below lists +// check whether they're named already elsewhere in rust +// e.g. in stdarch and whether the given name matches LLVM's +// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted. +// +// Also note that all target features listed here must be purely additive: for target_feature 1.1 to +// be sound, we can never allow features like `+soft-float` (on x86) to be controlled on a +// per-function level, since we would then allow safe calls from functions with `+soft-float` to +// functions without that feature! +// +// When adding a new feature, be particularly mindful of features that affect function ABIs. Those +// need to be treated very carefully to avoid introducing unsoundness! This often affects features +// that enable/disable hardfloat support (see https://github.com/rust-lang/rust/issues/116344 for an +// example of this going wrong), but features enabling new SIMD registers are also a concern (see +// https://github.com/rust-lang/rust/issues/116558 for an example of this going wrong). +// +// Stabilizing a target feature requires t-lang approval. + +const ARM_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("aclass", Unstable(sym::arm_target_feature)), + ("aes", Unstable(sym::arm_target_feature)), + ("crc", Unstable(sym::arm_target_feature)), + ("d32", Unstable(sym::arm_target_feature)), + ("dotprod", Unstable(sym::arm_target_feature)), + ("dsp", Unstable(sym::arm_target_feature)), + ("fp-armv8", Unstable(sym::arm_target_feature)), + ("i8mm", Unstable(sym::arm_target_feature)), + ("mclass", Unstable(sym::arm_target_feature)), + ("neon", Unstable(sym::arm_target_feature)), + ("rclass", Unstable(sym::arm_target_feature)), + ("sha2", Unstable(sym::arm_target_feature)), + // This is needed for inline assembly, but shouldn't be stabilized as-is + // since it should be enabled per-function using #[instruction_set], not + // #[target_feature]. + ("thumb-mode", Unstable(sym::arm_target_feature)), + ("thumb2", Unstable(sym::arm_target_feature)), + ("trustzone", Unstable(sym::arm_target_feature)), + ("v5te", Unstable(sym::arm_target_feature)), + ("v6", Unstable(sym::arm_target_feature)), + ("v6k", Unstable(sym::arm_target_feature)), + ("v6t2", Unstable(sym::arm_target_feature)), + ("v7", Unstable(sym::arm_target_feature)), + ("v8", Unstable(sym::arm_target_feature)), + ("vfp2", Unstable(sym::arm_target_feature)), + ("vfp3", Unstable(sym::arm_target_feature)), + ("vfp4", Unstable(sym::arm_target_feature)), + ("virtualization", Unstable(sym::arm_target_feature)), + // tidy-alphabetical-end +]; + +const AARCH64_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + // FEAT_AES + ("aes", Stable), + // FEAT_BF16 + ("bf16", Stable), + // FEAT_BTI + ("bti", Stable), + // FEAT_CRC + ("crc", Stable), + // FEAT_DIT + ("dit", Stable), + // FEAT_DotProd + ("dotprod", Stable), + // FEAT_DPB + ("dpb", Stable), + // FEAT_DPB2 + ("dpb2", Stable), + // FEAT_F32MM + ("f32mm", Stable), + // FEAT_F64MM + ("f64mm", Stable), + // FEAT_FCMA + ("fcma", Stable), + // FEAT_FHM + ("fhm", Stable), + // FEAT_FLAGM + ("flagm", Stable), + // FEAT_FP16 + ("fp16", Stable), + // FEAT_FRINTTS + ("frintts", Stable), + // FEAT_I8MM + ("i8mm", Stable), + // FEAT_JSCVT + ("jsconv", Stable), + // FEAT_LOR + ("lor", Stable), + // FEAT_LSE + ("lse", Stable), + // FEAT_MTE + ("mte", Stable), + // FEAT_AdvSimd & FEAT_FP + ("neon", Stable), + // FEAT_PAUTH (address authentication) + ("paca", Stable), + // FEAT_PAUTH (generic authentication) + ("pacg", Stable), + // FEAT_PAN + ("pan", Stable), + // FEAT_PMUv3 + ("pmuv3", Stable), + // FEAT_RAND + ("rand", Stable), + // FEAT_RAS + ("ras", Stable), + // FEAT_RCPC + ("rcpc", Stable), + // FEAT_RCPC2 + ("rcpc2", Stable), + // FEAT_RDM + ("rdm", Stable), + // FEAT_SB + ("sb", Stable), + // FEAT_SHA1 & FEAT_SHA256 + ("sha2", Stable), + // FEAT_SHA512 & FEAT_SHA3 + ("sha3", Stable), + // FEAT_SM3 & FEAT_SM4 + ("sm4", Stable), + // FEAT_SPE + ("spe", Stable), + // FEAT_SSBS + ("ssbs", Stable), + // FEAT_SVE + ("sve", Stable), + // FEAT_SVE2 + ("sve2", Stable), + // FEAT_SVE2_AES + ("sve2-aes", Stable), + // FEAT_SVE2_BitPerm + ("sve2-bitperm", Stable), + // FEAT_SVE2_SHA3 + ("sve2-sha3", Stable), + // FEAT_SVE2_SM4 + ("sve2-sm4", Stable), + // FEAT_TME + ("tme", Stable), + ("v8.1a", Unstable(sym::aarch64_ver_target_feature)), + ("v8.2a", Unstable(sym::aarch64_ver_target_feature)), + ("v8.3a", Unstable(sym::aarch64_ver_target_feature)), + ("v8.4a", Unstable(sym::aarch64_ver_target_feature)), + ("v8.5a", Unstable(sym::aarch64_ver_target_feature)), + ("v8.6a", Unstable(sym::aarch64_ver_target_feature)), + ("v8.7a", Unstable(sym::aarch64_ver_target_feature)), + // FEAT_VHE + ("vh", Stable), + // tidy-alphabetical-end +]; + +const AARCH64_TIED_FEATURES: &[&[&str]] = &[ + &["paca", "pacg"], // Together these represent `pauth` in LLVM +]; + +const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("adx", Stable), + ("aes", Stable), + ("avx", Stable), + ("avx2", Stable), + ("avx512bf16", Unstable(sym::avx512_target_feature)), + ("avx512bitalg", Unstable(sym::avx512_target_feature)), + ("avx512bw", Unstable(sym::avx512_target_feature)), + ("avx512cd", Unstable(sym::avx512_target_feature)), + ("avx512dq", Unstable(sym::avx512_target_feature)), + ("avx512er", Unstable(sym::avx512_target_feature)), + ("avx512f", Unstable(sym::avx512_target_feature)), + ("avx512ifma", Unstable(sym::avx512_target_feature)), + ("avx512pf", Unstable(sym::avx512_target_feature)), + ("avx512vbmi", Unstable(sym::avx512_target_feature)), + ("avx512vbmi2", Unstable(sym::avx512_target_feature)), + ("avx512vl", Unstable(sym::avx512_target_feature)), + ("avx512vnni", Unstable(sym::avx512_target_feature)), + ("avx512vp2intersect", Unstable(sym::avx512_target_feature)), + ("avx512vpopcntdq", Unstable(sym::avx512_target_feature)), + ("bmi1", Stable), + ("bmi2", Stable), + ("cmpxchg16b", Stable), + ("ermsb", Unstable(sym::ermsb_target_feature)), + ("f16c", Stable), + ("fma", Stable), + ("fxsr", Stable), + ("gfni", Unstable(sym::avx512_target_feature)), + ("lzcnt", Stable), + ("movbe", Stable), + ("pclmulqdq", Stable), + ("popcnt", Stable), + ("rdrand", Stable), + ("rdseed", Stable), + ("rtm", Unstable(sym::rtm_target_feature)), + ("sha", Stable), + ("sse", Stable), + ("sse2", Stable), + ("sse3", Stable), + ("sse4.1", Stable), + ("sse4.2", Stable), + ("sse4a", Unstable(sym::sse4a_target_feature)), + ("ssse3", Stable), + ("tbm", Unstable(sym::tbm_target_feature)), + ("vaes", Unstable(sym::avx512_target_feature)), + ("vpclmulqdq", Unstable(sym::avx512_target_feature)), + ("xsave", Stable), + ("xsavec", Stable), + ("xsaveopt", Stable), + ("xsaves", Stable), + // tidy-alphabetical-end +]; + +const HEXAGON_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("hvx", Unstable(sym::hexagon_target_feature)), + ("hvx-length128b", Unstable(sym::hexagon_target_feature)), + // tidy-alphabetical-end +]; + +const POWERPC_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("altivec", Unstable(sym::powerpc_target_feature)), + ("power10-vector", Unstable(sym::powerpc_target_feature)), + ("power8-altivec", Unstable(sym::powerpc_target_feature)), + ("power8-vector", Unstable(sym::powerpc_target_feature)), + ("power9-altivec", Unstable(sym::powerpc_target_feature)), + ("power9-vector", Unstable(sym::powerpc_target_feature)), + ("vsx", Unstable(sym::powerpc_target_feature)), + // tidy-alphabetical-end +]; + +const MIPS_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("fp64", Unstable(sym::mips_target_feature)), + ("msa", Unstable(sym::mips_target_feature)), + ("virt", Unstable(sym::mips_target_feature)), + // tidy-alphabetical-end +]; + +const RISCV_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("a", Stable), + ("c", Stable), + ("d", Unstable(sym::riscv_target_feature)), + ("e", Unstable(sym::riscv_target_feature)), + ("f", Unstable(sym::riscv_target_feature)), + ("fast-unaligned-access", Unstable(sym::riscv_target_feature)), + ("m", Stable), + ("relax", Unstable(sym::riscv_target_feature)), + ("v", Unstable(sym::riscv_target_feature)), + ("zba", Stable), + ("zbb", Stable), + ("zbc", Stable), + ("zbkb", Stable), + ("zbkc", Stable), + ("zbkx", Stable), + ("zbs", Stable), + ("zdinx", Unstable(sym::riscv_target_feature)), + ("zfh", Unstable(sym::riscv_target_feature)), + ("zfhmin", Unstable(sym::riscv_target_feature)), + ("zfinx", Unstable(sym::riscv_target_feature)), + ("zhinx", Unstable(sym::riscv_target_feature)), + ("zhinxmin", Unstable(sym::riscv_target_feature)), + ("zk", Stable), + ("zkn", Stable), + ("zknd", Stable), + ("zkne", Stable), + ("zknh", Stable), + ("zkr", Stable), + ("zks", Stable), + ("zksed", Stable), + ("zksh", Stable), + ("zkt", Stable), + // tidy-alphabetical-end +]; + +const WASM_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("atomics", Unstable(sym::wasm_target_feature)), + ("bulk-memory", Unstable(sym::wasm_target_feature)), + ("exception-handling", Unstable(sym::wasm_target_feature)), + ("multivalue", Unstable(sym::wasm_target_feature)), + ("mutable-globals", Unstable(sym::wasm_target_feature)), + ("nontrapping-fptoint", Unstable(sym::wasm_target_feature)), + ("reference-types", Unstable(sym::wasm_target_feature)), + ("relaxed-simd", Unstable(sym::wasm_target_feature)), + ("sign-ext", Unstable(sym::wasm_target_feature)), + ("simd128", Stable), + // tidy-alphabetical-end +]; + +const BPF_ALLOWED_FEATURES: &[(&str, Stability)] = &[("alu32", Unstable(sym::bpf_target_feature))]; + +const CSKY_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("10e60", Unstable(sym::csky_target_feature)), + ("2e3", Unstable(sym::csky_target_feature)), + ("3e3r1", Unstable(sym::csky_target_feature)), + ("3e3r2", Unstable(sym::csky_target_feature)), + ("3e3r3", Unstable(sym::csky_target_feature)), + ("3e7", Unstable(sym::csky_target_feature)), + ("7e10", Unstable(sym::csky_target_feature)), + ("cache", Unstable(sym::csky_target_feature)), + ("doloop", Unstable(sym::csky_target_feature)), + ("dsp1e2", Unstable(sym::csky_target_feature)), + ("dspe60", Unstable(sym::csky_target_feature)), + ("e1", Unstable(sym::csky_target_feature)), + ("e2", Unstable(sym::csky_target_feature)), + ("edsp", Unstable(sym::csky_target_feature)), + ("elrw", Unstable(sym::csky_target_feature)), + ("float1e2", Unstable(sym::csky_target_feature)), + ("float1e3", Unstable(sym::csky_target_feature)), + ("float3e4", Unstable(sym::csky_target_feature)), + ("float7e60", Unstable(sym::csky_target_feature)), + ("floate1", Unstable(sym::csky_target_feature)), + ("hard-tp", Unstable(sym::csky_target_feature)), + ("high-registers", Unstable(sym::csky_target_feature)), + ("hwdiv", Unstable(sym::csky_target_feature)), + ("mp", Unstable(sym::csky_target_feature)), + ("mp1e2", Unstable(sym::csky_target_feature)), + ("nvic", Unstable(sym::csky_target_feature)), + ("trust", Unstable(sym::csky_target_feature)), + ("vdsp2e60f", Unstable(sym::csky_target_feature)), + ("vdspv1", Unstable(sym::csky_target_feature)), + ("vdspv2", Unstable(sym::csky_target_feature)), + // tidy-alphabetical-end + //fpu + // tidy-alphabetical-start + ("fdivdu", Unstable(sym::csky_target_feature)), + ("fpuv2_df", Unstable(sym::csky_target_feature)), + ("fpuv2_sf", Unstable(sym::csky_target_feature)), + ("fpuv3_df", Unstable(sym::csky_target_feature)), + ("fpuv3_hf", Unstable(sym::csky_target_feature)), + ("fpuv3_hi", Unstable(sym::csky_target_feature)), + ("fpuv3_sf", Unstable(sym::csky_target_feature)), + ("hard-float", Unstable(sym::csky_target_feature)), + ("hard-float-abi", Unstable(sym::csky_target_feature)), + // tidy-alphabetical-end +]; + +const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[ + // tidy-alphabetical-start + ("d", Unstable(sym::loongarch_target_feature)), + ("f", Unstable(sym::loongarch_target_feature)), + ("lasx", Unstable(sym::loongarch_target_feature)), + ("lbt", Unstable(sym::loongarch_target_feature)), + ("lsx", Unstable(sym::loongarch_target_feature)), + ("lvz", Unstable(sym::loongarch_target_feature)), + ("ual", Unstable(sym::loongarch_target_feature)), + // tidy-alphabetical-end +]; + +/// When rustdoc is running, provide a list of all known features so that all their respective +/// primitives may be documented. +/// +/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator! +pub fn all_known_features() -> impl Iterator<Item = (&'static str, Stability)> { + std::iter::empty() + .chain(ARM_ALLOWED_FEATURES.iter()) + .chain(AARCH64_ALLOWED_FEATURES.iter()) + .chain(X86_ALLOWED_FEATURES.iter()) + .chain(HEXAGON_ALLOWED_FEATURES.iter()) + .chain(POWERPC_ALLOWED_FEATURES.iter()) + .chain(MIPS_ALLOWED_FEATURES.iter()) + .chain(RISCV_ALLOWED_FEATURES.iter()) + .chain(WASM_ALLOWED_FEATURES.iter()) + .chain(BPF_ALLOWED_FEATURES.iter()) + .chain(CSKY_ALLOWED_FEATURES) + .chain(LOONGARCH_ALLOWED_FEATURES) + .cloned() +} + +impl super::spec::Target { + pub fn supported_target_features(&self) -> &'static [(&'static str, Stability)] { + match &*self.arch { + "arm" => ARM_ALLOWED_FEATURES, + "aarch64" => AARCH64_ALLOWED_FEATURES, + "x86" | "x86_64" => X86_ALLOWED_FEATURES, + "hexagon" => HEXAGON_ALLOWED_FEATURES, + "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES, + "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES, + "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES, + "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES, + "bpf" => BPF_ALLOWED_FEATURES, + "csky" => CSKY_ALLOWED_FEATURES, + "loongarch64" => LOONGARCH_ALLOWED_FEATURES, + _ => &[], + } + } + + pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] { + match &*self.arch { + "aarch64" => AARCH64_TIED_FEATURES, + _ => &[], + } + } +} diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 4b11cc3ace9..251f0628a71 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -101,11 +101,10 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { self.tcx.impl_trait_ref(impl_def_id).map(|r| (impl_def_id, r)) }) .map(|(impl_def_id, imp)| (impl_def_id, imp.skip_binder())) - .filter(|(_, imp)| match imp.self_ty().peel_refs().kind() { + .find(|(_, imp)| match imp.self_ty().peel_refs().kind() { ty::Adt(i_def, _) if i_def.did() == def.did() => true, _ => false, }) - .next() { let mut fulfill_cx = FulfillmentCtxt::new(self); // We get all obligations from the impl to talk about specific diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index b3e7a63c972..cafb858794a 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -200,9 +200,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { let result = f(&mut ecx); let tree = ecx.inspect.finalize(); - if let (Some(tree), DumpSolverProofTree::Always) = - (&tree, infcx.tcx.sess.opts.unstable_opts.dump_solver_proof_tree) - { + if let (Some(tree), DumpSolverProofTree::Always) = ( + &tree, + infcx.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default(), + ) { let mut lock = std::io::stdout().lock(); let _ = lock.write_fmt(format_args!("{tree:?}\n")); let _ = lock.flush(); @@ -377,7 +378,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { // // This assert was removed as it did not hold for goals constraining // an inference variable to a recursive alias, e.g. in - // tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs. + // tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs. // // Once we have decided on how to handle trait-system-refactor-initiative#75, // we should re-add an assert here. @@ -421,7 +422,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct }) } ty::PredicateKind::ConstEquate(_, _) => { - bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active") + bug!("ConstEquate should not be emitted when `-Znext-solver` is active") } ty::PredicateKind::NormalizesTo(predicate) => { self.compute_normalizes_to_goal(Goal { param_env, predicate }) diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index 0d46df44c91..c857aae572d 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -265,7 +265,7 @@ impl<'tcx> ProofTreeBuilder<'tcx> { GenerateProofTree::Never => ProofTreeBuilder::new_noop(), GenerateProofTree::IfEnabled => { let opts = &tcx.sess.opts.unstable_opts; - match opts.dump_solver_proof_tree { + match opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() { DumpSolverProofTree::Always => ProofTreeBuilder::new_root(), // `OnError` is handled by reevaluating goals in error // reporting with `GenerateProofTree::Yes`. diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index f45473e06dc..1e58106e353 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -1,7 +1,6 @@ //! The next-generation trait solver, currently still WIP. //! -//! As a user of rust, you can use `-Ztrait-solver=next` or `next-coherence` -//! to enable the new trait solver always, or just within coherence, respectively. +//! As a user of rust, you can use `-Znext-solver` to enable the new trait solver. //! //! As a developer of rustc, you shouldn't be using the new trait //! solver without asking the trait-system-refactor-initiative, but it can @@ -248,7 +247,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { return None; } - // FIXME(-Ztrait-solver=next): We should instead try to find a `Certainty::Yes` response with + // FIXME(-Znext-solver): We should instead try to find a `Certainty::Yes` response with // a subset of the constraints that all the other responses have. let one = responses[0]; if responses[1..].iter().all(|&resp| resp == one) { diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 2fe51b400ec..980ef862366 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -203,7 +203,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ) .into(), ty::AssocKind::Type => Ty::new_error(tcx, guar).into(), - ty::AssocKind::Fn => unreachable!(), + // This makes no sense... + ty::AssocKind::Fn => span_bug!( + tcx.def_span(assoc_def.item.def_id), + "cannot project to an associated function" + ), }; ecx.eq(goal.param_env, goal.predicate.term, error_term) .expect("expected goal term to be fully unconstrained"); diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 0b80969c307..d0e92a54ceb 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -8,16 +8,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { &mut self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>, ) -> QueryResult<'tcx> { - match goal.predicate.term.unpack() { - ty::TermKind::Ty(term) => { - let alias = goal.predicate.projection_ty.to_ty(self.tcx()); - self.eq(goal.param_env, alias, term)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } - // FIXME(associated_const_equality): actually do something here. - ty::TermKind::Const(_) => { - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } - } + let tcx = self.tcx(); + let projection_term = match goal.predicate.term.unpack() { + ty::TermKind::Ty(_) => goal.predicate.projection_ty.to_ty(tcx).into(), + ty::TermKind::Const(_) => ty::Const::new_unevaluated( + tcx, + ty::UnevaluatedConst::new( + goal.predicate.projection_ty.def_id, + goal.predicate.projection_ty.args, + ), + tcx.type_of(goal.predicate.projection_ty.def_id) + .instantiate(tcx, goal.predicate.projection_ty.args), + ) + .into(), + }; + self.add_goal(goal.with( + tcx, + ty::PredicateKind::AliasRelate( + projection_term, + goal.predicate.term, + ty::AliasRelationDirection::Equate, + ), + )); + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index 71adebffc15..2a08b80e02a 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -38,7 +38,7 @@ struct StackEntry<'tcx> { /// If we were to use that result when later trying to prove another cycle /// participant, we can end up with unstable query results. /// - /// See tests/ui/new-solver/coinduction/incompleteness-unstable-result.rs for + /// See tests/ui/next-solver/coinduction/incompleteness-unstable-result.rs for /// an example of where this is needed. cycle_participants: FxHashSet<CanonicalInput<'tcx>>, } @@ -237,7 +237,7 @@ impl<'tcx> SearchGraph<'tcx> { // in unstable results due to incompleteness. // // However, a test for this would be an even more complex version of - // tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs. + // tests/ui/traits/next-solver/coinduction/incompleteness-unstable-result.rs. // I did not bother to write such a test and we have no regression test // for this. It would be good to have such a test :) #[allow(rustc::potential_query_instability)] @@ -248,7 +248,7 @@ impl<'tcx> SearchGraph<'tcx> { // until we reach a fixpoint. It is not enough to simply retry the // `root` goal of this cycle. // - // See tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs + // See tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs // for an example. self.stack[stack_depth].has_been_used = true; return if let Some(result) = self.stack[stack_depth].provisional_result { diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 5807f7c6153..deb50e6aefd 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -256,7 +256,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { Err(NoSolution) } } - ty::ImplPolarity::Reservation => bug!(), + // FIXME: Goal polarity should be split from impl polarity + ty::ImplPolarity::Reservation => { + bug!("we never expect a `Reservation` polarity in a trait goal") + } } } @@ -445,7 +448,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return Err(NoSolution); } - // FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver + // FIXME(-Znext-solver): Implement this when we get const working in the new solver // `Destruct` is automatically implemented for every type in // non-const environments. diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index db4d4a93e54..533fe32f70d 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -273,7 +273,6 @@ fn overlap<'tcx>( causing the impls to overlap", infcx.resolve_vars_if_possible(failing_obligation.predicate) )); - lint }, ); } @@ -487,7 +486,7 @@ fn plug_infer_with_placeholders<'tcx>( ), ) else { - bug!() + bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations, &[]); ControlFlow::Continue(()) @@ -510,7 +509,7 @@ fn plug_infer_with_placeholders<'tcx>( ), ) else { - bug!() + bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations, &[]); ControlFlow::Continue(()) @@ -544,7 +543,7 @@ fn plug_infer_with_placeholders<'tcx>( ), ) else { - bug!() + bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations, &[]); } @@ -855,7 +854,7 @@ where } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - // Need to lazily normalize here in with `-Ztrait-solver=next-coherence`. + // Need to lazily normalize here in with `-Znext-solver=coherence`. let ty = match (self.lazily_normalize_ty)(ty) { Ok(ty) => ty, Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)), @@ -1069,7 +1068,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { let lazily_normalize_ty = |ty: Ty<'tcx>| { let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx); if matches!(ty.kind(), ty::Alias(..)) { - // FIXME(-Ztrait-solver=next-coherence): we currently don't + // FIXME(-Znext-solver=coherence): we currently don't // normalize opaque types here, resulting in diverging behavior // for TAITs. match infcx diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 67718d0a348..013a50f9fa1 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -25,7 +25,6 @@ use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::Variance; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_session::config::TraitSolver; pub trait TraitEngineExt<'tcx> { fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>; @@ -33,18 +32,16 @@ pub trait TraitEngineExt<'tcx> { impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> { fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> { - match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) { - (TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => { - Box::new(FulfillmentContext::new(infcx)) - } - (TraitSolver::Classic | TraitSolver::Next | TraitSolver::NextCoherence, true) => { - Box::new(NextFulfillmentCtxt::new(infcx)) - } - (TraitSolver::Next, false) => bug!( - "incompatible combination of -Ztrait-solver flag ({:?}) and InferCtxt::next_trait_solver ({:?})", - infcx.tcx.sess.opts.unstable_opts.trait_solver, - infcx.next_trait_solver() - ), + if infcx.next_trait_solver() { + Box::new(NextFulfillmentCtxt::new(infcx)) + } else { + let new_solver_globally = + infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally); + assert!( + !new_solver_globally, + "using old solver even though new solver is enabled globally" + ); + Box::new(FulfillmentContext::new(infcx)) } } } 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 c07db12b25b..61e97dde5f8 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 @@ -103,7 +103,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { /// to be the enclosing (async) block/function/closure fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { let hir = self.tcx.hir(); - let node = hir.find(hir_id)?; + let node = self.tcx.opt_hir_node(hir_id)?; match &node { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => { self.describe_coroutine(*body_id).or_else(|| { 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 f7e8dc62a62..a1b896d2251 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -530,7 +530,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we // don't suggest `T: Sized + ?Sized`. - while let Some(node) = self.tcx.hir().find_by_def_id(body_id) { + while let Some(node) = self.tcx.opt_hir_node_by_def_id(body_id) { match node { hir::Node::Item(hir::Item { ident, @@ -732,7 +732,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let Some(typeck_results) = &self.typeck_results else { return false; }; - let hir::Node::Expr(expr) = self.tcx.hir().get(*arg_hir_id) else { + let hir::Node::Expr(expr) = self.tcx.hir_node(*arg_hir_id) else { return false; }; let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr) else { @@ -785,7 +785,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { kind: hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, expr), .. - })) = self.tcx.hir().find(*arg_hir_id) + })) = self.tcx.opt_hir_node(*arg_hir_id) { let derefs = "*".repeat(steps); err.span_suggestion_verbose( @@ -821,7 +821,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if self.predicate_may_hold(&obligation) && self.predicate_must_hold_modulo_regions(&sized_obligation) { - let call_node = self.tcx.hir().get(*call_hir_id); + let call_node = self.tcx.hir_node(*call_hir_id); let msg = "consider dereferencing here"; let is_receiver = matches!( call_node, @@ -1046,7 +1046,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let Res::Local(hir_id) = path.res else { return; }; - let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else { + let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else { return; }; let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) = @@ -1106,7 +1106,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { else { return false; }; - let arg_node = self.tcx.hir().get(*arg_hir_id); + let arg_node = self.tcx.hir_node(*arg_hir_id); let Node::Expr(Expr { kind: hir::ExprKind::Path(_), .. }) = arg_node else { return false }; let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); @@ -1387,14 +1387,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.message = vec![(rustc_errors::DiagnosticMessage::from(msg), Style::NoStyle)]; } + let mut file = None; err.span_label( span, format!( "the trait `{}` is not implemented for `{}`", old_pred.print_modifiers_and_trait_path(), - old_pred.self_ty().skip_binder(), + self.tcx.short_ty_string(old_pred.self_ty().skip_binder(), &mut file), ), ); + if let Some(file) = file { + err.note(format!( + "the full type name has been written to '{}'", + file.display() + )); + } if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { err.span_suggestions( @@ -1628,7 +1635,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let Res::Local(hir_id) = path.res - && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id) + && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(hir_id) && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id) && let None = local.ty && let Some(binding_expr) = local.init @@ -1644,7 +1651,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) { let hir = self.tcx.hir(); if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives() - && let hir::Node::Expr(expr) = hir.get(*hir_id) + && let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id) { // FIXME: use `obligation.predicate.kind()...trait_ref.self_ty()` to see if we have `()` // and if not maybe suggest doing something else? If we kept the expression around we @@ -1794,7 +1801,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { let hir = self.tcx.hir(); - let node = hir.find_by_def_id(obligation.cause.body_id); + let node = self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id); if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node && let hir::ExprKind::Block(blk, _) = &hir.body(*body_id).value.kind && sig.decl.output.span().overlaps(span) @@ -1829,9 +1836,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> { - let hir = self.tcx.hir(); let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) = - hir.find_by_def_id(obligation.cause.body_id) + self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id) else { return None; }; @@ -1923,7 +1929,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } let hir = self.tcx.hir(); - let node = hir.find_by_def_id(obligation.cause.body_id); + let node = self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id); if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) = node { @@ -2041,7 +2047,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let ty::FnPtr(found) = found.kind() else { return; }; - let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) else { + let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id) else { return; }; let hir::ExprKind::Path(path) = arg.kind else { @@ -2167,7 +2173,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }) .collect(); err.multipart_suggestion( - format!("consider wrapping the function in a closure"), + "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(", "))), @@ -2917,22 +2923,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } ObligationCauseCode::Coercion { source, target } => { - let (source, source_file) = - self.tcx.short_ty_string(self.resolve_vars_if_possible(source)); - let (target, target_file) = - self.tcx.short_ty_string(self.resolve_vars_if_possible(target)); + let mut file = None; + let source = + self.tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut file); + let target = + self.tcx.short_ty_string(self.resolve_vars_if_possible(target), &mut file); err.note(with_forced_trimmed_paths!(format!( "required for the cast from `{source}` to `{target}`", ))); - if let Some(file) = source_file { - err.note(format!( - "the full name for the source type has been written to '{}'", - file.display(), - )); - } - if let Some(file) = target_file { + if let Some(file) = file { err.note(format!( - "the full name for the target type has been written to '{}'", + "the full name for the type has been written to '{}'", file.display(), )); } @@ -2986,7 +2987,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::VariableType(hir_id) => { let parent_node = self.tcx.hir().parent_id(hir_id); - match self.tcx.hir().find(parent_node) { + match self.tcx.opt_hir_node(parent_node) { Some(Node::Local(hir::Local { ty: Some(ty), .. })) => { err.span_suggestion_verbose( ty.span.shrink_to_lo(), @@ -3130,7 +3131,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "all values captured by value by a closure must have a statically known size", ); let hir::ExprKind::Closure(closure) = - self.tcx.hir().get_by_def_id(closure_def_id).expect_expr().kind + self.tcx.hir_node_by_def_id(closure_def_id).expect_expr().kind else { bug!("expected closure in SizedClosureCapture obligation"); }; @@ -3185,9 +3186,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Don't print the tuple of capture types 'print: { if !is_upvar_tys_infer_tuple { - let msg = with_forced_trimmed_paths!(format!( - "required because it appears within the type `{ty}`", - )); + let mut file = None; + let ty_str = self.tcx.short_ty_string(ty, &mut file); + let msg = format!("required because it appears within the type `{ty_str}`"); match ty.kind() { ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) { Some(ident) => err.span_note(ident.span, msg), @@ -3284,8 +3285,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut parent_trait_pred = self.resolve_vars_if_possible(data.derived.parent_trait_pred); let parent_def_id = parent_trait_pred.def_id(); - let (self_ty, file) = - self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()); + let mut file = None; + let self_ty = + self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file); let msg = format!( "required for `{self_ty}` to implement `{}`", parent_trait_pred.print_modifiers_and_trait_path() @@ -3382,8 +3384,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { count, pluralize!(count) )); - let (self_ty, file) = - self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()); + let mut file = None; + let self_ty = self + .tcx + .short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut file); err.note(format!( "required for `{self_ty}` to implement `{}`", parent_trait_pred.print_modifiers_and_trait_path() @@ -3701,8 +3705,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { call_hir_id: HirId, ) { let tcx = self.tcx; - let hir = tcx.hir(); - if let Some(Node::Expr(expr)) = hir.find(arg_hir_id) + if let Some(Node::Expr(expr)) = tcx.opt_hir_node(arg_hir_id) && let Some(typeck_results) = &self.typeck_results { if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr { @@ -3735,7 +3738,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let hir::ExprKind::Closure(hir::Closure { body, fn_decl_span, .. }) = value.kind - && let body = hir.body(*body) + && let body = tcx.hir().body(*body) && !matches!(body.value.kind, hir::ExprKind::Block(..)) { // Check if the failed predicate was an expectation of a closure type @@ -3818,9 +3821,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: Res::Local(hir_id), .. } = path - && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) + && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*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) + && let Some(hir::Node::Local(local)) = self.tcx.opt_hir_node(parent_hir_id) && let Some(binding_expr) = local.init { // If the expression we're calling on is a binding, we want to point at the @@ -3831,7 +3834,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.point_at_chain(expr, typeck_results, type_diffs, param_env, err); } } - let call_node = hir.find(call_hir_id); + let call_node = tcx.opt_hir_node(call_hir_id); if let Some(Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(path, rcvr, ..), .. })) = call_node @@ -3841,7 +3844,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - if let Some(Node::Expr(expr)) = hir.find(call_hir_id) { + if let Some(Node::Expr(expr)) = tcx.opt_hir_node(call_hir_id) { if let hir::ExprKind::Call(hir::Expr { span, .. }, _) | hir::ExprKind::MethodCall( hir::PathSegment { ident: Ident { span, .. }, .. }, @@ -4002,7 +4005,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { continue; }; let hir = tcx.hir(); - let node = hir.get_by_def_id(hir.get_parent_item(expr.hir_id).def_id); + let node = tcx.hir_node_by_def_id(hir.get_parent_item(expr.hir_id).def_id); let pred = ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef::from_lang_item( @@ -4078,7 +4081,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: Res::Local(hir_id), .. } = path - && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) + && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id) && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id) { // We've reached the root of the method call chain... @@ -4457,7 +4460,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } return; }; - let Some(hir::Node::TraitItem(item)) = self.tcx.hir().find_by_def_id(fn_def_id) else { + let Some(hir::Node::TraitItem(item)) = self.tcx.opt_hir_node_by_def_id(fn_def_id) else { return; }; @@ -4662,7 +4665,7 @@ pub trait NextTypeParamName { impl NextTypeParamName for &[hir::GenericParam<'_>] { fn next_type_param_name(&self, name: Option<&str>) -> String { // This is the list of possible parameter names that we might suggest. - let name = name.and_then(|n| n.chars().next()).map(|c| c.to_string().to_uppercase()); + let name = name.and_then(|n| n.chars().next()).map(|c| c.to_uppercase().to_string()); let name = name.as_deref(); let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"]; let used_names = self @@ -4709,6 +4712,7 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> { } pub(super) fn get_explanation_based_on_obligation<'tcx>( + tcx: TyCtxt<'tcx>, obligation: &PredicateObligation<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, trait_predicate: &ty::PolyTraitPredicate<'tcx>, @@ -4729,13 +4733,13 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>( pre_message, trait_predicate.print_modifiers_and_trait_path(), desc, - trait_ref.skip_binder().self_ty(), + tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None), ), None => format!( "{}the trait `{}` is not implemented for `{}`", pre_message, trait_predicate.print_modifiers_and_trait_path(), - trait_ref.skip_binder().self_ty(), + tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None), ), } } @@ -4778,9 +4782,15 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>( return None; }; - let future = tcx.hir().get_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); - let Some(hir::GenericBound::LangItemTrait(_, _, _, generics)) = future.bounds.get(0) else { - // `async fn` should always lower to a lang item bound... but don't ICE. + let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); + let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else { + // `async fn` should always lower to a single bound... but don't ICE. + return None; + }; + let Some(hir::PathSegment { args: Some(generics), .. }) = + trait_ref.trait_ref.path.segments.last() + else { + // desugaring to a single path segment for `Future<...>`. return None; }; let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) = 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 4988222c135..5cc934e7bc5 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 @@ -37,7 +37,7 @@ use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, }; -use rustc_session::config::{DumpSolverProofTree, TraitSolver}; +use rustc_session::config::DumpSolverProofTree; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; @@ -250,7 +250,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.emit(); self.tcx.sess.abort_if_errors(); - bug!(); + // FIXME: this should be something like `build_overflow_error_fatal`, which returns + // `DiagnosticBuilder<', !>`. Then we don't even need anything after that `emit()`. + unreachable!( + "did not expect compilation to continue after `abort_if_errors`, \ + since an error was definitely emitted!" + ); } fn build_overflow_error<T>( @@ -370,7 +375,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) { let tcx = self.tcx; - if tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError { + if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() + == DumpSolverProofTree::OnError + { dump_proof_tree(root_obligation, self.infcx); } @@ -444,21 +451,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // reported on the binding definition (#56607). return; } - let (post_message, pre_message, type_def, file_note) = self + let mut file = None; + let (post_message, pre_message, type_def) = self .get_parent_trait_ref(obligation.cause.code()) .map(|(t, s)| { - let (t, file) = self.tcx.short_ty_string(t); + let t = self.tcx.short_ty_string(t, &mut file); ( format!(" in `{t}`"), format!("within `{t}`, "), s.map(|s| (format!("within this `{t}`"), s)), - file.map(|file| format!( - "the full trait has been written to '{}'", - file.display(), - )) ) }) .unwrap_or_default(); + let file_note = file.map(|file| format!( + "the full trait has been written to '{}'", + file.display(), + )); let OnUnimplementedNote { message, @@ -547,6 +555,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } let explanation = get_explanation_based_on_obligation( + self.tcx, &obligation, trait_ref, &trait_predicate, @@ -810,23 +819,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => { let ty = self.resolve_vars_if_possible(ty); - match self.tcx.sess.opts.unstable_opts.trait_solver { - TraitSolver::Classic => { - // WF predicates cannot themselves make - // errors. They can only block due to - // ambiguity; otherwise, they always - // degenerate into other obligations - // (which may fail). - span_bug!(span, "WF predicate not satisfied for {:?}", ty); - } - TraitSolver::Next | TraitSolver::NextCoherence => { - // FIXME: we'll need a better message which takes into account - // which bounds actually failed to hold. - self.tcx.sess.struct_span_err( - span, - format!("the type `{ty}` is not well-formed"), - ) - } + if self.next_trait_solver() { + // FIXME: we'll need a better message which takes into account + // which bounds actually failed to hold. + self.tcx.sess.struct_span_err( + span, + format!("the type `{ty}` is not well-formed"), + ) + } else { + // WF predicates cannot themselves make + // errors. They can only block due to + // ambiguity; otherwise, they always + // degenerate into other obligations + // (which may fail). + span_bug!(span, "WF predicate not satisfied for {:?}", ty); } } @@ -984,13 +990,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool { if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() - && let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) + && let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id) && let arg = arg.peel_borrows() && let hir::ExprKind::Path(hir::QPath::Resolved( None, hir::Path { res: hir::def::Res::Local(hir_id), .. }, )) = arg.kind - && let Some(Node::Pat(pat)) = self.tcx.hir().find(*hir_id) + && let Some(Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id) && let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span) && preds.contains(&obligation.predicate) { @@ -1028,7 +1034,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id); - let body_id = match self.tcx.hir().find(hir_id) { + let body_id = match self.tcx.opt_hir_node(hir_id) { Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => { body_id } @@ -1069,7 +1075,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if !self.tcx.is_diagnostic_item(sym::Result, def.did()) { return None; } - Some(arg.as_type()?) + arg.as_type() }; let mut suggested = false; @@ -1154,7 +1160,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 Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) + && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id) && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id) { // We've reached the root of the method call chain... @@ -1560,7 +1566,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { #[instrument(skip(self), level = "debug")] fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) { - if self.tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError { + if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() + == DumpSolverProofTree::OnError + { dump_proof_tree(&error.root_obligation, self.infcx); } @@ -1666,7 +1674,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) .into(), }; - // FIXME(-Ztrait-solver=next): For diagnostic purposes, it would be nice + // FIXME(-Znext-solver): For diagnostic purposes, it would be nice // to deeply normalize this type. let normalized_term = ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term); @@ -2499,7 +2507,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ident: trait_name, kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs), .. - })) = self.tcx.hir().find_by_def_id(local_def_id) + })) = self.tcx.opt_hir_node_by_def_id(local_def_id) && let Some(method_ref) = trait_item_refs .iter() .find(|item_ref| item_ref.ident == *assoc_item_name) diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 2f2411310a9..cf4fa233768 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -9,7 +9,7 @@ use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::query::NoSolution; use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError}; -use rustc_middle::ty::{self, AdtDef, GenericArg, List, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, AdtDef, GenericArg, List, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::DUMMY_SP; use super::outlives_bounds::InferCtxtExt; @@ -209,10 +209,10 @@ pub fn all_fields_implement_trait<'tcx>( pub fn check_tys_might_be_eq<'tcx>( tcx: TyCtxt<'tcx>, - canonical: Canonical<'tcx, (ParamEnv<'tcx>, Ty<'tcx>, Ty<'tcx>)>, + canonical: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>, ) -> Result<(), NoSolution> { - let (infcx, (param_env, ty_a, ty_b), _) = - tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical); + let (infcx, key, _) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical); + let (param_env, (ty_a, ty_b)) = key.into_parts(); let ocx = ObligationCtxt::new(&infcx); let result = ocx.eq(&ObligationCause::dummy(), param_env, ty_a, ty_b); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 64d2b5fc159..8c5f1e90715 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -315,7 +315,7 @@ pub fn normalize_param_env_or_error<'tcx>( // We do not normalize types here as there is no backwards compatibility requirement // for us to do so. // - // FIXME(-Ztrait-solver=next): remove this hack since we have deferred projection equality + // FIXME(-Znext-solver): remove this hack since we have deferred projection equality predicate.fold_with(&mut ConstNormalizer(tcx)) }), ) @@ -386,7 +386,7 @@ pub fn normalize_param_env_or_error<'tcx>( /// Normalize a type and process all resulting obligations, returning any errors. /// -/// FIXME(-Ztrait-solver=next): This should be replaced by `At::deeply_normalize` +/// FIXME(-Znext-solver): This should be replaced by `At::deeply_normalize` /// which has the same behavior with the new solver. Because using a separate /// fulfillment context worsens caching in the old solver, `At::deeply_normalize` /// is still lazy with the old solver as it otherwise negatively impacts perf. diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index fbde7455145..47a79bfa9ab 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -194,7 +194,6 @@ fn lint_object_unsafe_trait( // Only provide the help if its a local trait, otherwise it's not violation.solution().add_to(err); } - err }, ); } @@ -345,7 +344,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // Search for a predicate like `Self : Sized` amongst the trait bounds. let predicates = tcx.predicates_of(def_id); let predicates = predicates.instantiate_identity(tcx).predicates; - elaborate(tcx, predicates.into_iter()).any(|pred| match pred.kind().skip_binder() { + elaborate(tcx, predicates).any(|pred| match pred.kind().skip_binder() { ty::ClauseKind::Trait(ref trait_pred) => { trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a08e35b566f..d5635812c74 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -67,7 +67,7 @@ pub trait NormalizeExt<'tcx> { /// same goals in both a temporary and the shared context which negatively impacts /// performance as these don't share caching. /// - /// FIXME(-Ztrait-solver=next): This has the same behavior as `traits::fully_normalize` + /// FIXME(-Znext-solver): This has the same behavior as `traits::fully_normalize` /// in the new solver, but because of performance reasons, we currently reuse an /// existing fulfillment context in the old solver. Once we also eagerly prove goals with /// the old solver or have removed the old solver, remove `traits::fully_normalize` and @@ -191,7 +191,9 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { match (current, candidate) { (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (), (ParamEnv(..), _) => return false, - (_, ParamEnv(..)) => unreachable!(), + (_, ParamEnv(..)) => bug!( + "should never prefer non-param-env candidates over param-env candidates" + ), (_, _) => convert_to_ambiguous = (), } } @@ -2080,10 +2082,11 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx> { - let ty::Coroutine(_, args, _) = - selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Coroutine(_, args, _) = self_ty.kind() else { + unreachable!( + "expected coroutine self type for built-in coroutine candidate, found {self_ty}" + ) }; let coroutine_sig = args.as_coroutine().sig(); let Normalized { value: coroutine_sig, obligations } = normalize_with_depth( @@ -2113,7 +2116,10 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( } else if name == sym::Yield { yield_ty } else { - bug!() + span_bug!( + tcx.def_span(obligation.predicate.def_id), + "unexpected associated type: `Coroutine::{name}`" + ); }; let predicate = ty::ProjectionPredicate { @@ -2131,10 +2137,11 @@ fn confirm_future_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx> { - let ty::Coroutine(_, args, _) = - selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Coroutine(_, args, _) = self_ty.kind() else { + unreachable!( + "expected coroutine self type for built-in async future candidate, found {self_ty}" + ) }; let coroutine_sig = args.as_coroutine().sig(); let Normalized { value: coroutine_sig, obligations } = normalize_with_depth( @@ -2174,10 +2181,9 @@ fn confirm_iterator_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx> { - let ty::Coroutine(_, args, _) = - selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Coroutine(_, args, _) = self_ty.kind() else { + unreachable!("expected coroutine self type for built-in gen candidate, found {self_ty}") }; let gen_sig = args.as_coroutine().sig(); let Normalized { value: gen_sig, obligations } = normalize_with_depth( @@ -2341,9 +2347,9 @@ fn confirm_closure_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec<PredicateObligation<'tcx>>, ) -> Progress<'tcx> { - let ty::Closure(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Closure(_, args) = self_ty.kind() else { + unreachable!("expected closure self type for closure candidate, found {self_ty}") }; let closure_sig = args.as_closure().sig(); let Normalized { value: closure_sig, obligations } = normalize_with_depth( diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index 04b3119323f..d812d537d8c 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -72,7 +72,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { let mut fulfill_cx = crate::solve::FulfillmentCtxt::new(self); fulfill_cx.register_predicate_obligation(self, obligation.clone()); // True errors - // FIXME(-Ztrait-solver=next): Overflows are reported as ambig here, is that OK? + // FIXME(-Znext-solver): Overflows are reported as ambig here, is that OK? if !fulfill_cx.select_where_possible(self).is_empty() { Ok(EvaluationResult::EvaluatedToErr) } else if !fulfill_cx.select_all_or_error(self).is_empty() { diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 4728fcf3301..ed55533bc55 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -285,7 +285,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> ty::Projection => tcx.normalize_projection_ty(c_data), ty::Weak => tcx.normalize_weak_ty(c_data), ty::Inherent => tcx.normalize_inherent_projection_ty(c_data), - _ => unreachable!(), + kind => unreachable!("did not expect {kind:?} due to match arm above"), }?; // We don't expect ambiguity. if !result.value.is_proven() { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index 302b6016e5e..152ceeee869 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -26,7 +26,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { tcx.type_op_ascribe_user_type(canonicalized) } - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution> { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs index f6589308806..57e649f3e43 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs @@ -23,7 +23,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> { tcx.type_op_eq(canonicalized) } - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution> { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index f9b8ea32d89..ba6ed298774 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -50,7 +50,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { tcx.implied_outlives_bounds(canonicalized) } - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution> { @@ -184,7 +184,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( push_outlives_components(tcx, ty_a, &mut components); implied_bounds.extend(implied_bounds_from_components(r_b, components)) } - ty::GenericArgKind::Const(_) => unreachable!(), + ty::GenericArgKind::Const(_) => { + unreachable!("consts do not participate in outlives bounds") + } } } 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 cd09aaff2d9..272f1a54f81 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 @@ -89,7 +89,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't /// make sure to feed it predefined opaque types and the defining anchor /// and that would require duplicating all of the tcx queries. Instead, /// just perform these ops locally. - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution>; @@ -149,7 +149,7 @@ where if infcx.next_trait_solver() { return Ok(scrape_region_constraints( infcx, - |ocx| QueryTypeOp::perform_locally_in_new_solver(ocx, self), + |ocx| QueryTypeOp::perform_locally_with_next_solver(ocx, self), "query type op", span, )? diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 9559f5002f6..3b33f6e6144 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -25,11 +25,11 @@ where T::type_op_method(tcx, canonicalized) } - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution> { - // FIXME(-Ztrait-solver=next): shouldn't be using old normalizer + // FIXME(-Znext-solver): shouldn't be using old normalizer Ok(ocx.normalize(&ObligationCause::dummy(), key.param_env, key.value.value)) } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index f2c1243f931..07587e37411 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs @@ -42,7 +42,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { tcx.dropck_outlives(canonicalized) } - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution> { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 789ef647246..e21ede47f6d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -40,7 +40,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { tcx.type_op_prove_predicate(canonicalized) } - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution> { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs index 10976d5cd71..ae11b0825bd 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs @@ -20,7 +20,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> { tcx.type_op_subtype(canonicalized) } - fn perform_locally_in_new_solver( + fn perform_locally_with_next_solver( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Self>, ) -> Result<Self::QueryResponse, NoSolution> { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4a342a7f6b1..7e3d304d1cd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -942,8 +942,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let a_ty = self.infcx.shallow_resolve(predicate.self_ty()); let b_ty = self.infcx.shallow_resolve(predicate.trait_ref.args.type_at(1)); - let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else { bug!() }; - let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else { bug!() }; + let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else { + bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`") + }; + let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else { + bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`") + }; let source_principal = a_data.principal().unwrap().with_self_ty(tcx, a_ty); let unnormalized_upcast_principal = diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 39f5ff52eba..71a88f5f07c 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -450,7 +450,6 @@ fn report_conflicting_impls<'tcx>( msg, |err| { decorate(tcx, &overlap, impl_span, err); - err }, ); } diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 32de8feda81..b9ab26fe2fe 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -22,7 +22,7 @@ impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> { assert!(!ty.is_ty_var(), "should have resolved vars before calling"); if self.infcx.next_trait_solver() { - // FIXME(-Ztrait-solver=next): correctly handle + // FIXME(-Znext-solver): correctly handle // overflow here. for _ in 0..256 { let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, alias) = *ty.kind() else { diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 98da3bc2fe9..575010ff46d 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -220,9 +220,8 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates); let impl_obligations = super::predicates_for_generics(cause, param_env, predicates); - let impl_obligations = impl_obligations - .chain(normalization_obligations1.into_iter()) - .chain(normalization_obligations2.into_iter()); + let impl_obligations = + impl_obligations.chain(normalization_obligations1).chain(normalization_obligations2); (subject, impl_obligations) } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 7a81570e55b..db37bec4b82 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -345,8 +345,7 @@ fn associated_type_for_impl_trait_in_impl( let impl_local_def_id = tcx.local_parent(impl_fn_def_id); let decl = tcx - .hir() - .find_by_def_id(impl_fn_def_id) + .opt_hir_node_by_def_id(impl_fn_def_id) .expect("expected item") .fn_decl() .expect("expected decl"); diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index eef90dc6dac..3f9bd509b08 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -161,7 +161,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' } fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> + '_ { - let node = tcx.hir().get(tcx.local_def_id_to_hir_id(def_id)); + let node = tcx.hir_node_by_def_id(def_id); if let Some(decl) = node.fn_decl() { decl.inputs.iter().map(|ty| ty.span).chain(iter::once(decl.output.span())) } else { diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index d896873fadd..7918965e04b 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -831,7 +831,10 @@ fn coroutine_layout<'tcx>( Assigned(_) => bug!("assignment does not match variant"), Ineligible(_) => false, }) - .map(|local| subst_field(info.field_tys[*local].ty)); + .map(|local| { + let field_ty = subst_field(info.field_tys[*local].ty); + Ty::new_maybe_uninit(tcx, field_ty) + }); let mut variant = univariant_uninterned( cx, diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 7c0261c818f..b155a4ac87b 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -28,7 +28,7 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( // Walk over the signature of the function DefKind::AssocFn | DefKind::Fn => { let ty_sig = tcx.fn_sig(item).instantiate_identity(); - let hir_sig = tcx.hir().get_by_def_id(item).fn_decl().unwrap(); + let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap(); // Walk over the inputs and outputs manually in order to get good spans for them. visitor.visit(hir_sig.output.span(), ty_sig.output()); for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) { @@ -42,7 +42,7 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( DefKind::TyAlias {..} | DefKind::AssocTy | // Walk over the type of the item DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { - let span = match tcx.hir().get_by_def_id(item).ty() { + let span = match tcx.hir_node_by_def_id(item).ty() { Some(ty) => ty.span, _ => tcx.def_span(item), }; @@ -70,11 +70,11 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( DefKind::InlineConst | DefKind::Closure => {} DefKind::Impl { of_trait } => { if of_trait { - let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span; + let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span; let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..]; visitor.visit(span, args)?; } - let span = match tcx.hir().get_by_def_id(item).ty() { + let span = match tcx.hir_node_by_def_id(item).ty() { Some(ty) => ty.span, _ => tcx.def_span(item), }; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 56e84b6015d..2158aacab03 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -74,7 +74,7 @@ fn sized_constraint_for_ty<'tcx>( } fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { - match tcx.hir().get_by_def_id(def_id) { + match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.defaultness, hir::Node::ImplItem(hir::ImplItem { defaultness, .. }) | hir::Node::TraitItem(hir::TraitItem { defaultness, .. }) => *defaultness, @@ -300,7 +300,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<' /// Check if a function is async. fn asyncness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Asyncness { - let node = tcx.hir().get_by_def_id(def_id); + let node = tcx.hir_node_by_def_id(def_id); node.fn_sig().map_or(ty::Asyncness::No, |sig| match sig.header.asyncness { hir::IsAsync::Async(_) => ty::Asyncness::Yes, hir::IsAsync::NotAsync => ty::Asyncness::No, diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs index 8998001ec20..9c8e45b4338 100644 --- a/compiler/rustc_type_ir/src/debug.rs +++ b/compiler/rustc_type_ir/src/debug.rs @@ -32,11 +32,7 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> { None } - fn root_lt_var(&self, vid: I::InferRegion) -> I::InferRegion { - vid - } - - fn probe_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> { + fn opportunistic_resolve_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> { None } diff --git a/compiler/rustc_type_ir/src/infcx.rs b/compiler/rustc_type_ir/src/infcx.rs index 681f129a50b..28b71f0ea13 100644 --- a/compiler/rustc_type_ir/src/infcx.rs +++ b/compiler/rustc_type_ir/src/infcx.rs @@ -18,14 +18,14 @@ pub trait InferCtxtLike { lt: <Self::Interner as Interner>::InferRegion, ) -> Option<UniverseIndex>; - /// Resolve `InferRegion` to its root `InferRegion`. - fn root_lt_var( - &self, - vid: <Self::Interner as Interner>::InferRegion, - ) -> <Self::Interner as Interner>::InferRegion; - - /// Resolve `InferRegion` to its inferred region, if it has been equated with a non-infer region. - fn probe_lt_var( + /// Resolve `InferRegion` to its inferred region, if it has been equated with + /// a non-infer region. + /// + /// FIXME: This has slightly different semantics than `{probe,resolve}_{ty,ct}_var`, + /// that has to do with the fact unlike `Ty` or `Const` vars, in rustc, we may + /// not always be able to *name* the root region var from the universe of the + /// var we're trying to resolve. That's why it's called *opportunistic*. + fn opportunistic_resolve_lt_var( &self, vid: <Self::Interner as Interner>::InferRegion, ) -> Option<<Self::Interner as Interner>::Region>; diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index c262302133b..188910ecc52 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -3,8 +3,8 @@ use std::fmt::Debug; use std::hash::Hash; use crate::{ - BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, Mutability, RegionKind, - TyKind, UniverseIndex, + BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind, + UniverseIndex, }; pub trait Interner: Sized { @@ -20,7 +20,6 @@ pub trait Interner: Sized { type Term: Copy + Debug + Hash + Ord; type Binder<T>; - type TypeAndMut: Copy + Debug + Hash + Ord; type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>; // Kinds of tys @@ -81,8 +80,6 @@ pub trait Interner: Sized { type CoercePredicate: Copy + Debug + Hash + Eq; type ClosureKind: Copy + Debug + Hash + Eq; - fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability); - fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars; // FIXME: We should not have all these constructors on `Interner`, but as functions on some trait. diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 200963ff7c5..bff93859645 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -359,3 +359,45 @@ rustc_index::newtype_index! { #[gate_rustc_only] pub struct BoundVar {} } + +/// Represents the various closure traits in the language. This +/// will determine the type of the environment (`self`, in the +/// desugaring) argument that the closure expects. +/// +/// You can get the environment type of a closure using +/// `tcx.closure_env_ty()`. +#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] +pub enum ClosureKind { + // Warning: Ordering is significant here! The ordering is chosen + // because the trait Fn is a subtrait of FnMut and so in turn, and + // hence we order it so that Fn < FnMut < FnOnce. + Fn, + FnMut, + FnOnce, +} + +impl ClosureKind { + /// This is the initial value used when doing upvar inference. + pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn; + + pub const fn as_str(self) -> &'static str { + match self { + ClosureKind::Fn => "Fn", + ClosureKind::FnMut => "FnMut", + ClosureKind::FnOnce => "FnOnce", + } + } + + /// Returns `true` if a type that impls this closure kind + /// must also implement `other`. + pub fn extends(self, other: ClosureKind) -> bool { + self <= other + } +} + +impl fmt::Display for ClosureKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.as_str().fmt(f) + } +} diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index cfed84a35c6..82bb1bf2916 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -51,4 +51,6 @@ TrivialTypeTraversalImpls! { crate::DebruijnIndex, crate::AliasRelationDirection, crate::UniverseIndex, + crate::Mutability, + crate::Movability, } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 72ca9199a53..70adfbee2ed 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -4,6 +4,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; use std::fmt; +use crate::fold::{FallibleTypeFolder, TypeFoldable}; +use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx}; @@ -158,7 +160,7 @@ pub enum TyKind<I: Interner> { Slice(I::Ty), /// A raw pointer. Written as `*mut T` or `*const T` - RawPtr(I::TypeAndMut), + RawPtr(TypeAndMut<I>), /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. @@ -410,8 +412,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> { Str => write!(f, "str"), Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)), Slice(t) => write!(f, "[{:?}]", &this.wrap(t)), - RawPtr(p) => { - let (ty, mutbl) = I::ty_and_mut_to_parts(*p); + RawPtr(TypeAndMut { ty, mutbl }) => { match mutbl { Mutability::Mut => write!(f, "*mut "), Mutability::Not => write!(f, "*const "), @@ -831,3 +832,42 @@ impl<I: Interner> DebugWithInfcx<I> for InferTy { } } } + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + PartialOrd(bound = ""), + Ord(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Hash(bound = ""), + Debug(bound = "") +)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub struct TypeAndMut<I: Interner> { + pub ty: I::Ty, + pub mutbl: Mutability, +} + +impl<I: Interner> TypeFoldable<I> for TypeAndMut<I> +where + I::Ty: TypeFoldable<I>, +{ + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + Ok(TypeAndMut { + ty: self.ty.try_fold_with(folder)?, + mutbl: self.mutbl.try_fold_with(folder)?, + }) + } +} + +impl<I: Interner> TypeVisitable<I> for TypeAndMut<I> +where + I::Ty: TypeVisitable<I>, +{ + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> std::ops::ControlFlow<V::BreakTy> { + self.ty.visit_with(visitor)?; + self.mutbl.visit_with(visitor) + } +} diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 3dfe7096399..5023af9ab79 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -22,6 +22,11 @@ pub struct Body { /// Debug information pertaining to user variables, including captures. pub var_debug_info: Vec<VarDebugInfo>, + + /// Mark an argument (which must be a tuple) as getting passed as its individual components. + /// + /// This is used for the "rust-call" ABI such as closures. + pub(super) spread_arg: Option<Local>, } pub type BasicBlockIdx = usize; @@ -36,6 +41,7 @@ impl Body { locals: LocalDecls, arg_count: usize, var_debug_info: Vec<VarDebugInfo>, + spread_arg: Option<Local>, ) -> Self { // If locals doesn't contain enough entries, it can lead to panics in // `ret_local`, `arg_locals`, and `inner_locals`. @@ -43,7 +49,7 @@ impl Body { locals.len() > arg_count, "A Body must contain at least a local for the return value and each of the function's arguments" ); - Self { blocks, locals, arg_count, var_debug_info } + Self { blocks, locals, arg_count, var_debug_info, spread_arg } } /// Return local that holds this function's return value. @@ -75,6 +81,11 @@ impl Body { self.locals.get(local) } + /// Get an iterator for all local declarations. + pub fn local_decls(&self) -> impl Iterator<Item = (Local, &LocalDecl)> { + self.locals.iter().enumerate() + } + pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> { writeln!(w, "{}", function_body(self))?; self.blocks @@ -98,6 +109,10 @@ impl Body { .collect::<Result<Vec<_>, _>>()?; Ok(()) } + + pub fn spread_arg(&self) -> Option<Local> { + self.spread_arg + } } type LocalDecls = Vec<LocalDecl>; @@ -248,6 +263,57 @@ pub enum AssertMessage { MisalignedPointerDereference { required: Operand, found: Operand }, } +impl AssertMessage { + pub fn description(&self) -> Result<&'static str, Error> { + match self { + AssertMessage::Overflow(BinOp::Add, _, _) => Ok("attempt to add with overflow"), + AssertMessage::Overflow(BinOp::Sub, _, _) => Ok("attempt to subtract with overflow"), + AssertMessage::Overflow(BinOp::Mul, _, _) => Ok("attempt to multiply with overflow"), + AssertMessage::Overflow(BinOp::Div, _, _) => Ok("attempt to divide with overflow"), + AssertMessage::Overflow(BinOp::Rem, _, _) => { + Ok("attempt to calculate the remainder with overflow") + } + AssertMessage::OverflowNeg(_) => Ok("attempt to negate with overflow"), + AssertMessage::Overflow(BinOp::Shr, _, _) => Ok("attempt to shift right with overflow"), + AssertMessage::Overflow(BinOp::Shl, _, _) => Ok("attempt to shift left with overflow"), + AssertMessage::Overflow(op, _, _) => Err(error!("`{:?}` cannot overflow", op)), + AssertMessage::DivisionByZero(_) => Ok("attempt to divide by zero"), + AssertMessage::RemainderByZero(_) => { + Ok("attempt to calculate the remainder with a divisor of zero") + } + AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine) => { + Ok("coroutine resumed after completion") + } + AssertMessage::ResumedAfterReturn(CoroutineKind::Async(_)) => { + Ok("`async fn` resumed after completion") + } + AssertMessage::ResumedAfterReturn(CoroutineKind::Gen(_)) => { + Ok("`async gen fn` resumed after completion") + } + AssertMessage::ResumedAfterReturn(CoroutineKind::AsyncGen(_)) => { + Ok("`gen fn` should just keep returning `AssertMessage::None` after completion") + } + AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine) => { + Ok("coroutine resumed after panicking") + } + AssertMessage::ResumedAfterPanic(CoroutineKind::Async(_)) => { + Ok("`async fn` resumed after panicking") + } + AssertMessage::ResumedAfterPanic(CoroutineKind::Gen(_)) => { + Ok("`async gen fn` resumed after panicking") + } + AssertMessage::ResumedAfterPanic(CoroutineKind::AsyncGen(_)) => { + Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking") + } + + AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"), + AssertMessage::MisalignedPointerDereference { .. } => { + Ok("misaligned pointer dereference") + } + } + } +} + #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum BinOp { Add, @@ -325,6 +391,7 @@ pub enum CoroutineKind { Async(CoroutineSource), Coroutine, Gen(CoroutineSource), + AsyncGen(CoroutineSource), } #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs index bc5d4a3b8f4..c126de23c4b 100644 --- a/compiler/stable_mir/src/mir/mono.rs +++ b/compiler/stable_mir/src/mir/mono.rs @@ -1,6 +1,6 @@ use crate::crate_def::CrateDef; use crate::mir::Body; -use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, FnSig, GenericArgs, IndexedVal, Ty}; +use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty}; use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol}; use std::fmt::{Debug, Formatter}; @@ -115,11 +115,6 @@ impl Instance { }) } - /// Get this function signature with all types already instantiated. - pub fn fn_sig(&self) -> FnSig { - self.ty().kind().fn_sig().unwrap().skip_binder() - } - /// Check whether this instance is an empty shim. /// /// Allow users to check if this shim can be ignored when called directly. diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 3a0eed521dc..8b7b488d312 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -58,18 +58,35 @@ pub fn pretty_statement(statement: &StatementKind) -> String { pretty.push_str(format!(" _{} = ", place.local).as_str()); pretty.push_str(format!("{}", &pretty_rvalue(rval)).as_str()); } - StatementKind::FakeRead(_, _) => todo!(), - StatementKind::SetDiscriminant { .. } => todo!(), - StatementKind::Deinit(_) => todo!(), - StatementKind::StorageLive(_) => todo!(), - StatementKind::StorageDead(_) => todo!(), - StatementKind::Retag(_, _) => todo!(), - StatementKind::PlaceMention(_) => todo!(), - StatementKind::AscribeUserType { .. } => todo!(), - StatementKind::Coverage(_) => todo!(), - StatementKind::Intrinsic(_) => todo!(), - StatementKind::ConstEvalCounter => (), - StatementKind::Nop => (), + // FIXME: Add rest of the statements + StatementKind::FakeRead(_, _) => { + return String::from("StatementKind::FakeRead:Unimplemented"); + } + StatementKind::SetDiscriminant { .. } => { + return String::from("StatementKind::SetDiscriminant:Unimplemented"); + } + StatementKind::Deinit(_) => return String::from("StatementKind::Deinit:Unimplemented"), + StatementKind::StorageLive(_) => { + return String::from("StatementKind::StorageLive:Unimplemented"); + } + StatementKind::StorageDead(_) => { + return String::from("StatementKind::StorageDead:Unimplemented"); + } + StatementKind::Retag(_, _) => return String::from("StatementKind::Retag:Unimplemented"), + StatementKind::PlaceMention(_) => { + return String::from("StatementKind::PlaceMention:Unimplemented"); + } + StatementKind::AscribeUserType { .. } => { + return String::from("StatementKind::AscribeUserType:Unimplemented"); + } + StatementKind::Coverage(_) => return String::from("StatementKind::Coverage:Unimplemented"), + StatementKind::Intrinsic(_) => { + return String::from("StatementKind::Intrinsic:Unimplemented"); + } + StatementKind::ConstEvalCounter => { + return String::from("StatementKind::ConstEvalCounter:Unimplemented"); + } + StatementKind::Nop => return String::from("StatementKind::Nop:Unimplemented"), } pretty } @@ -243,6 +260,7 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String { ); pretty } + AssertMessage::Overflow(op, _, _) => unreachable!("`{:?}` cannot overflow", op), AssertMessage::OverflowNeg(op) => { let pretty_op = pretty_operand(op); pretty.push_str( @@ -262,17 +280,15 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String { ); pretty } - AssertMessage::ResumedAfterReturn(_) => { - format!("attempt to resume a generator after completion") - } - AssertMessage::ResumedAfterPanic(_) => format!("attempt to resume a panicked generator"), AssertMessage::MisalignedPointerDereference { required, found } => { let pretty_required = pretty_operand(required); let pretty_found = pretty_operand(found); pretty.push_str(format!("\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}").as_str()); pretty } - _ => todo!(), + AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => { + msg.description().unwrap().to_string() + } } } @@ -355,7 +371,7 @@ pub fn pretty_rvalue(rval: &Rvalue) -> String { pretty.push_str(" "); pretty.push_str(&pretty_ty(cnst.ty().kind())); } - Rvalue::ShallowInitBox(_, _) => todo!(), + Rvalue::ShallowInitBox(_, _) => (), Rvalue::ThreadLocalRef(item) => { pretty.push_str("thread_local_ref"); pretty.push_str(format!("{:#?}", item).as_str()); diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index d46caad9a01..98336a72900 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -133,7 +133,7 @@ pub trait MirVisitor { } fn super_body(&mut self, body: &Body) { - let Body { blocks, locals: _, arg_count, var_debug_info } = body; + let Body { blocks, locals: _, arg_count, var_debug_info, spread_arg: _ } = body; for bb in blocks { self.visit_basic_block(bb); diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index f473fd8dbb7..3d5e264104b 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -22,9 +22,7 @@ impl Debug for Ty { /// Constructors for `Ty`. impl Ty { /// Create a new type from a given kind. - /// - /// Note that not all types may be supported at this point. - fn from_rigid_kind(kind: RigidTy) -> Ty { + pub fn from_rigid_kind(kind: RigidTy) -> Ty { with(|cx| cx.new_rigid_ty(kind)) } @@ -77,6 +75,16 @@ impl Ty { pub fn bool_ty() -> Ty { Ty::from_rigid_kind(RigidTy::Bool) } + + /// Create a type representing a signed integer. + pub fn signed_ty(inner: IntTy) -> Ty { + Ty::from_rigid_kind(RigidTy::Int(inner)) + } + + /// Create a type representing an unsigned integer. + pub fn unsigned_ty(inner: UintTy) -> Ty { + Ty::from_rigid_kind(RigidTy::Uint(inner)) + } } impl Ty { diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 62856fc9a49..4a4a3abd47f 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -421,7 +421,7 @@ impl CString { /// Failure to call [`CString::from_raw`] will lead to a memory leak. /// /// The C side must **not** modify the length of the string (by writing a - /// `null` somewhere inside the string or removing the final one) before + /// nul byte somewhere inside the string or removing the final one) before /// it makes it back into Rust using [`CString::from_raw`]. See the safety section /// in [`CString::from_raw`]. /// @@ -797,7 +797,7 @@ impl From<Box<CStr>> for CString { #[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")] impl From<Vec<NonZeroU8>> for CString { /// Converts a <code>[Vec]<[NonZeroU8]></code> into a [`CString`] without - /// copying nor checking for inner null bytes. + /// copying nor checking for inner nul bytes. #[inline] fn from(v: Vec<NonZeroU8>) -> CString { unsafe { @@ -809,7 +809,7 @@ impl From<Vec<NonZeroU8>> for CString { let (ptr, len, cap): (*mut NonZeroU8, _, _) = Vec::into_raw_parts(v); Vec::from_raw_parts(ptr.cast::<u8>(), len, cap) }; - // SAFETY: `v` cannot contain null bytes, given the type-level + // SAFETY: `v` cannot contain nul bytes, given the type-level // invariant of `NonZeroU8`. Self::_from_vec_unchecked(v) } diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 22777fb078a..c82984d5c6b 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -695,44 +695,41 @@ pub const fn type_name<T: ?Sized>() -> &'static str { intrinsics::type_name::<T>() } -/// Returns the name of the type of the pointed-to value as a string slice. +/// Returns the type name of the pointed-to value as a string slice. +/// /// This is the same as `type_name::<T>()`, but can be used where the type of a /// variable is not easily available. /// /// # Note /// -/// This is intended for diagnostic use. The exact contents and format of the -/// string are not specified, other than being a best-effort description of the -/// type. For example, `type_name_of_val::<Option<String>>(None)` could return -/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not -/// `"foobar"`. In addition, the output may change between versions of the -/// compiler. -/// -/// This function does not resolve trait objects, -/// meaning that `type_name_of_val(&7u32 as &dyn Debug)` -/// may return `"dyn Debug"`, but not `"u32"`. +/// Like [`type_name`], this is intended for diagnostic use and the exact output is not +/// guaranteed. It provides a best-effort description, but the output may change between +/// versions of the compiler. /// -/// The type name should not be considered a unique identifier of a type; -/// multiple types may share the same type name. +/// In short: use this for debugging, avoid using the output to affect program behavior. More +/// information is available at [`type_name`]. /// -/// The current implementation uses the same infrastructure as compiler -/// diagnostics and debuginfo, but this is not guaranteed. +/// Additionally, this function does not resolve trait objects. This means that +/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"` +/// at this time. /// /// # Examples /// /// Prints the default integer and float types. /// /// ```rust -/// #![feature(type_name_of_val)] /// use std::any::type_name_of_val; /// -/// let x = 1; -/// println!("{}", type_name_of_val(&x)); -/// let y = 1.0; -/// println!("{}", type_name_of_val(&y)); +/// let s = "foo"; +/// let x: i32 = 1; +/// let y: f32 = 1.0; +/// +/// assert!(type_name_of_val(&s).contains("str")); +/// assert!(type_name_of_val(&x).contains("i32")); +/// assert!(type_name_of_val(&y).contains("f32")); /// ``` #[must_use] -#[unstable(feature = "type_name_of_val", issue = "66359")] +#[stable(feature = "type_name_of_val", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str { type_name::<T>() diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index e7ec1fb73cd..bb839a71e90 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -205,7 +205,7 @@ impl CStr { /// * The memory pointed to by `ptr` must contain a valid nul terminator at the /// end of the string. /// - /// * `ptr` must be [valid] for reads of bytes up to and including the null terminator. + /// * `ptr` must be [valid] for reads of bytes up to and including the nul terminator. /// This means in particular: /// /// * The entire memory range of this `CStr` must be contained within a single allocated object! @@ -415,7 +415,7 @@ impl CStr { let mut i = bytes.len().saturating_sub(1); assert!(!bytes.is_empty() && bytes[i] == 0, "input was not nul-terminated"); - // Ending null byte exists, skip to the rest. + // Ending nul byte exists, skip to the rest. while i != 0 { i -= 1; let byte = bytes[i]; diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 778515f8616..ab2158394bf 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -15,7 +15,7 @@ trait DisplayInt: fn zero() -> Self; fn from_u8(u: u8) -> Self; fn to_u8(&self) -> u8; - fn to_u16(&self) -> u16; + #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] fn to_u32(&self) -> u32; fn to_u64(&self) -> u64; fn to_u128(&self) -> u128; @@ -27,7 +27,7 @@ macro_rules! impl_int { fn zero() -> Self { 0 } fn from_u8(u: u8) -> Self { u as Self } fn to_u8(&self) -> u8 { *self as u8 } - fn to_u16(&self) -> u16 { *self as u16 } + #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] fn to_u32(&self) -> u32 { *self as u32 } fn to_u64(&self) -> u64 { *self as u64 } fn to_u128(&self) -> u128 { *self as u128 } @@ -40,7 +40,7 @@ macro_rules! impl_uint { fn zero() -> Self { 0 } fn from_u8(u: u8) -> Self { u as Self } fn to_u8(&self) -> u8 { *self as u8 } - fn to_u16(&self) -> u16 { *self as u16 } + #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] fn to_u32(&self) -> u32 { *self as u32 } fn to_u64(&self) -> u64 { *self as u64 } fn to_u128(&self) -> u128 { *self as u128 } diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index dafc58d3a7d..8bf15c736c3 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -1437,7 +1437,7 @@ impl Ipv6Addr { /// - The [unspecified address] ([`is_unspecified`](Ipv6Addr::is_unspecified)) /// - The [loopback address] ([`is_loopback`](Ipv6Addr::is_loopback)) /// - IPv4-mapped addresses - /// - Addresses reserved for benchmarking + /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv6Addr::is_benchmarking)) /// - Addresses reserved for documentation ([`is_documentation`](Ipv6Addr::is_documentation)) /// - Unique local addresses ([`is_unique_local`](Ipv6Addr::is_unique_local)) /// - Unicast addresses with link-local scope ([`is_unicast_link_local`](Ipv6Addr::is_unicast_link_local)) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index d6603681a0b..eed793186b9 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -720,7 +720,8 @@ where /// type or mutability, in particular if the code is refactored. #[inline(always)] #[must_use] -#[unstable(feature = "ptr_from_ref", issue = "106116")] +#[stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")] #[rustc_never_returns_null_ptr] #[rustc_diagnostic_item = "ptr_from_ref"] pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { @@ -733,7 +734,9 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { /// type or mutability, in particular if the code is refactored. #[inline(always)] #[must_use] -#[unstable(feature = "ptr_from_ref", issue = "106116")] +#[stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")] +#[rustc_allow_const_fn_unstable(const_mut_refs)] #[rustc_never_returns_null_ptr] pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T { r diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 4cfccd2e3ce..ce04a9f4089 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -125,6 +125,7 @@ impl [u8] { /// assert_eq!(b"".trim_ascii_start(), b""); /// ``` #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[inline] pub const fn trim_ascii_start(&self) -> &[u8] { let mut bytes = self; // Note: A pattern matching based approach (instead of indexing) allows @@ -154,6 +155,7 @@ impl [u8] { /// assert_eq!(b"".trim_ascii_end(), b""); /// ``` #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[inline] pub const fn trim_ascii_end(&self) -> &[u8] { let mut bytes = self; // Note: A pattern matching based approach (instead of indexing) allows @@ -184,6 +186,7 @@ impl [u8] { /// assert_eq!(b"".trim_ascii(), b""); /// ``` #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[inline] pub const fn trim_ascii(&self) -> &[u8] { self.trim_ascii_start().trim_ascii_end() } diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 27178328be5..a22c46edce2 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2423,6 +2423,85 @@ impl str { me.make_ascii_lowercase() } + /// Returns a string slice with leading ASCII whitespace removed. + /// + /// 'Whitespace' refers to the definition used by + /// [`u8::is_ascii_whitespace`]. + /// + /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_slice_trim_ascii)] + /// + /// assert_eq!(" \t \u{3000}hello world\n".trim_ascii_start(), "\u{3000}hello world\n"); + /// assert_eq!(" ".trim_ascii_start(), ""); + /// assert_eq!("".trim_ascii_start(), ""); + /// ``` + #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[must_use = "this returns the trimmed string as a new slice, \ + without modifying the original"] + #[inline] + pub const fn trim_ascii_start(&self) -> &str { + // SAFETY: Removing ASCII characters from a `&str` does not invalidate + // UTF-8. + unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_start()) } + } + + /// Returns a string slice with trailing ASCII whitespace removed. + /// + /// 'Whitespace' refers to the definition used by + /// [`u8::is_ascii_whitespace`]. + /// + /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_slice_trim_ascii)] + /// + /// assert_eq!("\r hello world\u{3000}\n ".trim_ascii_end(), "\r hello world\u{3000}"); + /// assert_eq!(" ".trim_ascii_end(), ""); + /// assert_eq!("".trim_ascii_end(), ""); + /// ``` + #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[must_use = "this returns the trimmed string as a new slice, \ + without modifying the original"] + #[inline] + pub const fn trim_ascii_end(&self) -> &str { + // SAFETY: Removing ASCII characters from a `&str` does not invalidate + // UTF-8. + unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_end()) } + } + + /// Returns a string slice with leading and trailing ASCII whitespace + /// removed. + /// + /// 'Whitespace' refers to the definition used by + /// [`u8::is_ascii_whitespace`]. + /// + /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_slice_trim_ascii)] + /// + /// assert_eq!("\r hello world\n ".trim_ascii(), "hello world"); + /// assert_eq!(" ".trim_ascii(), ""); + /// assert_eq!("".trim_ascii(), ""); + /// ``` + #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[must_use = "this returns the trimmed string as a new slice, \ + without modifying the original"] + #[inline] + pub const fn trim_ascii(&self) -> &str { + // SAFETY: Removing ASCII characters from a `&str` does not invalidate + // UTF-8. + unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii()) } + } + /// Return an iterator that escapes each char in `self` with [`char::escape_debug`]. /// /// Note: only extended grapheme codepoints that begin the string will be diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 1a11291e86b..9c41b8b4f46 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -48,7 +48,7 @@ impl RawWaker { /// Get the `data` pointer used to create this `RawWaker`. #[inline] #[must_use] - #[unstable(feature = "waker_getters", issue = "87021")] + #[unstable(feature = "waker_getters", issue = "96992")] pub fn data(&self) -> *const () { self.data } @@ -56,7 +56,7 @@ impl RawWaker { /// Get the `vtable` pointer used to create this `RawWaker`. #[inline] #[must_use] - #[unstable(feature = "waker_getters", issue = "87021")] + #[unstable(feature = "waker_getters", issue = "96992")] pub fn vtable(&self) -> &'static RawWakerVTable { self.vtable } @@ -371,7 +371,7 @@ impl Waker { /// Get a reference to the underlying [`RawWaker`]. #[inline] #[must_use] - #[unstable(feature = "waker_getters", issue = "87021")] + #[unstable(feature = "waker_getters", issue = "96992")] pub fn as_raw(&self) -> &RawWaker { &self.waker } diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 765f73636fb..3689312e6ae 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -8,6 +8,7 @@ use crate::marker::{StructuralEq, StructuralPartialEq}; // // Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C) // will implement everything for (A, B, C), (A, B) and (A,). +#[cfg(bootstrap)] macro_rules! tuple_impls { // Stopping criteria (1-ary tuple) ($T:ident) => { @@ -142,6 +143,148 @@ macro_rules! tuple_impls { } } +// Recursive macro for implementing n-ary tuple functions and operations +// +// Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C) +// will implement everything for (A, B, C), (A, B) and (A,). +#[cfg(not(bootstrap))] +macro_rules! tuple_impls { + // Stopping criteria (1-ary tuple) + ($T:ident) => { + tuple_impls!(@impl $T); + }; + // Running criteria (n-ary tuple, with n >= 2) + ($T:ident $( $U:ident )+) => { + tuple_impls!($( $U )+); + tuple_impls!(@impl $T $( $U )+); + }; + // "Private" internal implementation + (@impl $( $T:ident )+) => { + maybe_tuple_doc! { + $($T)+ @ + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T: PartialEq),+> PartialEq for ($($T,)+) + where + last_type!($($T,)+): ?Sized + { + #[inline] + fn eq(&self, other: &($($T,)+)) -> bool { + $( ${ignore($T)} self.${index()} == other.${index()} )&&+ + } + #[inline] + fn ne(&self, other: &($($T,)+)) -> bool { + $( ${ignore($T)} self.${index()} != other.${index()} )||+ + } + } + } + + maybe_tuple_doc! { + $($T)+ @ + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T: Eq),+> Eq for ($($T,)+) + where + last_type!($($T,)+): ?Sized + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+) + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + impl<$($T),+> StructuralPartialEq for ($($T,)+) + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + impl<$($T),+> StructuralEq for ($($T,)+) + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+) + where + last_type!($($T,)+): ?Sized + { + #[inline] + fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> { + lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+) + } + #[inline] + fn lt(&self, other: &($($T,)+)) -> bool { + lexical_ord!(lt, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + } + #[inline] + fn le(&self, other: &($($T,)+)) -> bool { + lexical_ord!(le, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + } + #[inline] + fn ge(&self, other: &($($T,)+)) -> bool { + lexical_ord!(ge, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + } + #[inline] + fn gt(&self, other: &($($T,)+)) -> bool { + lexical_ord!(gt, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + } + } + } + + maybe_tuple_doc! { + $($T)+ @ + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T: Ord),+> Ord for ($($T,)+) + where + last_type!($($T,)+): ?Sized + { + #[inline] + fn cmp(&self, other: &($($T,)+)) -> Ordering { + lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+) + } + } + } + + maybe_tuple_doc! { + $($T)+ @ + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T: Default),+> Default for ($($T,)+) { + #[inline] + fn default() -> ($($T,)+) { + ($({ let x: $T = Default::default(); x},)+) + } + } + } + + #[stable(feature = "array_tuple_conv", since = "1.71.0")] + impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) { + #[inline] + #[allow(non_snake_case)] + fn from(array: [T; ${count($T)}]) -> Self { + let [$($T,)+] = array; + ($($T,)+) + } + } + + #[stable(feature = "array_tuple_conv", since = "1.71.0")] + impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] { + #[inline] + #[allow(non_snake_case)] + fn from(tuple: ($(${ignore($T)} T,)+)) -> Self { + let ($($T,)+) = tuple; + [$($T,)+] + } + } + } +} + // If this is a unary tuple, it adds a doc comment. // Otherwise, it hides the docs entirely. macro_rules! maybe_tuple_doc { diff --git a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs index bd8a38e350d..dac013cc98d 100644 --- a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs +++ b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs @@ -55,7 +55,7 @@ where 16 => transize(vqtbl1q_u8, self, idxs), #[cfg(all(target_feature = "avx2", not(target_feature = "avx512vbmi")))] 32 => transize_raw(avx2_pshufb, self, idxs), - #[cfg(target_feature = "avx512vl,avx512vbmi")] + #[cfg(all(target_feature = "avx512vl", target_feature = "avx512vbmi"))] 32 => transize(x86::_mm256_permutexvar_epi8, self, idxs), // Notable absence: avx512bw shuffle // If avx512bw is available, odds of avx512vbmi are good diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f666b18887c..fe66788b564 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -30,8 +30,13 @@ rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] } [target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies] miniz_oxide = { version = "0.7.0", optional = true, default-features = false } addr2line = { version = "0.21.0", optional = true, default-features = false } + +[target.'cfg(all(not(target_os = "aix"), not(all(windows, target_env = "msvc", not(target_vendor = "uwp")))))'.dependencies] object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] } +[target.'cfg(target_os = "aix")'.dependencies] +object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'xcoff', 'unaligned', 'archive'] } + [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } rand_xorshift = "0.3.0" diff --git a/library/std/src/env.rs b/library/std/src/env.rs index f67f6034d34..30ac0512348 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -313,17 +313,32 @@ impl Error for VarError { /// Sets the environment variable `key` to the value `value` for the currently running /// process. /// -/// Note that while concurrent access to environment variables is safe in Rust, -/// some platforms only expose inherently unsafe non-threadsafe APIs for -/// inspecting the environment. As a result, extra care needs to be taken when -/// auditing calls to unsafe external FFI functions to ensure that any external -/// environment accesses are properly synchronized with accesses in Rust. +/// # Safety +/// +/// Even though this function is currently not marked as `unsafe`, it needs to +/// be because invoking it can cause undefined behaviour. The function will be +/// marked `unsafe` in a future version of Rust. This is tracked in +/// [rust#27970](https://github.com/rust-lang/rust/issues/27970). +/// +/// This function is safe to call in a single-threaded program. +/// +/// In multi-threaded programs, you must ensure that are no other threads +/// concurrently writing or *reading*(!) from the environment through functions +/// other than the ones in this module. You are responsible for figuring out +/// how to achieve this, but we strongly suggest not using `set_var` or +/// `remove_var` in multi-threaded programs at all. +/// +/// Most C libraries, including libc itself do not advertise which functions +/// read from the environment. Even functions from the Rust standard library do +/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`]. /// /// Discussion of this unsafety on Unix may be found in: /// /// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188) /// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2) /// +/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs +/// /// # Panics /// /// This function may panic if `key` is empty, contains an ASCII equals sign `'='` @@ -351,17 +366,32 @@ fn _set_var(key: &OsStr, value: &OsStr) { /// Removes an environment variable from the environment of the currently running process. /// -/// Note that while concurrent access to environment variables is safe in Rust, -/// some platforms only expose inherently unsafe non-threadsafe APIs for -/// inspecting the environment. As a result extra care needs to be taken when -/// auditing calls to unsafe external FFI functions to ensure that any external -/// environment accesses are properly synchronized with accesses in Rust. +/// # Safety +/// +/// Even though this function is currently not marked as `unsafe`, it needs to +/// be because invoking it can cause undefined behaviour. The function will be +/// marked `unsafe` in a future version of Rust. This is tracked in +/// [rust#27970](https://github.com/rust-lang/rust/issues/27970). +/// +/// This function is safe to call in a single-threaded program. +/// +/// In multi-threaded programs, you must ensure that are no other threads +/// concurrently writing or *reading*(!) from the environment through functions +/// other than the ones in this module. You are responsible for figuring out +/// how to achieve this, but we strongly suggest not using `set_var` or +/// `remove_var` in multi-threaded programs at all. +/// +/// Most C libraries, including libc itself do not advertise which functions +/// read from the environment. Even functions from the Rust standard library do +/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`]. /// /// Discussion of this unsafety on Unix may be found in: /// /// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188) /// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2) /// +/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs +/// /// # Panics /// /// This function may panic if `key` is empty, contains an ASCII equals sign diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 3b6fbf95faf..12afdef2669 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -22,7 +22,7 @@ use crate::os::unix::fs::symlink as symlink_file; #[cfg(unix)] use crate::os::unix::fs::symlink as symlink_junction; #[cfg(windows)] -use crate::os::windows::fs::{symlink_dir, symlink_file}; +use crate::os::windows::fs::{symlink_dir, symlink_file, OpenOptionsExt}; #[cfg(windows)] use crate::sys::fs::symlink_junction; #[cfg(target_os = "macos")] @@ -1793,3 +1793,28 @@ fn windows_unix_socket_exists() { assert_eq!(socket_path.try_exists().unwrap(), true); assert_eq!(socket_path.metadata().is_ok(), true); } + +#[cfg(windows)] +#[test] +fn test_hidden_file_truncation() { + // Make sure that File::create works on an existing hidden file. See #115745. + let tmpdir = tmpdir(); + let path = tmpdir.join("hidden_file.txt"); + + // Create a hidden file. + const FILE_ATTRIBUTE_HIDDEN: u32 = 2; + let mut file = OpenOptions::new() + .write(true) + .create_new(true) + .attributes(FILE_ATTRIBUTE_HIDDEN) + .open(&path) + .unwrap(); + file.write("hidden world!".as_bytes()).unwrap(); + file.flush().unwrap(); + drop(file); + + // Create a new file by truncating the existing one. + let file = File::create(&path).unwrap(); + let metadata = file.metadata().unwrap(); + assert_eq!(metadata.len(), 0); +} diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 52b1fe822d6..76081833e05 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -308,6 +308,7 @@ // // Library features (core): // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(c_str_literals))] #![feature(char_internals)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] @@ -337,7 +338,6 @@ #![feature(portable_simd)] #![feature(prelude_2024)] #![feature(ptr_as_uninit)] -#![feature(ptr_from_ref)] #![feature(raw_os_nonzero)] #![feature(round_ties_even)] #![feature(slice_internals)] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 55f4917a937..66b4ec37c8e 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -588,7 +588,7 @@ pub fn panicking() -> bool { } /// Entry point of panics from the core crate (`panic_impl` lang item). -#[cfg(not(test))] +#[cfg(not(any(test, doctest)))] #[panic_handler] pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { struct FormatStringPayload<'a> { @@ -669,7 +669,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { /// panic!() and assert!(). In particular, this is the only entry point that supports /// arbitrary payloads, not just format strings. #[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")] -#[cfg_attr(not(test), lang = "begin_panic")] +#[cfg_attr(not(any(test, doctest)), lang = "begin_panic")] // lang item for CTFE panic support // never inline unless panic_immediate_abort to avoid code // bloat at the call sites as much as possible diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 6004ed51bd1..4a7f5d8e0be 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -2311,7 +2311,7 @@ pub fn id() -> u32 { /// of the `main` function, this trait is likely to be available only on /// standard library's runtime for convenience. Other runtimes are not required /// to provide similar functionality. -#[cfg_attr(not(test), lang = "termination")] +#[cfg_attr(not(any(test, doctest)), lang = "termination")] #[stable(feature = "termination_trait_lib", since = "1.61.0")] #[rustc_on_unimplemented(on( cause = "MainFunctionType", diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index 5c83f72f3c1..335944845ae 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -154,8 +154,7 @@ fn lang_start_internal( ret_code } -#[cfg(not(test))] -#[inline(never)] +#[cfg(not(any(test, doctest)))] #[lang = "start"] fn lang_start<T: crate::process::Termination + 'static>( main: fn() -> T, diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs index 0fff53f1887..d37b8ce6346 100644 --- a/library/std/src/sys/personality/mod.rs +++ b/library/std/src/sys/personality/mod.rs @@ -12,7 +12,7 @@ mod dwarf; -#[cfg(not(test))] +#[cfg(not(any(test, doctest)))] cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { mod emcc; diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index 2da17fabcd6..9f7dcc0416e 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -244,13 +244,15 @@ mod imp { let mut res = Vec::new(); unsafe { - let process_info_sel = sel_registerName("processInfo\0".as_ptr()); - let arguments_sel = sel_registerName("arguments\0".as_ptr()); - let utf8_sel = sel_registerName("UTF8String\0".as_ptr()); - let count_sel = sel_registerName("count\0".as_ptr()); - let object_at_sel = sel_registerName("objectAtIndex:\0".as_ptr()); - - let klass = objc_getClass("NSProcessInfo\0".as_ptr()); + let process_info_sel = + sel_registerName(c"processInfo".as_ptr() as *const libc::c_uchar); + let arguments_sel = sel_registerName(c"arguments".as_ptr() as *const libc::c_uchar); + let utf8_sel = sel_registerName(c"UTF8String".as_ptr() as *const libc::c_uchar); + let count_sel = sel_registerName(c"count".as_ptr() as *const libc::c_uchar); + let object_at_sel = + sel_registerName(c"objectAtIndex:".as_ptr() as *const libc::c_uchar); + + let klass = objc_getClass(c"NSProcessInfo".as_ptr() as *const libc::c_uchar); let info = objc_msgSend(klass, process_info_sel); let args = objc_msgSend(info, arguments_sel); diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index e3455cfef33..72e7b1b1fc3 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1140,7 +1140,7 @@ impl File { cfg_has_statx! { if let Some(ret) = unsafe { try_statx( fd, - b"\0" as *const _ as *const c_char, + c"".as_ptr() as *const c_char, libc::AT_EMPTY_PATH | libc::AT_STATX_SYNC_AS_STAT, libc::STATX_ALL, ) } { diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 4b28f6feba5..b5da5f870ec 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -1,6 +1,5 @@ #![allow(missing_docs, nonstandard_style)] -use crate::ffi::CStr; use crate::io::ErrorKind; pub use self::rand::hashmap_random_keys; @@ -75,7 +74,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { // thread-id for the main thread and so renaming the main thread will rename the // process and we only want to enable this on platforms we've tested. if cfg!(target_os = "macos") { - thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0")); + thread::Thread::set_name(&c"main"); } unsafe fn sanitize_standard_fds() { @@ -127,7 +126,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { if pfd.revents & libc::POLLNVAL == 0 { continue; } - if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { + if open64(c"/dev/null".as_ptr().cast(), libc::O_RDWR, 0) == -1 { // If the stream is closed but we failed to reopen it, abort the // process. Otherwise we wouldn't preserve the safety of // operations on the corresponding Rust object Stdin, Stdout, or @@ -157,7 +156,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { use libc::open64; for fd in 0..3 { if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { - if open64("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { + if open64(c"/dev/null".as_ptr().cast(), libc::O_RDWR, 0) == -1 { // If the stream is closed but we failed to reopen it, abort the // process. Otherwise we wouldn't preserve the safety of // operations on the corresponding Rust object Stdin, Stdout, or diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index bac32d9e60e..c5f04fb8b3b 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -24,11 +24,11 @@ cfg_if::cfg_if! { if #[cfg(target_os = "fuchsia")] { // fuchsia doesn't have /dev/null } else if #[cfg(target_os = "redox")] { - const DEV_NULL: &str = "null:\0"; + const DEV_NULL: &CStr = c"null:"; } else if #[cfg(target_os = "vxworks")] { - const DEV_NULL: &str = "/null\0"; + const DEV_NULL: &CStr = c"/null"; } else { - const DEV_NULL: &str = "/dev/null\0"; + const DEV_NULL: &CStr = c"/dev/null"; } } @@ -481,8 +481,7 @@ impl Stdio { let mut opts = OpenOptions::new(); opts.read(readable); opts.write(!readable); - let path = unsafe { CStr::from_ptr(DEV_NULL.as_ptr() as *const _) }; - let fd = File::open_c(&path, &opts)?; + let fd = File::open_c(DEV_NULL, &opts)?; Ok((ChildStdio::Owned(fd.into_inner()), None)) } diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 29db9468e5f..76b96bb37df 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -163,10 +163,9 @@ impl Thread { #[cfg(target_os = "netbsd")] pub fn set_name(name: &CStr) { unsafe { - let cname = CStr::from_bytes_with_nul_unchecked(b"%s\0".as_slice()); let res = libc::pthread_setname_np( libc::pthread_self(), - cname.as_ptr(), + c"%s".as_ptr(), name.as_ptr() as *mut libc::c_void, ); debug_assert_eq!(res, 0); diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 7435b21be4c..d55d9bace81 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -324,7 +324,7 @@ pub unsafe fn NtWriteFile( // Functions that aren't available on every version of Windows that we support, // but we still use them and just provide some form of a fallback implementation. compat_fn_with_fallback! { - pub static KERNEL32: &CStr = ansi_str!("kernel32"); + pub static KERNEL32: &CStr = c"kernel32"; // >= Win10 1607 // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription @@ -357,7 +357,7 @@ compat_fn_optional! { } compat_fn_with_fallback! { - pub static NTDLL: &CStr = ansi_str!("ntdll"); + pub static NTDLL: &CStr = c"ntdll"; pub fn NtCreateKeyedEvent( KeyedEventHandle: LPHANDLE, diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs index e28dd493536..f60b3a2c700 100644 --- a/library/std/src/sys/windows/compat.rs +++ b/library/std/src/sys/windows/compat.rs @@ -225,9 +225,9 @@ macro_rules! compat_fn_optional { /// Load all needed functions from "api-ms-win-core-synch-l1-2-0". pub(super) fn load_synch_functions() { fn try_load() -> Option<()> { - const MODULE_NAME: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0"); - const WAIT_ON_ADDRESS: &CStr = ansi_str!("WaitOnAddress"); - const WAKE_BY_ADDRESS_SINGLE: &CStr = ansi_str!("WakeByAddressSingle"); + const MODULE_NAME: &CStr = c"api-ms-win-core-synch-l1-2-0"; + const WAIT_ON_ADDRESS: &CStr = c"WaitOnAddress"; + const WAKE_BY_ADDRESS_SINGLE: &CStr = c"WakeByAddressSingle"; // Try loading the library and all the required functions. // If any step fails, then they all fail. diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index f57034cc8d5..09dfb0caeec 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -1,7 +1,7 @@ use crate::os::windows::prelude::*; use crate::borrow::Cow; -use crate::ffi::OsString; +use crate::ffi::{c_void, OsString}; use crate::fmt; use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::mem::{self, MaybeUninit}; @@ -16,8 +16,6 @@ use crate::sys::{c, cvt, Align8}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::thread; -use core::ffi::c_void; - use super::path::maybe_verbatim; use super::{api, to_u16s, IoResult}; @@ -273,7 +271,9 @@ impl OpenOptions { (false, false, false) => c::OPEN_EXISTING, (true, false, false) => c::OPEN_ALWAYS, (false, true, false) => c::TRUNCATE_EXISTING, - (true, true, false) => c::CREATE_ALWAYS, + // `CREATE_ALWAYS` has weird semantics so we emulate it using + // `OPEN_ALWAYS` and a manual truncation step. See #115745. + (true, true, false) => c::OPEN_ALWAYS, (_, _, true) => c::CREATE_NEW, }) } @@ -289,19 +289,40 @@ impl OpenOptions { impl File { pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> { let path = maybe_verbatim(path)?; + let creation = opts.get_creation_mode()?; let handle = unsafe { c::CreateFileW( path.as_ptr(), opts.get_access_mode()?, opts.share_mode, opts.security_attributes, - opts.get_creation_mode()?, + creation, opts.get_flags_and_attributes(), ptr::null_mut(), ) }; let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) }; - if let Ok(handle) = handle.try_into() { + if let Ok(handle) = OwnedHandle::try_from(handle) { + // Manual truncation. See #115745. + if opts.truncate + && creation == c::OPEN_ALWAYS + && unsafe { c::GetLastError() } == c::ERROR_ALREADY_EXISTS + { + unsafe { + // Setting the allocation size to zero also sets the + // EOF position to zero. + let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 }; + let result = c::SetFileInformationByHandle( + handle.as_raw_handle(), + c::FileAllocationInfo, + ptr::addr_of!(alloc).cast::<c_void>(), + mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32, + ); + if result == 0 { + return Err(io::Error::last_os_error()); + } + } + } Ok(File { handle: Handle::from_inner(handle) }) } else { Err(Error::last_os_error()) diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index 9c83d6eb8bf..8b722f01a5d 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -1,6 +1,6 @@ #![allow(missing_docs, nonstandard_style)] -use crate::ffi::{CStr, OsStr, OsString}; +use crate::ffi::{OsStr, OsString}; use crate::io::ErrorKind; use crate::mem::MaybeUninit; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; @@ -63,7 +63,7 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) { // Normally, `thread::spawn` will call `Thread::set_name` but since this thread already // exists, we have to call it ourselves. - thread::Thread::set_name(CStr::from_bytes_with_nul_unchecked(b"main\0")); + thread::Thread::set_name(&c"main"); } // SAFETY: must be called only once during runtime cleanup. diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 32f6a3f80d0..b1ab8dae535 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -5,7 +5,6 @@ //! parent directory, and otherwise documentation can be found throughout the `build` //! directory in each respective module. -#[cfg(all(any(unix, windows), not(target_os = "solaris")))] use std::io::Write; #[cfg(all(any(unix, windows), not(target_os = "solaris")))] use std::process; @@ -175,7 +174,7 @@ fn check_version(config: &Config) -> Option<String> { "update `config.toml` to use `change-id = {latest_change_id}` instead" )); - if io::stdout().is_terminal() { + if io::stdout().is_terminal() && !config.dry_run() { t!(fs::write(warned_id_path, latest_change_id.to_string())); } } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index c485481b9a1..98e267713da 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1319,7 +1319,7 @@ impl Step for CodegenBackend { return None; } - if self.compiler.host.contains("windows") { + if self.compiler.host.is_windows() { builder.info( "dist currently disabled for windows by rustc_codegen_cranelift. skipping", ); @@ -1658,7 +1658,7 @@ impl Step for Extended { builder.run(&mut cmd); } - if target.contains("windows") { + if target.is_windows() { let exe = tmp.join("exe"); let _ = fs::remove_dir_all(&exe); diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 8de208cd09c..4b2d3e9ab4b 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -283,7 +283,7 @@ impl Step for Llvm { }; builder.update_submodule(&Path::new("src").join("llvm-project")); - if builder.llvm_link_shared() && target.contains("windows") { + if builder.llvm_link_shared() && target.is_windows() { panic!("shared linking to LLVM is not currently supported on {}", target.triple); } @@ -361,7 +361,7 @@ impl Step for Llvm { // Disable zstd to avoid a dependency on libzstd.so. cfg.define("LLVM_ENABLE_ZSTD", "OFF"); - if !target.contains("windows") { + if !target.is_windows() { cfg.define("LLVM_ENABLE_ZLIB", "ON"); } else { cfg.define("LLVM_ENABLE_ZLIB", "OFF"); @@ -607,7 +607,7 @@ fn configure_cmake( cfg.define("CMAKE_SYSTEM_NAME", "DragonFly"); } else if target.contains("freebsd") { cfg.define("CMAKE_SYSTEM_NAME", "FreeBSD"); - } else if target.contains("windows") { + } else if target.is_windows() { cfg.define("CMAKE_SYSTEM_NAME", "Windows"); } else if target.contains("haiku") { cfg.define("CMAKE_SYSTEM_NAME", "Haiku"); @@ -772,7 +772,7 @@ fn configure_cmake( && !target.contains("netbsd") && !target.contains("solaris") { - if target.contains("apple") || target.contains("windows") { + if target.contains("apple") || target.is_windows() { ldflags.push_all("-static-libstdc++"); } else { ldflags.push_all("-Wl,-Bsymbolic -static-libstdc++"); @@ -1295,7 +1295,7 @@ impl Step for Libunwind { cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None); cfg.define("NDEBUG", None); } - if self.target.contains("windows") { + if self.target.is_windows() { cfg.define("_LIBUNWIND_HIDE_SYMBOLS", "1"); cfg.define("_LIBUNWIND_IS_NATIVE_ONLY", "1"); } diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 054c3ab14c0..28761a7ee4b 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1653,10 +1653,7 @@ impl<'a> Builder<'a> { // flesh out rpath support more fully in the future. rustflags.arg("-Zosx-rpath-install-name"); Some(format!("-Wl,-rpath,@loader_path/../{libdir}")) - } else if !target.contains("windows") - && !target.contains("aix") - && !target.contains("xous") - { + } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") { rustflags.arg("-Clink-args=-Wl,-z,origin"); Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}")) } else { @@ -1729,8 +1726,7 @@ impl<'a> Builder<'a> { let split_debuginfo_is_stable = target.contains("linux") || target.contains("apple") || (target.is_msvc() && self.config.rust_split_debuginfo == SplitDebuginfo::Packed) - || (target.contains("windows") - && self.config.rust_split_debuginfo == SplitDebuginfo::Off); + || (target.is_windows() && self.config.rust_split_debuginfo == SplitDebuginfo::Off); if !split_debuginfo_is_stable { rustflags.arg("-Zunstable-options"); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index c3db5641ea4..f1e1b89d9ba 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -421,10 +421,10 @@ impl std::str::FromStr for SplitDebuginfo { impl SplitDebuginfo { /// Returns the default `-Csplit-debuginfo` value for the current target. See the comment for /// `rust.split-debuginfo` in `config.example.toml`. - fn default_for_platform(target: &str) -> Self { + fn default_for_platform(target: TargetSelection) -> Self { if target.contains("apple") { SplitDebuginfo::Unpacked - } else if target.contains("windows") { + } else if target.is_windows() { SplitDebuginfo::Packed } else { SplitDebuginfo::Off @@ -527,6 +527,10 @@ impl TargetSelection { pub fn is_msvc(&self) -> bool { self.contains("msvc") } + + pub fn is_windows(&self) -> bool { + self.contains("windows") + } } impl fmt::Display for TargetSelection { @@ -1595,7 +1599,7 @@ impl Config { .as_deref() .map(SplitDebuginfo::from_str) .map(|v| v.expect("invalid value for rust.split_debuginfo")) - .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple)); + .unwrap_or(SplitDebuginfo::default_for_platform(config.build)); optimize = optimize_toml; omit_git_hash = omit_git_hash_toml; config.rust_new_symbol_mangling = new_symbol_mangling; @@ -1791,8 +1795,7 @@ impl Config { config.llvm_link_shared.set(Some(true)); } } else { - config.llvm_from_ci = config.channel == "dev" - && crate::core::build_steps::llvm::is_ci_llvm_available(&config, false); + config.llvm_from_ci = config.parse_download_ci_llvm(None, false); } if let Some(t) = toml.target { @@ -1965,7 +1968,7 @@ impl Config { config } - pub(crate) fn dry_run(&self) -> bool { + pub fn dry_run(&self) -> bool { match self.dry_run { DryRun::Disabled => false, DryRun::SelfCheck | DryRun::UserSelected => true, @@ -2337,29 +2340,30 @@ impl Config { download_ci_llvm: Option<StringOrBool>, asserts: bool, ) -> bool { + let if_unchanged = || { + // Git is needed to track modifications here, but tarball source is not available. + // If not modified here or built through tarball source, we maintain consistency + // with '"if available"'. + if !self.rust_info.is_from_tarball() + && self + .last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true) + .is_none() + { + // there are some untracked changes in the the given paths. + false + } else { + llvm::is_ci_llvm_available(&self, asserts) + } + }; match download_ci_llvm { - None => self.channel == "dev" && llvm::is_ci_llvm_available(&self, asserts), + None => self.channel == "dev" && if_unchanged(), Some(StringOrBool::Bool(b)) => b, // FIXME: "if-available" is deprecated. Remove this block later (around mid 2024) // to not break builds between the recent-to-old checkouts. Some(StringOrBool::String(s)) if s == "if-available" => { llvm::is_ci_llvm_available(&self, asserts) } - Some(StringOrBool::String(s)) if s == "if-unchanged" => { - // Git is needed to track modifications here, but tarball source is not available. - // If not modified here or built through tarball source, we maintain consistency - // with '"if available"'. - if !self.rust_info.is_from_tarball() - && self - .last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true) - .is_none() - { - // there are some untracked changes in the the given paths. - false - } else { - llvm::is_ci_llvm_available(&self, asserts) - } - } + Some(StringOrBool::String(s)) if s == "if-unchanged" => if_unchanged(), Some(StringOrBool::String(other)) => { panic!("unrecognized option for download-ci-llvm: {:?}", other) } diff --git a/src/bootstrap/src/tests/config.rs b/src/bootstrap/src/tests/config.rs index c24d57fb8f8..6f432343882 100644 --- a/src/bootstrap/src/tests/config.rs +++ b/src/bootstrap/src/tests/config.rs @@ -31,10 +31,10 @@ fn download_ci_llvm() { assert_eq!(parse_llvm(""), if_unchanged); assert_eq!(parse_llvm("rust.channel = \"dev\""), if_unchanged); assert!(!parse_llvm("rust.channel = \"stable\"")); - assert!(parse_llvm("build.build = \"x86_64-unknown-linux-gnu\"")); - assert!(parse_llvm( + assert_eq!(parse_llvm("build.build = \"x86_64-unknown-linux-gnu\""), if_unchanged); + assert_eq!(parse_llvm( "llvm.assertions = true \r\n build.build = \"x86_64-unknown-linux-gnu\" \r\n llvm.download-ci-llvm = \"if-unchanged\"" - )); + ), if_unchanged); assert!(!parse_llvm( "llvm.assertions = true \r\n build.build = \"aarch64-apple-darwin\" \r\n llvm.download-ci-llvm = \"if-unchanged\"" )); diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 133792d85e8..d96608db22c 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -49,7 +49,7 @@ pub use t; /// Given an executable called `name`, return the filename for the /// executable for a particular target. pub fn exe(name: &str, target: TargetSelection) -> String { - if target.contains("windows") { + if target.is_windows() { format!("{name}.exe") } else if target.contains("uefi") { format!("{name}.efi") @@ -72,7 +72,7 @@ pub fn is_debug_info(name: &str) -> bool { /// Returns the corresponding relative library directory that the compiler's /// dylibs will be found in. pub fn libdir(target: TargetSelection) -> &'static str { - if target.contains("windows") { "bin" } else { "lib" } + if target.is_windows() { "bin" } else { "lib" } } /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. @@ -191,7 +191,7 @@ pub fn target_supports_cranelift_backend(target: TargetSelection) -> bool { || target.contains("aarch64") || target.contains("s390x") || target.contains("riscv64gc") - } else if target.contains("darwin") || target.contains("windows") { + } else if target.contains("darwin") || target.is_windows() { target.contains("x86_64") } else { false @@ -519,7 +519,7 @@ pub fn linker_flags( if matches!(lld_threads, LldThreads::No) { args.push(format!( "-Clink-arg=-Wl,{}", - lld_flag_no_threads(builder.config.lld_mode, target.is_msvc()) + lld_flag_no_threads(builder.config.lld_mode, target.is_windows()) )); } } diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md index 046d018543f..669dc9358eb 100644 --- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md +++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md @@ -201,7 +201,7 @@ mod bar { # fn main() {} ``` -Here, because `bar` is not public, `Bar` wouldn't have its own page, so there's nowhere +Here, because `bar` is not public, `bar` wouldn't have its own page, so there's nowhere to link to. `rustdoc` will inline these definitions, and so we end up in the same case as the `#[doc(inline)]` above; `Bar` is in a `Structs` section, as if it were defined at the top level. If we add the `no_inline` form of the attribute: diff --git a/src/doc/unstable-book/src/compiler-flags/default-hidden-visibility.md b/src/doc/unstable-book/src/compiler-flags/default-hidden-visibility.md new file mode 100644 index 00000000000..579add4a9d9 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/default-hidden-visibility.md @@ -0,0 +1,12 @@ +# `default-hidden-visibility` + +The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/656 + +------------------------ + +This flag can be used to override the target's +[`default_hidden_visibility`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_target/spec/struct.TargetOptions.html#structfield.default_hidden_visibility) +setting. +Using `-Zdefault_hidden_visibility=yes` is roughly equivalent to Clang's +[`-fvisibility=hidden`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fvisibility) +cmdline flag. diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index dad2aa4061d..4da85885d67 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -14,7 +14,6 @@ pub(crate) struct BlanketImplFinder<'a, 'tcx> { impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { pub(crate) fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> { let cx = &mut self.cx; - let param_env = cx.tcx.param_env(item_def_id); let ty = cx.tcx.type_of(item_def_id); trace!("get_blanket_impls({ty:?})"); @@ -40,7 +39,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { let infcx = cx.tcx.infer_ctxt().build(); let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id); let impl_ty = ty.instantiate(infcx.tcx, args); - let param_env = EarlyBinder::bind(param_env).instantiate(infcx.tcx, args); + let param_env = ty::ParamEnv::empty(); let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); let impl_trait_ref = trait_ref.instantiate(infcx.tcx, impl_args); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 688751627f3..828e7f959b4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::TypeVisitableExt; -use rustc_middle::ty::{self, AdtKind, EarlyBinder, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtKind, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::hygiene::{AstPass, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -184,22 +184,6 @@ fn clean_generic_bound<'tcx>( ) -> Option<GenericBound> { Some(match *bound { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)), - hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => { - let def_id = cx.tcx.require_lang_item(lang_item, Some(span)); - - let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(cx.tcx, def_id)); - - let generic_args = clean_generic_args(generic_args, cx); - let GenericArgs::AngleBracketed { bindings, .. } = generic_args else { - bug!("clean: parenthesized `GenericBound::LangItemTrait`"); - }; - - let trait_ = clean_trait_ref_with_bindings(cx, trait_ref, bindings); - GenericBound::TraitBound( - PolyTrait { trait_, generic_params: vec![] }, - hir::TraitBoundModifier::None, - ) - } hir::GenericBound::Trait(ref t, modifier) => { // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op. if modifier == hir::TraitBoundModifier::MaybeConst @@ -743,7 +727,7 @@ pub(crate) fn clean_generics<'tcx>( .into_iter() .map(|(lifetime, bounds)| WherePredicate::RegionPredicate { lifetime, bounds }), ) - .chain(eq_predicates.into_iter()) + .chain(eq_predicates) .collect(), } } @@ -1596,7 +1580,6 @@ fn first_non_private<'tcx>( // Absolute paths are not. We start from the parent of the item. [.., parent, leaf] => (parent.res.opt_def_id()?.as_local()?, leaf.ident), }; - let hir = cx.tcx.hir(); // First we try to get the `DefId` of the item. for child in cx.tcx.module_children_local(parent_def_id).iter().filter(move |c| c.ident == ident) @@ -1612,7 +1595,8 @@ fn first_non_private<'tcx>( 'reexps: for reexp in child.reexport_chain.iter() { if let Some(use_def_id) = reexp.id() && let Some(local_use_def_id) = use_def_id.as_local() - && let Some(hir::Node::Item(item)) = hir.find_by_def_id(local_use_def_id) + && let Some(hir::Node::Item(item)) = + cx.tcx.opt_hir_node_by_def_id(local_use_def_id) && !item.ident.name.is_empty() && let hir::ItemKind::Use(path, _) = item.kind { @@ -2646,6 +2630,40 @@ fn filter_tokens_from_list( tokens } +fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool { + if is_inline { + ident == sym::hidden || ident == sym::inline || ident == sym::no_inline + } else { + ident == sym::cfg + } +} + +/// Remove attributes from `normal` that should not be inherited by `use` re-export. +/// Before calling this function, make sure `normal` is a `#[doc]` attribute. +fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) { + match normal.item.args { + ast::AttrArgs::Delimited(ref mut args) => { + let tokens = filter_tokens_from_list(&args.tokens, |token| { + !matches!( + token, + TokenTree::Token( + Token { + kind: TokenKind::Ident( + ident, + _, + ), + .. + }, + _, + ) if filter_doc_attr_ident(*ident, is_inline), + ) + }); + args.tokens = TokenStream::new(tokens); + } + ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {} + } +} + /// When inlining items, we merge their attributes (and all the reexports attributes too) with the /// final reexport. For example: /// @@ -2672,13 +2690,6 @@ fn add_without_unwanted_attributes<'hir>( is_inline: bool, import_parent: Option<DefId>, ) { - // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything. - if !is_inline { - for attr in new_attrs { - attrs.push((Cow::Borrowed(attr), import_parent)); - } - return; - } for attr in new_attrs { if matches!(attr.kind, ast::AttrKind::DocComment(..)) { attrs.push((Cow::Borrowed(attr), import_parent)); @@ -2687,33 +2698,14 @@ fn add_without_unwanted_attributes<'hir>( let mut attr = attr.clone(); match attr.kind { ast::AttrKind::Normal(ref mut normal) => { - if let [ident] = &*normal.item.path.segments - && let ident = ident.ident.name - && ident == sym::doc - { - match normal.item.args { - ast::AttrArgs::Delimited(ref mut args) => { - let tokens = filter_tokens_from_list(&args.tokens, |token| { - !matches!( - token, - TokenTree::Token( - Token { - kind: TokenKind::Ident( - sym::hidden | sym::inline | sym::no_inline, - _, - ), - .. - }, - _, - ), - ) - }); - args.tokens = TokenStream::new(tokens); - attrs.push((Cow::Owned(attr), import_parent)); - } - ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => { - attrs.push((Cow::Owned(attr), import_parent)); - } + if let [ident] = &*normal.item.path.segments { + let ident = ident.ident.name; + if ident == sym::doc { + filter_doc_attr(normal, is_inline); + attrs.push((Cow::Owned(attr), import_parent)); + } else if ident != sym::cfg { + // If it's not a `cfg()` attribute, we keep it. + attrs.push((Cow::Owned(attr), import_parent)); } } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0a14404d689..150625c6d92 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2245,8 +2245,8 @@ impl GenericArgs { } pub(crate) fn bindings<'a>(&'a self) -> Box<dyn Iterator<Item = TypeBinding> + 'a> { match self { - &GenericArgs::AngleBracketed { ref bindings, .. } => Box::new(bindings.iter().cloned()), - &GenericArgs::Parenthesized { ref output, .. } => Box::new( + GenericArgs::AngleBracketed { bindings, .. } => Box::new(bindings.iter().cloned()), + GenericArgs::Parenthesized { output, .. } => Box::new( output .as_ref() .map(|ty| TypeBinding { @@ -2270,8 +2270,8 @@ impl<'a> IntoIterator for &'a GenericArgs { type Item = GenericArg; fn into_iter(self) -> Self::IntoIter { match self { - &GenericArgs::AngleBracketed { ref args, .. } => Box::new(args.iter().cloned()), - &GenericArgs::Parenthesized { ref inputs, .. } => { + GenericArgs::AngleBracketed { args, .. } => Box::new(args.iter().cloned()), + GenericArgs::Parenthesized { inputs, .. } => { Box::new(inputs.iter().cloned().map(GenericArg::Type)) } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 82f4a38384d..bdfda07be09 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -439,7 +439,7 @@ fn print_const_with_custom_print_scalar<'tcx>( } pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { - if let hir::Node::Expr(expr) = tcx.hir().get(hir_id) { + if let hir::Node::Expr(expr) = tcx.hir_node(hir_id) { if let hir::ExprKind::Lit(_) = &expr.kind { return true; } @@ -641,7 +641,6 @@ pub(crate) fn inherits_doc_hidden( mut def_id: LocalDefId, stop_at: Option<LocalDefId>, ) -> bool { - let hir = tcx.hir(); while let Some(id) = tcx.opt_local_parent(def_id) { if let Some(stop_at) = stop_at && id == stop_at @@ -651,7 +650,7 @@ pub(crate) fn inherits_doc_hidden( def_id = id; if tcx.is_doc_hidden(def_id.to_def_id()) { return true; - } else if let Some(node) = hir.find_by_def_id(def_id) + } else if let Some(node) = tcx.opt_hir_node_by_def_id(def_id) && matches!(node, hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }),) { // `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8215926ee33..0150496990d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -380,7 +380,9 @@ pub(crate) fn run_global_ctxt( crate::lint::MISSING_CRATE_LEVEL_DOCS, DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(), "no documentation found for this crate's top-level module", - |lint| lint.help(help), + |lint| { + lint.help(help); + }, ); } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index abc27bcdf07..642265f5f6b 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -27,7 +27,7 @@ //! ``` use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_errors::{DiagnosticBuilder, DiagnosticMessage}; use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; pub(crate) use rustc_resolve::rustdoc::main_body_opts; @@ -234,10 +234,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { fn next(&mut self) -> Option<Self::Item> { let event = self.inner.next(); - let compile_fail; - let should_panic; - let ignore; - let edition; let Some(Event::Start(Tag::CodeBlock(kind))) = event else { return event; }; @@ -253,49 +249,44 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> { } } - let parse_result = match kind { - CodeBlockKind::Fenced(ref lang) => { - let parse_result = LangString::parse_without_check( - lang, - self.check_error_codes, - false, - self.custom_code_classes_in_docs, - ); - if !parse_result.rust { - let added_classes = parse_result.added_classes; - let lang_string = if let Some(lang) = parse_result.unknown.first() { - format!("language-{}", lang) - } else { - String::new() - }; - let whitespace = if added_classes.is_empty() { "" } else { " " }; - return Some(Event::Html( - format!( - "<div class=\"example-wrap\">\ + let LangString { added_classes, compile_fail, should_panic, ignore, edition, .. } = + match kind { + CodeBlockKind::Fenced(ref lang) => { + let parse_result = LangString::parse_without_check( + lang, + self.check_error_codes, + false, + self.custom_code_classes_in_docs, + ); + if !parse_result.rust { + let added_classes = parse_result.added_classes; + let lang_string = if let Some(lang) = parse_result.unknown.first() { + format!("language-{}", lang) + } else { + String::new() + }; + let whitespace = if added_classes.is_empty() { "" } else { " " }; + return Some(Event::Html( + format!( + "<div class=\"example-wrap\">\ <pre class=\"{lang_string}{whitespace}{added_classes}\">\ <code>{text}</code>\ </pre>\ </div>", - added_classes = added_classes.join(" "), - text = Escape(&original_text), - ) - .into(), - )); + added_classes = added_classes.join(" "), + text = Escape(&original_text), + ) + .into(), + )); + } + parse_result } - parse_result - } - CodeBlockKind::Indented => Default::default(), - }; + CodeBlockKind::Indented => Default::default(), + }; - let added_classes = parse_result.added_classes; let lines = original_text.lines().filter_map(|l| map_line(l).for_html()); let text = lines.intersperse("\n".into()).collect::<String>(); - compile_fail = parse_result.compile_fail; - should_panic = parse_result.should_panic; - ignore = parse_result.ignore; - edition = parse_result.edition; - let explicit_edition = edition.is_some(); let edition = edition.unwrap_or(self.edition); @@ -844,7 +835,7 @@ impl<'tcx> ExtraInfo<'tcx> { self.tcx.local_def_id_to_hir_id(def_id), self.sp, msg, - |l| l, + |_| {}, ); } } @@ -852,7 +843,7 @@ impl<'tcx> ExtraInfo<'tcx> { fn error_invalid_codeblock_attr_with_help( &self, msg: impl Into<DiagnosticMessage>, - help: impl Into<SubdiagnosticMessage>, + f: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>), ) { if let Some(def_id) = self.def_id.as_local() { self.tcx.struct_span_lint_hir( @@ -860,7 +851,7 @@ impl<'tcx> ExtraInfo<'tcx> { self.tcx.local_def_id_to_hir_id(def_id), self.sp, msg, - |lint| lint.help(help), + f, ); } } @@ -1294,6 +1285,21 @@ impl LangString { data.edition = x[7..].parse::<Edition>().ok(); } LangStringToken::LangToken(x) + if x.starts_with("rust") && x[4..].parse::<Edition>().is_ok() => + { + if let Some(extra) = extra { + extra.error_invalid_codeblock_attr_with_help( + format!("unknown attribute `{x}`"), + |lint| { + lint.help(format!( + "there is an attribute with a similar name: `edition{}`", + &x[4..], + )); + }, + ); + } + } + LangStringToken::LangToken(x) if allow_error_code_check && x.starts_with('E') && x.len() == 5 => { if x[1..].parse::<u32>().is_ok() { @@ -1337,8 +1343,13 @@ impl LangString { } { if let Some(extra) = extra { extra.error_invalid_codeblock_attr_with_help( - format!("unknown attribute `{x}`. Did you mean `{flag}`?"), - help, + format!("unknown attribute `{x}`"), + |lint| { + lint.help(format!( + "there is an attribute with a similar name: `{flag}`" + )) + .help(help); + }, ); } } @@ -1370,7 +1381,7 @@ impl LangString { }; if custom_code_classes_in_docs { - call(&mut TagIterator::new(string, extra).into_iter()) + call(&mut TagIterator::new(string, extra)) } else { call(&mut tokens(string)) } @@ -2000,6 +2011,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> { map.insert("themeStyle".into(), 1); map.insert("settings-menu".into(), 1); map.insert("help-button".into(), 1); + map.insert("sidebar-button".into(), 1); map.insert("main-content".into(), 1); map.insert("toggle-all-docs".into(), 1); map.insert("all-types".into(), 1); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index ff7ce01e807..5ca623f01f1 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1,5 +1,3 @@ -use clean::AttributesExt; - use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; @@ -465,16 +463,9 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: clean::ImportItem(ref import) => { let stab_tags = if let Some(import_def_id) = import.source.did { - let ast_attrs = tcx.get_attrs_unchecked(import_def_id); - let import_attrs = Box::new(clean::Attributes::from_ast(ast_attrs)); - // Just need an item with the correct def_id and attrs - let import_item = clean::Item { - item_id: import_def_id.into(), - attrs: import_attrs, - cfg: ast_attrs.cfg(tcx, &cx.cache().hidden_cfg), - ..myitem.clone() - }; + let import_item = + clean::Item { item_id: import_def_id.into(), ..myitem.clone() }; let stab_tags = Some(extra_info_tags(&import_item, item, tcx).to_string()); stab_tags diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index b3ae720fcf6..a1029320d2d 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -488,7 +488,7 @@ pub(crate) fn build_index<'tcx>( // Collect the index into a string format!( - r#""{}":{}"#, + r#"["{}",{}]"#, krate.name(tcx), serde_json::to_string(&CrateData { doc: crate_doc, diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 5f130f1875a..d1ece73374d 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -94,7 +94,7 @@ impl<'tcx> SpanMapVisitor<'tcx> { /// Used to generate links on items' definition to go to their documentation page. pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) { - if let Some(Node::Item(item)) = self.tcx.hir().find(hir_id) { + if let Some(Node::Item(item)) = self.tcx.opt_hir_node(hir_id) { if let Some(span) = self.tcx.def_ident_span(item.owner_id) { let cspan = clean::Span::new(span); // If the span isn't from the current crate, we ignore it. @@ -177,7 +177,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { if !span.overlaps(m.spans.inner_span) { // Now that we confirmed it's a file import, we want to get the span for the module // name only and not all the "mod foo;". - if let Some(Node::Item(item)) = self.tcx.hir().find(id) { + if let Some(Node::Item(item)) = self.tcx.opt_hir_node(id) { self.matches.insert( item.ident.span, LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)), diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index ee581173a4a..738ea0aee7e 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -79,6 +79,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( TypeLayoutSize { is_unsized, is_uninhabited, size } }); - Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) + TypeLayout { variants, type_layout_size }.render_into(f).unwrap(); + Ok(()) }) } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index b04776e91dc..6408e97df50 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -167,23 +167,24 @@ pub(super) fn write_shared( let mut krates = Vec::new(); if path.exists() { - let prefix = format!("\"{krate}\""); + let prefix = format!("[\"{krate}\""); for line in BufReader::new(File::open(path)?).lines() { let line = line?; - if !line.starts_with('"') { + if !line.starts_with("[\"") { continue; } if line.starts_with(&prefix) { continue; } - if line.ends_with(",\\") { + if line.ends_with("],\\") { ret.push(line[..line.len() - 2].to_string()); } else { // Ends with "\\" (it's the case for the last added crate line) ret.push(line[..line.len() - 1].to_string()); } krates.push( - line.split('"') + line[1..] // We skip the `[` parent at the beginning of the line. + .split('"') .find(|s| !s.is_empty()) .map(|s| s.to_owned()) .unwrap_or_else(String::new), @@ -285,7 +286,7 @@ pub(super) fn write_shared( let (mut all_sources, _krates) = try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst); all_sources.push(format!( - r#""{}":{}"#, + r#"["{}",{}]"#, &krate.name(cx.tcx()), hierarchy .to_json_string() @@ -296,9 +297,12 @@ pub(super) fn write_shared( .replace("\\\"", "\\\\\"") )); all_sources.sort(); - let mut v = String::from("var srcIndex = JSON.parse('{\\\n"); + // This needs to be `var`, not `const`. + // This variable needs declared in the current global scope so that if + // src-script.js loads first, it can pick it up. + let mut v = String::from("var srcIndex = new Map(JSON.parse('[\\\n"); v.push_str(&all_sources.join(",\\\n")); - v.push_str("\\\n}');\ncreateSrcSidebar();\n"); + v.push_str("\\\n]'));\ncreateSrcSidebar();\n"); Ok(v.into_bytes()) }; write_invocation_specific("src-files.js", &make_sources)?; @@ -316,13 +320,16 @@ pub(super) fn write_shared( // with rustdoc running in parallel. all_indexes.sort(); write_invocation_specific("search-index.js", &|| { - let mut v = String::from("var searchIndex = JSON.parse('{\\\n"); + // This needs to be `var`, not `const`. + // This variable needs declared in the current global scope so that if + // search.js loads first, it can pick it up. + let mut v = String::from("var searchIndex = new Map(JSON.parse('[\\\n"); v.push_str(&all_indexes.join(",\\\n")); v.push_str( r#"\ -}'); -if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; -if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; +]')); +if (typeof exports !== 'undefined') exports.searchIndex = searchIndex; +else if (window.initSearch) window.initSearch(searchIndex); "#, ); Ok(v.into_bytes()) diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index fe0cf6dc8cc..390e812772a 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -9,7 +9,7 @@ rules. margin-left: 0 !important; } -#copy-path { +#copy-path, #sidebar-button, .sidebar-resizer { /* It requires JS to work so no need to display it in this case. */ display: none; } @@ -132,6 +132,8 @@ nav.sub { --scrape-example-help-hover-color: #000; --scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1); --scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0); + --sidebar-resizer-hover: hsl(207, 90%, 66%); + --sidebar-resizer-active: hsl(207, 90%, 54%); } /* End theme: light */ @@ -238,6 +240,8 @@ nav.sub { --scrape-example-help-hover-color: #fff; --scrape-example-code-wrapper-background-start: rgba(53, 53, 53, 1); --scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0); + --sidebar-resizer-hover: hsl(207, 30%, 54%); + --sidebar-resizer-active: hsl(207, 90%, 54%); } /* End theme: dark */ } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 6e61969a8c1..6e673aa77c5 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -9,6 +9,11 @@ :root { --nav-sub-mobile-padding: 8px; --search-typename-width: 6.75rem; + /* DEFAULT_SIDEBAR_WIDTH + see main.js for information on these values + and on the RUSTDOC_MOBILE_BREAKPOINT */ + --desktop-sidebar-width: 200px; + --src-sidebar-width: 300px; } /* See FiraSans-LICENSE.txt for the Fira Sans license. */ @@ -383,13 +388,15 @@ img { .sidebar { font-size: 0.875rem; - flex: 0 0 200px; + flex: 0 0 var(--desktop-sidebar-width); + width: var(--desktop-sidebar-width); overflow-y: scroll; overscroll-behavior: contain; position: sticky; height: 100vh; top: 0; left: 0; + z-index: 100; } .rustdoc.src .sidebar { @@ -398,7 +405,95 @@ img { overflow-x: hidden; /* The sidebar is by default hidden */ overflow-y: hidden; - z-index: 1; +} + +.hide-sidebar .sidebar, +.hide-sidebar .sidebar-resizer { + display: none; +} + +.sidebar-resizer { + touch-action: none; + width: 9px; + cursor: col-resize; + z-index: 200; + position: fixed; + height: 100%; + /* make sure there's a 1px gap between the scrollbar and resize handle */ + left: calc(var(--desktop-sidebar-width) + 1px); +} + +.rustdoc.src .sidebar-resizer { + /* when closed, place resizer glow on top of the normal src sidebar border (no need to worry + about sidebar) */ + left: 49px; +} + +.src-sidebar-expanded .rustdoc.src .sidebar-resizer { + /* for src sidebar, gap is already provided by 1px border on sidebar itself, so place resizer + to right of it */ + left: var(--src-sidebar-width); +} + +.sidebar-resizing { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.sidebar-resizing * { + cursor: col-resize !important; +} + +.sidebar-resizing .sidebar { + position: fixed; + z-index: 100; +} +.sidebar-resizing > body { + padding-left: var(--resizing-sidebar-width); +} + +.sidebar-resizer:hover, +.sidebar-resizer:active, +.sidebar-resizer:focus, +.sidebar-resizer.active { + width: 10px; + margin: 0; + /* when active or hovered, place resizer glow on top of the sidebar (right next to, or even + on top of, the scrollbar) */ + left: var(--desktop-sidebar-width); + border-left: solid 1px var(--sidebar-resizer-hover); +} + +.src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover, +.src-sidebar-expanded .rustdoc.src .sidebar-resizer:active, +.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus, +.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active { + /* when active or hovered, place resizer glow on top of the normal src sidebar border */ + left: calc(var(--src-sidebar-width) - 1px); +} + +@media (pointer: coarse) { + .sidebar-resizer { + /* too easy to hit the resizer while trying to hit the [-] toggle */ + display: none !important; + } +} + +.sidebar-resizer.active { + /* make the resize tool bigger when actually resizing, to avoid :hover styles on other stuff + while resizing */ + padding: 0 140px; + width: 2px; + margin-left: -140px; + border-left: none; +} +.sidebar-resizer.active:before { + border-left: solid 2px var(--sidebar-resizer-active); + display: block; + height: 100%; + content: ""; } .sidebar, .mobile-topbar, .sidebar-menu-toggle, @@ -416,7 +511,8 @@ img { .src-sidebar-expanded .src .sidebar { overflow-y: auto; - flex-basis: 300px; + flex-basis: var(--src-sidebar-width); + width: var(--src-sidebar-width); } .src-sidebar-expanded .src .sidebar > *:not(#src-sidebar-toggle) { @@ -477,6 +573,7 @@ ul.block, .block li { display: block; padding: 0.25rem; /* 4px */ margin-left: -0.25rem; + margin-right: 0.25rem; } .sidebar h2 { @@ -775,7 +872,7 @@ h2.section-header > .anchor { text-decoration: underline; } -.crate.block a.current { font-weight: 500; } +.crate.block li.current a { font-weight: 500; } /* In most contexts we use `overflow-wrap: anywhere` to ensure that we can wrap as much as needed on mobile (see @@ -1478,7 +1575,20 @@ a.tooltip:hover::after { margin-left: 4px; display: flex; } -#settings-menu > a, #help-button > a { +#sidebar-button { + display: none; +} +.hide-sidebar #sidebar-button { + display: flex; + margin-right: 4px; + position: fixed; + left: 6px; + height: 34px; + width: 34px; + background-color: var(--main-background-color); + z-index: 1; +} +#settings-menu > a, #help-button > a, #sidebar-button > a { display: flex; align-items: center; justify-content: center; @@ -1493,10 +1603,21 @@ a.tooltip:hover::after { } #settings-menu > a:hover, #settings-menu > a:focus, -#help-button > a:hover, #help-button > a:focus { +#help-button > a:hover, #help-button > a:focus, +#sidebar-button > a:hover, #sidebar-button > a:focus { border-color: var(--settings-button-border-focus); } +#sidebar-button > a:before { + content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" \ + fill="none" stroke="black">\ + <rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5"/>\ + <circle cx="4.375" cy="4.375" r="1" stroke-width=".75"/>\ + <path d="m7.6121 3v16 M5.375 7.625h-2 m2 3h-2 m2 3h-2" stroke-width="1.25"/></svg>'); + width: 22px; + height: 22px; +} + #copy-path { color: var(--copy-path-button-color); background: var(--main-background-color); @@ -1711,7 +1832,7 @@ However, it's not needed with smaller screen width because the doc/code block is /* WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY If you update this line, then you also need to update the line with the same warning -in src-script.js +in src-script.js and main.js */ @media (max-width: 700px) { /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, @@ -1722,6 +1843,10 @@ in src-script.js scroll-margin-top: 45px; } + .hide-sidebar #sidebar-button { + position: static; + } + .rustdoc { /* Sidebar should overlay main content, rather than pushing main content to the right. Turn off `display: flex` on the body element. */ @@ -1750,7 +1875,8 @@ in src-script.js /* Hide the logo and item name from the sidebar. Those are displayed in the mobile-topbar instead. */ .sidebar .logo-container, - .sidebar .location { + .sidebar .location, + .sidebar-resizer { display: none; } @@ -1818,6 +1944,10 @@ in src-script.js top: 0; } + .hide-sidebar .mobile-topbar { + display: none; + } + .sidebar-menu-toggle { width: 45px; /* Rare exception to specifying font sizes in rem. Since this is acting @@ -1827,6 +1957,10 @@ in src-script.js color: var(--main-color); } + .hide-sidebar .sidebar-menu-toggle { + display: none; + } + .sidebar-elems { margin-top: 1em; } @@ -1870,6 +2004,17 @@ in src-script.js display: none; } + /* sidebar button becomes topbar button */ + #sidebar-button > a:before { + content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \ + viewBox="0 0 22 22" fill="none" stroke="black">\ + <rect x="1" y="1" width="20" height="20" ry="1.5" stroke-width="1.5"/>\ + <circle cx="4.375" cy="4.375" r="1" stroke-width=".75"/>\ + <path d="m3 7.375h16m0-3h-4" stroke-width="1.25"/></svg>'); + width: 22px; + height: 22px; + } + /* Display an alternating layout on tablets and phones */ .item-table, .item-row, .item-table > li, .item-table > li > div, .search-results > a, .search-results > a > div { @@ -2274,6 +2419,8 @@ in src-script.js --scrape-example-help-hover-color: #000; --scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1); --scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0); + --sidebar-resizer-hover: hsl(207, 90%, 66%); + --sidebar-resizer-active: hsl(207, 90%, 54%); } /* End theme: light */ @@ -2379,6 +2526,8 @@ in src-script.js --scrape-example-help-hover-color: #fff; --scrape-example-code-wrapper-background-start: rgba(53, 53, 53, 1); --scrape-example-code-wrapper-background-end: rgba(53, 53, 53, 0); + --sidebar-resizer-hover: hsl(207, 30%, 54%); + --sidebar-resizer-active: hsl(207, 90%, 54%); } /* End theme: dark */ @@ -2488,6 +2637,8 @@ Original by Dempfi (https://github.com/dempfi/ayu) --scrape-example-help-hover-color: #fff; --scrape-example-code-wrapper-background-start: rgba(15, 20, 25, 1); --scrape-example-code-wrapper-background-end: rgba(15, 20, 25, 0); + --sidebar-resizer-hover: hsl(34, 50%, 33%); + --sidebar-resizer-active: hsl(34, 100%, 66%); } :root[data-theme="ayu"] h1, @@ -2519,6 +2670,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) } :root[data-theme="ayu"] .sidebar .current, +:root[data-theme="ayu"] .sidebar .current a, :root[data-theme="ayu"] .sidebar a:hover, :root[data-theme="ayu"] #src-sidebar div.files > a:hover, :root[data-theme="ayu"] details.dir-entry summary:hover, @@ -2569,7 +2721,8 @@ Original by Dempfi (https://github.com/dempfi/ayu) border-bottom: 1px solid rgba(242, 151, 24, 0.3); } -:root[data-theme="ayu"] #settings-menu > a img { +:root[data-theme="ayu"] #settings-menu > a img, +:root[data-theme="ayu"] #sidebar-button > a:before { filter: invert(100); } /* End theme: ayu */ diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js index 2338931a18f..93709e4e830 100644 --- a/src/librustdoc/html/static/js/externs.js +++ b/src/librustdoc/html/static/js/externs.js @@ -14,7 +14,7 @@ function initSearch(searchIndex){} * pathWithoutLast: Array<string>, * pathLast: string, * generics: Array<QueryElement>, - * bindings: Map<(string|integer), Array<QueryElement>>, + * bindings: Map<integer, Array<QueryElement>>, * }} */ let QueryElement; @@ -42,6 +42,7 @@ let ParserState; * totalElems: number, * literalSearch: boolean, * corrections: Array<{from: string, to: integer}>, + * typeFingerprint: Uint32Array, * }} */ let ParsedQuery; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index d613997cd7f..63ab56053af 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,5 +1,5 @@ // Local js definitions: -/* global addClass, getSettingValue, hasClass, searchState */ +/* global addClass, getSettingValue, hasClass, searchState, updateLocalStorage */ /* global onEach, onEachLazy, removeClass, getVar */ "use strict"; @@ -495,7 +495,7 @@ function preLoadCss(cssUrl) { } const link = document.createElement("a"); link.href = path; - if (link.href === current_page) { + if (path === current_page) { link.className = "current"; } link.textContent = name; @@ -857,12 +857,12 @@ function preLoadCss(cssUrl) { for (const crate of window.ALL_CRATES) { const link = document.createElement("a"); link.href = window.rootPath + crate + "/index.html"; - if (window.rootPath !== "./" && crate === window.currentCrate) { - link.className = "current"; - } link.textContent = crate; const li = document.createElement("li"); + if (window.rootPath !== "./" && crate === window.currentCrate) { + li.className = "current"; + } li.appendChild(link); ul.appendChild(li); } @@ -1473,6 +1473,264 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm searchState.setup(); }()); +// Hide, show, and resize the sidebar +// +// The body class and CSS variable are initially set up in storage.js, +// but in this file, we implement: +// +// * the show sidebar button, which appears if the sidebar is hidden +// and, by clicking on it, will bring it back +// * the sidebar resize handle, which appears only on large viewports +// with a [fine precision pointer] to allow the user to change +// the size of the sidebar +// +// [fine precision pointer]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer +(function() { + // 100 is the size of the logo + // don't let the sidebar get smaller than that, or it'll get squished + const SIDEBAR_MIN = 100; + // Don't let the sidebar get bigger than this + const SIDEBAR_MAX = 500; + // Don't let the body (including the gutter) get smaller than this + // + // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY + // Acceptable values for BODY_MIN are constrained by the mobile breakpoint + // (which is the minimum size of the whole page where the sidebar exists) + // and the default sidebar width: + // + // BODY_MIN <= RUSTDOC_MOBILE_BREAKPOINT - DEFAULT_SIDEBAR_WIDTH + // + // At the time of this writing, the DEFAULT_SIDEBAR_WIDTH on src pages is + // 300px, and the RUSTDOC_MOBILE_BREAKPOINT is 700px, so BODY_MIN must be + // at most 400px. Otherwise, it would start out at the default size, then + // grabbing the resize handle would suddenly cause it to jank to + // its contraint-generated maximum. + const RUSTDOC_MOBILE_BREAKPOINT = 700; + const BODY_MIN = 400; + // At half-way past the minimum size, vanish the sidebar entirely + const SIDEBAR_VANISH_THRESHOLD = SIDEBAR_MIN / 2; + + // Toolbar button to show the sidebar. + // + // On small, "mobile-sized" viewports, it's not persistent and it + // can only be activated by going into Settings and hiding the nav bar. + // On larger, "desktop-sized" viewports (though that includes many + // tablets), it's fixed-position, appears in the left side margin, + // and it can be activated by resizing the sidebar into nothing. + const sidebarButton = document.getElementById("sidebar-button"); + if (sidebarButton) { + sidebarButton.addEventListener("click", e => { + removeClass(document.documentElement, "hide-sidebar"); + updateLocalStorage("hide-sidebar", "false"); + e.preventDefault(); + }); + } + + // Pointer capture. + // + // Resizing is a single-pointer gesture. Any secondary pointer is ignored + let currentPointerId = null; + + // "Desired" sidebar size. + // + // This is stashed here for window resizing. If the sidebar gets + // shrunk to maintain BODY_MIN, and then the user grows the window again, + // it gets the sidebar to restore its size. + let desiredSidebarSize = null; + + // Sidebar resize debouncer. + // + // The sidebar itself is resized instantly, but the body HTML can be too + // big for that, causing reflow jank. To reduce this, we queue up a separate + // animation frame and throttle it. + let pendingSidebarResizingFrame = false; + + // If this page has no sidebar at all, bail out. + const resizer = document.querySelector(".sidebar-resizer"); + const sidebar = document.querySelector(".sidebar"); + if (!resizer || !sidebar) { + return; + } + + // src page and docs page use different variables, because the contents of + // the sidebar are so different that it's reasonable to thing the user + // would want them to have different sizes + const isSrcPage = hasClass(document.body, "src"); + + // Call this function to hide the sidebar when using the resize handle + // + // This function also nulls out the sidebar width CSS variable and setting, + // causing it to return to its default. This does not happen if you do it + // from settings.js, which uses a separate function. It's done here because + // the minimum sidebar size is rather uncomfortable, and it must pass + // through that size when using the shrink-to-nothing gesture. + function hideSidebar() { + if (isSrcPage) { + window.rustdocCloseSourceSidebar(); + updateLocalStorage("src-sidebar-width", null); + // [RUSTDOCIMPL] CSS variable fast path + // + // The sidebar width variable is attached to the <html> element by + // storage.js, because the sidebar and resizer don't exist yet. + // But the resize code, in `resize()`, sets the property on the + // sidebar and resizer elements (which are the only elements that + // use the variable) to avoid recalculating CSS on the entire + // document on every frame. + // + // So, to clear it, we need to clear all three. + document.documentElement.style.removeProperty("--src-sidebar-width"); + sidebar.style.removeProperty("--src-sidebar-width"); + resizer.style.removeProperty("--src-sidebar-width"); + } else { + addClass(document.documentElement, "hide-sidebar"); + updateLocalStorage("hide-sidebar", "true"); + updateLocalStorage("desktop-sidebar-width", null); + document.documentElement.style.removeProperty("--desktop-sidebar-width"); + sidebar.style.removeProperty("--desktop-sidebar-width"); + resizer.style.removeProperty("--desktop-sidebar-width"); + } + } + + // Call this function to show the sidebar from the resize handle. + // On docs pages, this can only happen if the user has grabbed the resize + // handle, shrunk the sidebar down to nothing, and then pulls back into + // the visible range without releasing it. You can, however, grab the + // resize handle on a source page with the sidebar closed, because it + // remains visible all the time on there. + function showSidebar() { + if (isSrcPage) { + window.rustdocShowSourceSidebar(); + } else { + removeClass(document.documentElement, "hide-sidebar"); + updateLocalStorage("hide-sidebar", "false"); + } + } + + /** + * Call this to set the correct CSS variable and setting. + * This function doesn't enforce size constraints. Do that before calling it! + * + * @param {number} size - CSS px width of the sidebar. + */ + function changeSidebarSize(size) { + if (isSrcPage) { + updateLocalStorage("src-sidebar-width", size); + // [RUSTDOCIMPL] CSS variable fast path + // + // While this property is set on the HTML element at load time, + // because the sidebar isn't actually loaded yet, + // we scope this update to the sidebar to avoid hitting a slow + // path in WebKit. + sidebar.style.setProperty("--src-sidebar-width", size + "px"); + resizer.style.setProperty("--src-sidebar-width", size + "px"); + } else { + updateLocalStorage("desktop-sidebar-width", size); + sidebar.style.setProperty("--desktop-sidebar-width", size + "px"); + resizer.style.setProperty("--desktop-sidebar-width", size + "px"); + } + } + + // Check if the sidebar is hidden. Since src pages and doc pages have + // different settings, this function has to check that. + function isSidebarHidden() { + return isSrcPage ? + !hasClass(document.documentElement, "src-sidebar-expanded") : + hasClass(document.documentElement, "hide-sidebar"); + } + + // Respond to the resize handle event. + // This function enforces size constraints, and implements the + // shrink-to-nothing gesture based on thresholds defined above. + function resize(e) { + if (currentPointerId === null || currentPointerId !== e.pointerId) { + return; + } + e.preventDefault(); + const pos = e.clientX - sidebar.offsetLeft - 3; + if (pos < SIDEBAR_VANISH_THRESHOLD) { + hideSidebar(); + } else if (pos >= SIDEBAR_MIN) { + if (isSidebarHidden()) { + showSidebar(); + } + // don't let the sidebar get wider than SIDEBAR_MAX, or the body narrower + // than BODY_MIN + const constrainedPos = Math.min(pos, window.innerWidth - BODY_MIN, SIDEBAR_MAX); + changeSidebarSize(constrainedPos); + desiredSidebarSize = constrainedPos; + if (pendingSidebarResizingFrame !== false) { + clearTimeout(pendingSidebarResizingFrame); + } + pendingSidebarResizingFrame = setTimeout(() => { + if (currentPointerId === null || pendingSidebarResizingFrame === false) { + return; + } + pendingSidebarResizingFrame = false; + document.documentElement.style.setProperty( + "--resizing-sidebar-width", + desiredSidebarSize + "px" + ); + }, 100); + } + } + // Respond to the window resize event. + window.addEventListener("resize", () => { + if (window.innerWidth < RUSTDOC_MOBILE_BREAKPOINT) { + return; + } + stopResize(); + if (desiredSidebarSize >= (window.innerWidth - BODY_MIN)) { + changeSidebarSize(window.innerWidth - BODY_MIN); + } else if (desiredSidebarSize !== null && desiredSidebarSize > SIDEBAR_MIN) { + changeSidebarSize(desiredSidebarSize); + } + }); + function stopResize(e) { + if (currentPointerId === null) { + return; + } + if (e) { + e.preventDefault(); + } + desiredSidebarSize = sidebar.getBoundingClientRect().width; + removeClass(resizer, "active"); + window.removeEventListener("pointermove", resize, false); + window.removeEventListener("pointerup", stopResize, false); + removeClass(document.documentElement, "sidebar-resizing"); + document.documentElement.style.removeProperty( "--resizing-sidebar-width"); + if (resizer.releasePointerCapture) { + resizer.releasePointerCapture(currentPointerId); + currentPointerId = null; + } + } + function initResize(e) { + if (currentPointerId !== null || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { + return; + } + if (resizer.setPointerCapture) { + resizer.setPointerCapture(e.pointerId); + if (!resizer.hasPointerCapture(e.pointerId)) { + // unable to capture pointer; something else has it + // on iOS, this usually means you long-clicked a link instead + resizer.releasePointerCapture(e.pointerId); + return; + } + currentPointerId = e.pointerId; + } + e.preventDefault(); + window.addEventListener("pointermove", resize, false); + window.addEventListener("pointercancel", stopResize, false); + window.addEventListener("pointerup", stopResize, false); + addClass(resizer, "active"); + addClass(document.documentElement, "sidebar-resizing"); + const pos = e.clientX - sidebar.offsetLeft - 3; + document.documentElement.style.setProperty( "--resizing-sidebar-width", pos + "px"); + desiredSidebarSize = null; + } + resizer.addEventListener("pointerdown", initResize, false); +}()); + +// This section handles the copy button that appears next to the path breadcrumbs (function() { let reset_button_timeout = null; diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index f2875b7f01e..ccb54e14a5c 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -80,10 +80,6 @@ const longItemTypes = [ const TY_GENERIC = itemTypes.indexOf("generic"); const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../"; -function hasOwnPropertyRustdoc(obj, property) { - return Object.prototype.hasOwnProperty.call(obj, property); -} - // In the search display, allows to switch between tabs. function printTab(nb) { let iter = 0; @@ -238,6 +234,10 @@ function initSearch(rawSearchIndex) { * @type {Array<Row>} */ let searchIndex; + /** + * @type {Uint32Array} + */ + let functionTypeFingerprint; let currentResults; /** * Map from normalized type names to integers. Used to make type search @@ -1038,6 +1038,8 @@ function initSearch(rawSearchIndex) { correction: null, proposeCorrectionFrom: null, proposeCorrectionTo: null, + // bloom filter build from type ids + typeFingerprint: new Uint32Array(4), }; } @@ -1068,7 +1070,7 @@ function initSearch(rawSearchIndex) { if (elem && elem.value !== "all crates" && - hasOwnPropertyRustdoc(rawSearchIndex, elem.value) + rawSearchIndex.has(elem.value) ) { return elem.value; } @@ -1133,7 +1135,6 @@ function initSearch(rawSearchIndex) { query.error = err; return query; } - if (!query.literalSearch) { // If there is more than one element in the query, we switch to literalSearch in any // case. @@ -1329,25 +1330,6 @@ function initSearch(rawSearchIndex) { return 0; }); - let nameSplit = null; - if (parsedQuery.elems.length === 1) { - const hasPath = typeof parsedQuery.elems[0].path === "undefined"; - nameSplit = hasPath ? null : parsedQuery.elems[0].path; - } - - for (const result of result_list) { - // this validation does not make sense when searching by types - if (result.dontValidate) { - continue; - } - const name = result.item.name.toLowerCase(), - path = result.item.path.toLowerCase(), - parent = result.item.parent; - - if (!isType && !validateResult(name, path, nameSplit, parent)) { - result.id = -1; - } - } return transformResults(result_list); } @@ -1960,8 +1942,7 @@ function initSearch(rawSearchIndex) { * @param {integer} path_dist */ function addIntoResults(results, fullId, id, index, dist, path_dist, maxEditDistance) { - const inBounds = dist <= maxEditDistance || index !== -1; - if (dist === 0 || (!parsedQuery.literalSearch && inBounds)) { + if (dist <= maxEditDistance || index !== -1) { if (results.has(fullId)) { const result = results.get(fullId); if (result.dontValidate || result.dist <= dist) { @@ -2009,17 +1990,31 @@ function initSearch(rawSearchIndex) { const fullId = row.id; const searchWord = searchWords[pos]; - const in_args = row.type && row.type.inputs - && checkIfInList(row.type.inputs, elem, row.type.where_clause); - if (in_args) { - // path_dist is 0 because no parent path information is currently stored - // in the search index - addIntoResults(results_in_args, fullId, pos, -1, 0, 0, maxEditDistance); - } - const returned = row.type && row.type.output - && checkIfInList(row.type.output, elem, row.type.where_clause); - if (returned) { - addIntoResults(results_returned, fullId, pos, -1, 0, 0, maxEditDistance); + // fpDist is a minimum possible type distance, where "type distance" is the number of + // atoms in the function not present in the query + const tfpDist = compareTypeFingerprints( + fullId, + parsedQuery.typeFingerprint + ); + if (tfpDist !== null) { + const in_args = row.type && row.type.inputs + && checkIfInList(row.type.inputs, elem, row.type.where_clause); + const returned = row.type && row.type.output + && checkIfInList(row.type.output, elem, row.type.where_clause); + if (in_args) { + results_in_args.max_dist = Math.max(results_in_args.max_dist || 0, tfpDist); + const maxDist = results_in_args.size < MAX_RESULTS ? + (tfpDist + 1) : + results_in_args.max_dist; + addIntoResults(results_in_args, fullId, pos, -1, tfpDist, 0, maxDist); + } + if (returned) { + results_returned.max_dist = Math.max(results_returned.max_dist || 0, tfpDist); + const maxDist = results_returned.size < MAX_RESULTS ? + (tfpDist + 1) : + results_returned.max_dist; + addIntoResults(results_returned, fullId, pos, -1, tfpDist, 0, maxDist); + } } if (!typePassesFilter(elem.typeFilter, row.ty)) { @@ -2078,6 +2073,17 @@ function initSearch(rawSearchIndex) { return; } + const tfpDist = compareTypeFingerprints( + row.id, + parsedQuery.typeFingerprint + ); + if (tfpDist === null) { + return; + } + if (results.size >= MAX_RESULTS && tfpDist > results.max_dist) { + return; + } + // If the result is too "bad", we return false and it ends this search. if (!unifyFunctionTypes( row.type.inputs, @@ -2096,12 +2102,11 @@ function initSearch(rawSearchIndex) { return; } - addIntoResults(results, row.id, pos, 0, 0, 0, Number.MAX_VALUE); + results.max_dist = Math.max(results.max_dist || 0, tfpDist); + addIntoResults(results, row.id, pos, 0, tfpDist, 0, Number.MAX_VALUE); } function innerRunQuery() { - let elem, i, nSearchWords, in_returned, row; - let queryLen = 0; for (const elem of parsedQuery.elems) { queryLen += elem.name.length; @@ -2218,17 +2223,20 @@ function initSearch(rawSearchIndex) { ); } + const fps = new Set(); for (const elem of parsedQuery.elems) { convertNameToId(elem); + buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint, fps); } for (const elem of parsedQuery.returned) { convertNameToId(elem); + buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint, fps); } - if (parsedQuery.foundElems === 1) { + if (parsedQuery.foundElems === 1 && parsedQuery.returned.length === 0) { if (parsedQuery.elems.length === 1) { - elem = parsedQuery.elems[0]; - for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + const elem = parsedQuery.elems[0]; + for (let i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { // It means we want to check for this element everywhere (in names, args and // returned). handleSingleArg( @@ -2241,30 +2249,25 @@ function initSearch(rawSearchIndex) { maxEditDistance ); } - } else if (parsedQuery.returned.length === 1) { - // We received one returned argument to check, so looking into returned values. - elem = parsedQuery.returned[0]; - for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { - row = searchIndex[i]; - in_returned = row.type && unifyFunctionTypes( - row.type.output, - parsedQuery.returned, - row.type.where_clause - ); - if (in_returned) { - addIntoResults( - results_others, - row.id, - i, - -1, - 0, - Number.MAX_VALUE - ); - } - } } } else if (parsedQuery.foundElems > 0) { - for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + // Sort input and output so that generic type variables go first and + // types with generic parameters go last. + // That's because of the way unification is structured: it eats off + // the end, and hits a fast path if the last item is a simple atom. + const sortQ = (a, b) => { + const ag = a.generics.length === 0 && a.bindings.size === 0; + const bg = b.generics.length === 0 && b.bindings.size === 0; + if (ag !== bg) { + return ag - bg; + } + const ai = a.id > 0; + const bi = b.id > 0; + return ai - bi; + }; + parsedQuery.elems.sort(sortQ); + parsedQuery.returned.sort(sortQ); + for (let i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { handleArgs(searchIndex[i], i, results_others); } } @@ -2287,44 +2290,6 @@ function initSearch(rawSearchIndex) { return ret; } - /** - * Validate performs the following boolean logic. For example: - * "File::open" will give IF A PARENT EXISTS => ("file" && "open") - * exists in (name || path || parent) OR => ("file" && "open") exists in - * (name || path ) - * - * This could be written functionally, but I wanted to minimise - * functions on stack. - * - * @param {string} name - The name of the result - * @param {string} path - The path of the result - * @param {string} keys - The keys to be used (["file", "open"]) - * @param {Object} parent - The parent of the result - * - * @return {boolean} - Whether the result is valid or not - */ - function validateResult(name, path, keys, parent, maxEditDistance) { - if (!keys || !keys.length) { - return true; - } - for (const key of keys) { - // each check is for validation so we negate the conditions and invalidate - if (!( - // check for an exact name match - name.indexOf(key) > -1 || - // then an exact path match - path.indexOf(key) > -1 || - // next if there is a parent, check for exact parent match - (parent !== undefined && parent.name !== undefined && - parent.name.toLowerCase().indexOf(key) > -1) || - // lastly check to see if the name was an editDistance match - editDistance(name, key, maxEditDistance) <= maxEditDistance)) { - return false; - } - } - return true; - } - function nextTab(direction) { const next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length; searchState.focusedByTab[searchState.currentTab] = document.activeElement; @@ -2420,7 +2385,6 @@ function initSearch(rawSearchIndex) { const extraClass = display ? " active" : ""; const output = document.createElement("div"); - let length = 0; if (array.length > 0) { output.className = "search-results " + extraClass; @@ -2430,8 +2394,6 @@ function initSearch(rawSearchIndex) { const longType = longItemTypes[item.ty]; const typeName = longType.length !== 0 ? `${longType}` : "?"; - length += 1; - const link = document.createElement("a"); link.className = "result-" + type; link.href = item.href; @@ -2479,7 +2441,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\ "href=\"https://docs.rs\">Docs.rs</a> for documentation of crates released on" + " <a href=\"https://crates.io/\">crates.io</a>.</li></ul>"; } - return [output, length]; + return [output, array.length]; } function makeTabHeader(tabNb, text, nbElems) { @@ -2558,11 +2520,10 @@ ${item.displayPath}<span class="${type}">${name}</span>\ } let crates = ""; - const crates_list = Object.keys(rawSearchIndex); - if (crates_list.length > 1) { + if (rawSearchIndex.size > 1) { crates = " in <div id=\"crate-search-div\"><select id=\"crate-search\">" + "<option value=\"all crates\">all crates</option>"; - for (const c of crates_list) { + for (const c of rawSearchIndex.keys()) { crates += `<option value="${c}" ${c === filterCrates && "selected"}>${c}</option>`; } crates += "</select></div>"; @@ -2846,6 +2807,117 @@ ${item.displayPath}<span class="${type}">${name}</span>\ }; } + /** + * Type fingerprints allow fast, approximate matching of types. + * + * This algo creates a compact representation of the type set using a Bloom filter. + * This fingerprint is used three ways: + * + * - It accelerates the matching algorithm by checking the function fingerprint against the + * query fingerprint. If any bits are set in the query but not in the function, it can't + * match. + * + * - The fourth section has the number of distinct items in the set. + * This is the distance function, used for filtering and for sorting. + * + * [^1]: Distance is the relatively naive metric of counting the number of distinct items in + * the function that are not present in the query. + * + * @param {FunctionType|QueryElement} type - a single type + * @param {Uint32Array} output - write the fingerprint to this data structure: uses 128 bits + * @param {Set<number>} fps - Set of distinct items + */ + function buildFunctionTypeFingerprint(type, output, fps) { + let input = type.id; + // All forms of `[]` get collapsed down to one thing in the bloom filter. + // Differentiating between arrays and slices, if the user asks for it, is + // still done in the matching algorithm. + if (input === typeNameIdOfArray || input === typeNameIdOfSlice) { + input = typeNameIdOfArrayOrSlice; + } + // http://burtleburtle.net/bob/hash/integer.html + // ~~ is toInt32. It's used before adding, so + // the number stays in safe integer range. + const hashint1 = k => { + k = (~~k + 0x7ed55d16) + (k << 12); + k = (k ^ 0xc761c23c) ^ (k >>> 19); + k = (~~k + 0x165667b1) + (k << 5); + k = (~~k + 0xd3a2646c) ^ (k << 9); + k = (~~k + 0xfd7046c5) + (k << 3); + return (k ^ 0xb55a4f09) ^ (k >>> 16); + }; + const hashint2 = k => { + k = ~k + (k << 15); + k ^= k >>> 12; + k += k << 2; + k ^= k >>> 4; + k = Math.imul(k, 2057); + return k ^ (k >> 16); + }; + if (input !== null) { + const h0a = hashint1(input); + const h0b = hashint2(input); + // Less Hashing, Same Performance: Building a Better Bloom Filter + // doi=10.1.1.72.2442 + const h1a = ~~(h0a + Math.imul(h0b, 2)); + const h1b = ~~(h0a + Math.imul(h0b, 3)); + const h2a = ~~(h0a + Math.imul(h0b, 4)); + const h2b = ~~(h0a + Math.imul(h0b, 5)); + output[0] |= (1 << (h0a % 32)) | (1 << (h1b % 32)); + output[1] |= (1 << (h1a % 32)) | (1 << (h2b % 32)); + output[2] |= (1 << (h2a % 32)) | (1 << (h0b % 32)); + fps.add(input); + } + for (const g of type.generics) { + buildFunctionTypeFingerprint(g, output, fps); + } + const fb = { + id: null, + ty: 0, + generics: [], + bindings: new Map(), + }; + for (const [k, v] of type.bindings.entries()) { + fb.id = k; + fb.generics = v; + buildFunctionTypeFingerprint(fb, output, fps); + } + output[3] = fps.size; + } + + /** + * Compare the query fingerprint with the function fingerprint. + * + * @param {{number}} fullId - The function + * @param {{Uint32Array}} queryFingerprint - The query + * @returns {number|null} - Null if non-match, number if distance + * This function might return 0! + */ + function compareTypeFingerprints(fullId, queryFingerprint) { + const fh0 = functionTypeFingerprint[fullId * 4]; + const fh1 = functionTypeFingerprint[(fullId * 4) + 1]; + const fh2 = functionTypeFingerprint[(fullId * 4) + 2]; + const [qh0, qh1, qh2] = queryFingerprint; + // Approximate set intersection with bloom filters. + // This can be larger than reality, not smaller, because hashes have + // the property that if they've got the same value, they hash to the + // same thing. False positives exist, but not false negatives. + const [in0, in1, in2] = [fh0 & qh0, fh1 & qh1, fh2 & qh2]; + // Approximate the set of items in the query but not the function. + // This might be smaller than reality, but cannot be bigger. + // + // | in_ | qh_ | XOR | Meaning | + // | --- | --- | --- | ------------------------------------------------ | + // | 0 | 0 | 0 | Not present | + // | 1 | 0 | 1 | IMPOSSIBLE because `in_` is `fh_ & qh_` | + // | 1 | 1 | 0 | If one or both is false positive, false negative | + // | 0 | 1 | 1 | Since in_ has no false negatives, must be real | + if ((in0 ^ qh0) || (in1 ^ qh1) || (in2 ^ qh2)) { + return null; + } + return functionTypeFingerprint[(fullId * 4) + 3]; + } + function buildIndex(rawSearchIndex) { searchIndex = []; /** @@ -2865,68 +2937,73 @@ ${item.displayPath}<span class="${type}">${name}</span>\ typeNameIdOfSlice = buildTypeMapIndex("slice"); typeNameIdOfArrayOrSlice = buildTypeMapIndex("[]"); - for (const crate in rawSearchIndex) { - if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) { - continue; - } - - let crateSize = 0; - - /** - * The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f` - * are arrays with the same length. `q`, `a`, and `c` use a sparse - * representation for compactness. - * - * `n[i]` contains the name of an item. - * - * `t[i]` contains the type of that item - * (as a string of characters that represent an offset in `itemTypes`). - * - * `d[i]` contains the description of that item. - * - * `q` contains the full paths of the items. For compactness, it is a set of - * (index, path) pairs used to create a map. If a given index `i` is - * not present, this indicates "same as the last index present". - * - * `i[i]` contains an item's parent, usually a module. For compactness, - * it is a set of indexes into the `p` array. - * - * `f[i]` contains function signatures, or `0` if the item isn't a function. - * Functions are themselves encoded as arrays. The first item is a list of - * types representing the function's inputs, and the second list item is a list - * of types representing the function's output. Tuples are flattened. - * Types are also represented as arrays; the first item is an index into the `p` - * array, while the second is a list of types representing any generic parameters. - * - * b[i] contains an item's impl disambiguator. This is only present if an item - * is defined in an impl block and, the impl block's type has more than one associated - * item with the same name. - * - * `a` defines aliases with an Array of pairs: [name, offset], where `offset` - * points into the n/t/d/q/i/f arrays. - * - * `doc` contains the description of the crate. - * - * `p` is a list of path/type pairs. It is used for parents and function parameters. - * - * `c` is an array of item indices that are deprecated. - * - * @type {{ - * doc: string, - * a: Object, - * n: Array<string>, - * t: String, - * d: Array<string>, - * q: Array<[Number, string]>, - * i: Array<Number>, - * f: Array<RawFunctionSearchType>, - * p: Array<Object>, - * b: Array<[Number, String]>, - * c: Array<Number> - * }} - */ - const crateCorpus = rawSearchIndex[crate]; + // Function type fingerprints are 128-bit bloom filters that are used to + // estimate the distance between function and query. + // This loop counts the number of items to allocate a fingerprint for. + for (const crate of rawSearchIndex.values()) { + // Each item gets an entry in the fingerprint array, and the crate + // does, too + id += crate.t.length + 1; + } + functionTypeFingerprint = new Uint32Array((id + 1) * 4); + // This loop actually generates the search item indexes, including + // normalized names, type signature objects and fingerprints, and aliases. + id = 0; + /** + * The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f` + * are arrays with the same length. `q`, `a`, and `c` use a sparse + * representation for compactness. + * + * `n[i]` contains the name of an item. + * + * `t[i]` contains the type of that item + * (as a string of characters that represent an offset in `itemTypes`). + * + * `d[i]` contains the description of that item. + * + * `q` contains the full paths of the items. For compactness, it is a set of + * (index, path) pairs used to create a map. If a given index `i` is + * not present, this indicates "same as the last index present". + * + * `i[i]` contains an item's parent, usually a module. For compactness, + * it is a set of indexes into the `p` array. + * + * `f[i]` contains function signatures, or `0` if the item isn't a function. + * Functions are themselves encoded as arrays. The first item is a list of + * types representing the function's inputs, and the second list item is a list + * of types representing the function's output. Tuples are flattened. + * Types are also represented as arrays; the first item is an index into the `p` + * array, while the second is a list of types representing any generic parameters. + * + * b[i] contains an item's impl disambiguator. This is only present if an item + * is defined in an impl block and, the impl block's type has more than one associated + * item with the same name. + * + * `a` defines aliases with an Array of pairs: [name, offset], where `offset` + * points into the n/t/d/q/i/f arrays. + * + * `doc` contains the description of the crate. + * + * `p` is a list of path/type pairs. It is used for parents and function parameters. + * + * `c` is an array of item indices that are deprecated. + * + * @type {{ + * doc: string, + * a: Object, + * n: Array<string>, + * t: String, + * d: Array<string>, + * q: Array<[Number, string]>, + * i: Array<Number>, + * f: Array<RawFunctionSearchType>, + * p: Array<Object>, + * b: Array<[Number, String]>, + * c: Array<Number> + * }} + */ + for (const [crate, crateCorpus] of rawSearchIndex) { searchWords.push(crate); // This object should have exactly the same set of fields as the "row" // object defined below. Your JavaScript runtime will thank you. @@ -3014,6 +3091,28 @@ ${item.displayPath}<span class="${type}">${name}</span>\ } searchWords.push(word); const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath; + let type = null; + if (itemFunctionSearchTypes[i] !== 0) { + type = buildFunctionSearchType( + itemFunctionSearchTypes[i], + lowercasePaths + ); + if (type) { + const fp = functionTypeFingerprint.subarray(id * 4, (id + 1) * 4); + const fps = new Set(); + for (const t of type.inputs) { + buildFunctionTypeFingerprint(t, fp, fps); + } + for (const t of type.output) { + buildFunctionTypeFingerprint(t, fp, fps); + } + for (const w of type.where_clause) { + for (const t of w) { + buildFunctionTypeFingerprint(t, fp, fps); + } + } + } + } const row = { crate: crate, ty: itemTypes.charCodeAt(i) - charA, @@ -3021,10 +3120,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\ path: path, desc: itemDescs[i], parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, - type: buildFunctionSearchType( - itemFunctionSearchTypes[i], - lowercasePaths - ), + type, id: id, normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""), deprecated: deprecatedItems.has(i), @@ -3033,14 +3129,13 @@ ${item.displayPath}<span class="${type}">${name}</span>\ id += 1; searchIndex.push(row); lastPath = row.path; - crateSize += 1; } if (aliases) { const currentCrateAliases = new Map(); ALIASES.set(crate, currentCrateAliases); for (const alias_name in aliases) { - if (!hasOwnPropertyRustdoc(aliases, alias_name)) { + if (!Object.prototype.hasOwnProperty.call(aliases, alias_name)) { continue; } @@ -3056,7 +3151,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\ } } } - currentIndex += crateSize; + currentIndex += itemTypes.length; } return searchWords; } @@ -3265,7 +3360,7 @@ if (typeof window !== "undefined") { } else { // Running in Node, not a browser. Run initSearch just to produce the // exports. - initSearch({}); + initSearch(new Map()); } diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 70a2825265e..2b42fbebb80 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -29,6 +29,13 @@ window.rustdoc_remove_line_numbers_from_examples(); } break; + case "hide-sidebar": + if (value === true) { + addClass(document.documentElement, "hide-sidebar"); + } else { + removeClass(document.documentElement, "hide-sidebar"); + } + break; } } @@ -187,6 +194,11 @@ "default": false, }, { + "name": "Hide persistent navigation bar", + "js_name": "hide-sidebar", + "default": false, + }, + { "name": "Disable keyboard shortcuts", "js_name": "disable-shortcuts", "default": false, @@ -216,6 +228,13 @@ function displaySettings() { settingsMenu.style.display = ""; + onEachLazy(settingsMenu.querySelectorAll("input[type='checkbox']"), el => { + const val = getSettingValue(el.id); + const checked = val === "true"; + if (checked !== el.checked && val !== null) { + el.checked = checked; + } + }); } function settingsBlurHandler(event) { diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js index 679c2341f02..fc1d2d37845 100644 --- a/src/librustdoc/html/static/js/src-script.js +++ b/src/librustdoc/html/static/js/src-script.js @@ -71,16 +71,31 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { return hasFoundFile; } +let toggleLabel; + +function getToggleLabel() { + toggleLabel = toggleLabel || document.querySelector("#src-sidebar-toggle button"); + return toggleLabel; +} + +window.rustdocCloseSourceSidebar = () => { + removeClass(document.documentElement, "src-sidebar-expanded"); + getToggleLabel().innerText = ">"; + updateLocalStorage("source-sidebar-show", "false"); +}; + +window.rustdocShowSourceSidebar = () => { + addClass(document.documentElement, "src-sidebar-expanded"); + getToggleLabel().innerText = "<"; + updateLocalStorage("source-sidebar-show", "true"); +}; + function toggleSidebar() { const child = this.parentNode.children[0]; if (child.innerText === ">") { - addClass(document.documentElement, "src-sidebar-expanded"); - child.innerText = "<"; - updateLocalStorage("source-sidebar-show", "true"); + window.rustdocShowSourceSidebar(); } else { - removeClass(document.documentElement, "src-sidebar-expanded"); - child.innerText = ">"; - updateLocalStorage("source-sidebar-show", "false"); + window.rustdocCloseSourceSidebar(); } } @@ -118,10 +133,10 @@ function createSrcSidebar() { title.className = "title"; title.innerText = "Files"; sidebar.appendChild(title); - Object.keys(srcIndex).forEach(key => { - srcIndex[key][NAME_OFFSET] = key; - hasFoundFile = createDirEntry(srcIndex[key], sidebar, "", hasFoundFile); - }); + for (const [key, source] of srcIndex) { + source[NAME_OFFSET] = key; + hasFoundFile = createDirEntry(source, sidebar, "", hasFoundFile); + } container.appendChild(sidebar); // Focus on the current file in the source files sidebar. @@ -131,12 +146,8 @@ function createSrcSidebar() { } } -const lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/; - -function highlightSrcLines(match) { - if (typeof match === "undefined") { - match = window.location.hash.match(lineNumbersRegex); - } +function highlightSrcLines() { + const match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); if (!match) { return; } @@ -218,12 +229,7 @@ const handleSrcHighlight = (function() { }; }()); -window.addEventListener("hashchange", () => { - const match = window.location.hash.match(lineNumbersRegex); - if (match) { - return highlightSrcLines(match); - } -}); +window.addEventListener("hashchange", highlightSrcLines); onEachLazy(document.getElementsByClassName("src-line-numbers"), el => { el.addEventListener("click", handleSrcHighlight); diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 37250ba5a1f..ac9c6f377b8 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -183,11 +183,38 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) { updateTheme(); +// Hide, show, and resize the sidebar at page load time +// +// This needs to be done here because this JS is render-blocking, +// so that the sidebar doesn't "jump" after appearing on screen. +// The user interaction to change this is set up in main.js. if (getSettingValue("source-sidebar-show") === "true") { // At this point in page load, `document.body` is not available yet. // Set a class on the `<html>` element instead. addClass(document.documentElement, "src-sidebar-expanded"); } +if (getSettingValue("hide-sidebar") === "true") { + // At this point in page load, `document.body` is not available yet. + // Set a class on the `<html>` element instead. + addClass(document.documentElement, "hide-sidebar"); +} +function updateSidebarWidth() { + const desktopSidebarWidth = getSettingValue("desktop-sidebar-width"); + if (desktopSidebarWidth && desktopSidebarWidth !== "null") { + document.documentElement.style.setProperty( + "--desktop-sidebar-width", + desktopSidebarWidth + "px" + ); + } + const srcSidebarWidth = getSettingValue("src-sidebar-width"); + if (srcSidebarWidth && srcSidebarWidth !== "null") { + document.documentElement.style.setProperty( + "--src-sidebar-width", + srcSidebarWidth + "px" + ); + } +} +updateSidebarWidth(); // If we navigate away (for example to a settings page), and then use the back or // forward button to get back to a page, the theme may have changed in the meantime. @@ -201,5 +228,6 @@ if (getSettingValue("source-sidebar-show") === "true") { window.addEventListener("pageshow", ev => { if (ev.persisted) { setTimeout(updateTheme, 0); + setTimeout(updateSidebarWidth, 0); } }); diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 3f6147bb916..60ca5660c02 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -114,6 +114,7 @@ {% endif %} {{ sidebar|safe }} </nav> {# #} + <div class="sidebar-resizer"></div> <main> {# #} {% if page.css_class != "src" %}<div class="width-limiter">{% endif %} <nav class="sub"> {# #} @@ -128,6 +129,11 @@ {% endif %} <form class="search-form"> {# #} <span></span> {# This empty span is a hacky fix for Safari - See #93184 #} + {% if page.css_class != "src" %} + <div id="sidebar-button" tabindex="-1"> {# #} + <a href="{{page.root_path|safe}}{{layout.krate|safe}}/all.html" title="show sidebar"></a> {# #} + </div> {# #} + {% endif %} <input {#+ #} class="search-input" {#+ #} name="search" {#+ #} @@ -136,8 +142,8 @@ spellcheck="false" {#+ #} placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {#+ #} type="search"> {# #} - <div id="help-button" title="help" tabindex="-1"> {# #} - <a href="{{page.root_path|safe}}help.html">?</a> {# #} + <div id="help-button" tabindex="-1"> {# #} + <a href="{{page.root_path|safe}}help.html" title="help">?</a> {# #} </div> {# #} <div id="settings-menu" tabindex="-1"> {# #} <a href="{{page.root_path|safe}}settings.html" title="settings"> {# #} diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index d45040e348a..267f1cb0b72 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -33,7 +33,7 @@ where let lints = || { lint::builtin::HardwiredLints::get_lints() .into_iter() - .chain(rustc_lint::SoftLints::get_lints().into_iter()) + .chain(rustc_lint::SoftLints::get_lints()) }; let lint_opts = lints() @@ -46,7 +46,7 @@ where filter_call(lint) } }) - .chain(lint_opts.into_iter()) + .chain(lint_opts) .collect::<Vec<_>>(); let lint_caps = lints() diff --git a/src/librustdoc/passes/check_custom_code_classes.rs b/src/librustdoc/passes/check_custom_code_classes.rs index 6266d3ff51d..f246e2962fe 100644 --- a/src/librustdoc/passes/check_custom_code_classes.rs +++ b/src/librustdoc/passes/check_custom_code_classes.rs @@ -48,7 +48,7 @@ struct TestsWithCustomClasses { impl crate::doctest::Tester for TestsWithCustomClasses { fn add_test(&mut self, _: String, config: LangString, _: usize) { - self.custom_classes_found.extend(config.added_classes.into_iter()); + self.custom_classes_found.extend(config.added_classes); } } diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 21a31b9df93..a931e8804d9 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -80,7 +80,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - // check if parent is trait impl if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id) - && let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id) + && let Some(parent_node) = cx.tcx.opt_hir_node_by_def_id(parent_def_id) && matches!( parent_node, hir::Node::Item(hir::Item { @@ -131,7 +131,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item hir_id, sp, "missing code example in this documentation", - |lint| lint, + |_| {}, ); } } else if tests.found_tests > 0 @@ -142,7 +142,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item hir_id, item.attr_span(cx.tcx), "documentation test in private item", - |lint| lint, + |_| {}, ); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 6b536e97c43..ee185ab9892 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1755,8 +1755,6 @@ fn report_diagnostic( } decorate(lint, span, link_range); - - lint }); } diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index 0c5cfffe1be..bffa17da3b4 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -31,7 +31,7 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) { "use an automatic link instead", format!("<{url}>"), Applicability::MachineApplicable, - ) + ); }); }; diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index e9b9e36a530..b5583ae4520 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -131,8 +131,6 @@ fn check_rust_syntax( for message in buffer.messages.iter() { lint.note(message.clone()); } - - lint }); } diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index 4a80c22ed08..90874c01102 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -89,7 +89,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<') || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>') { - return lint; + return; } // multipart form is chosen here because ``Vec<i32>`` would be confusing. lint.multipart_suggestion( @@ -101,8 +101,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { Applicability::MaybeIncorrect, ); } - - lint }); }; diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 472781e7d22..4491d20b478 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -181,8 +181,6 @@ fn check_inline_or_reference_unknown_redundancy( .span_label(display_span, "because label contains path that resolves to same destination") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); - - lint }); } @@ -234,8 +232,6 @@ fn check_reference_redundancy( .span_note(def_span, "referenced explicit link target defined here") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); - - lint }); } diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs index 8b7fdd6ab1f..0893cd0b40b 100644 --- a/src/librustdoc/passes/lint/unescaped_backticks.rs +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -111,8 +111,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { } suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it"); - - lint }); } Event::Code(_) => { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index bef151745d8..42ff1210f23 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -168,10 +168,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }) .collect::<Vec<_>>() }) - .chain( - [Cfg::Cfg(sym::test, None), Cfg::Cfg(sym::doc, None), Cfg::Cfg(sym::doctest, None)] - .into_iter(), - ) + .chain([ + Cfg::Cfg(sym::test, None), + Cfg::Cfg(sym::doc, None), + Cfg::Cfg(sym::doctest, None), + ]) .collect(); self.cx.cache.exact_paths = self.exact_paths; @@ -275,7 +276,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did); - let item = tcx.hir().get_by_def_id(res_did); + let item = tcx.hir_node_by_def_id(res_did); if !please_inline { let inherits_hidden = !document_hidden && inherits_doc_hidden(tcx, res_did, None); diff --git a/src/llvm-project b/src/llvm-project -Subproject 7738295178045041669876bf32b0543ec8319a5 +Subproject 2c4de6c2492d5530de3f19f41d8f88ba984c2fe diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 9787229614b27854cf73d57ffae430d7c1e6caa +Subproject 1aa9df1a5be205cce621f0bc0ea6062a5e22a98 diff --git a/src/tools/clippy/clippy_lints/src/absolute_paths.rs b/src/tools/clippy/clippy_lints/src/absolute_paths.rs index 83d15c0c425..3822b83b4bc 100644 --- a/src/tools/clippy/clippy_lints/src/absolute_paths.rs +++ b/src/tools/clippy/clippy_lints/src/absolute_paths.rs @@ -62,7 +62,7 @@ impl LateLintPass<'_> for AbsolutePaths { } = self; if !path.span.from_expansion() - && let Some(node) = cx.tcx.hir().find(hir_id) + && let Some(node) = cx.tcx.opt_hir_node(hir_id) && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(_, _))) && let [first, rest @ ..] = path.segments // Handle `::std` diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs index 55294f5f386..b55cd8833b7 100644 --- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs +++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs @@ -10,8 +10,8 @@ use super::AS_PTR_CAST_MUT; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) { if let ty::RawPtr( - ptrty @ TypeAndMut { - mutbl: Mutability::Mut, .. + TypeAndMut { + mutbl: Mutability::Mut, ty: ptrty, }, ) = cast_to.kind() && let ty::RawPtr(TypeAndMut { @@ -34,7 +34,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cx, AS_PTR_CAST_MUT, expr.span, - &format!("casting the result of `as_ptr` to *{ptrty}"), + &format!("casting the result of `as_ptr` to *mut {ptrty}"), "replace with", format!("{recv}.as_mut_ptr()"), applicability, diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs index 2a9f7fec172..91bad8256ec 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs @@ -69,7 +69,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let map = cx.tcx.hir(); if let Some(parent_id) = map.opt_parent_id(expr.hir_id) - && let Some(parent) = map.find(parent_id) + && let Some(parent) = cx.tcx.opt_hir_node(parent_id) { let expr = match parent { Node::Block(block) => { diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 854324f845b..aaef163ad55 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1090,7 +1090,7 @@ fn report<'tcx>( if parent_id == data.first_expr.hir_id { return; } - (cx.tcx.hir().get(parent_id).expect_expr().span, true) + (cx.tcx.hir_node(parent_id).expect_expr().span, true) } else { (expr.span, false) }; diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 53ef6d7e387..6b0423200d7 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -195,7 +195,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let Some(def_id) = trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::Default, def_id) && let impl_item_hir = child.id.hir_id() - && let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir) + && let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) && let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs index e97030cc8b6..1d2b907b948 100644 --- a/src/tools/clippy/clippy_lints/src/empty_drop.rs +++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs @@ -42,7 +42,7 @@ impl LateLintPass<'_> for EmptyDrop { }) = item.kind && trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait() && let impl_item_hir = child.id.hir_id() - && let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir) + && let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) && let func_expr = peel_blocks(func_expr) diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 3452f98c5aa..b7776263060 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -5,7 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, TraitRef, Ty}; +use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; @@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { .hir() .get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id)) .def_id; - let parent_node = cx.tcx.hir().find_by_def_id(parent_id); + let parent_node = cx.tcx.opt_hir_node_by_def_id(parent_id); let mut trait_self_ty = None; if let Some(Node::Item(item)) = parent_node { @@ -122,8 +122,8 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { } // TODO: Replace with Map::is_argument(..) when it's fixed -fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool { - match map.find(id) { +fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool { + match tcx.opt_hir_node(id) { Some(Node::Pat(Pat { kind: PatKind::Binding(..), .. @@ -131,7 +131,7 @@ fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool { _ => return false, } - matches!(map.find_parent(id), Some(Node::Param(_))) + matches!(tcx.hir().find_parent(id), Some(Node::Param(_))) } impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { @@ -154,7 +154,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) { if cmt.place.projections.is_empty() { let map = &self.cx.tcx.hir(); - if is_argument(*map, cmt.hir_id) { + if is_argument(self.cx.tcx, cmt.hir_id) { // Skip closure arguments let parent_id = map.parent_id(cmt.hir_id); if let Some(Node::Expr(..)) = map.find_parent(parent_id) { diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs index a974c10bc7d..6603512c73c 100644 --- a/src/tools/clippy/clippy_lints/src/exit.rs +++ b/src/tools/clippy/clippy_lints/src/exit.rs @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit { && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::process_exit, def_id) && let parent = cx.tcx.hir().get_parent_item(e.hir_id).def_id - && let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.hir().find_by_def_id(parent) + && let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.opt_hir_node_by_def_id(parent) // If the next item up is a function we check if it is an entry point // and only then emit a linter warning && !is_entrypoint_fn(cx, parent.to_def_id()) diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs index 4e2e1d1724a..f1366c434f4 100644 --- a/src/tools/clippy/clippy_lints/src/explicit_write.rs +++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs @@ -111,7 +111,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>) // Find id of the local that expr_end_of_block resolves to && let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind && let Res::Local(expr_res) = expr_path.res - && let Some(Node::Pat(res_pat)) = cx.tcx.hir().find(expr_res) + && let Some(Node::Pat(res_pat)) = cx.tcx.opt_hir_node(expr_res) // Find id of the local we found in the block && let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs index 5e90fcd72eb..f1200c2edc1 100644 --- a/src/tools/clippy/clippy_lints/src/functions/result.rs +++ b/src/tools/clippy/clippy_lints/src/functions/result.rs @@ -92,7 +92,7 @@ fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty .expect("already checked this is adt") .did() .as_local() - && let Some(hir::Node::Item(item)) = cx.tcx.hir().find_by_def_id(local_def_id) + && let Some(hir::Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(local_def_id) && let hir::ItemKind::Enum(ref def, _) = item.kind { let variants_size = AdtVariantInfo::new(cx, *adt, subst); diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index b6f9d8b81f8..5417c13d079 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -248,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { // Checking for slice indexing && let parent_id = map.parent_id(expr.hir_id) - && let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id) + && let Some(hir::Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id) && let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind && let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr) && let Ok(index_value) = index_value.try_into() @@ -256,7 +256,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { // Make sure that this slice index is read only && let maybe_addrof_id = map.parent_id(parent_id) - && let Some(hir::Node::Expr(maybe_addrof_expr)) = map.find(maybe_addrof_id) + && let Some(hir::Node::Expr(maybe_addrof_expr)) = cx.tcx.opt_hir_node(maybe_addrof_id) && let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind { use_info.index_use.push((index_value, map.span(parent_expr.hir_id))); diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index 5c926133c42..e4781752e75 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -122,7 +122,7 @@ fn get_impl_span(cx: &LateContext<'_>, id: LocalDefId) -> Option<Span> { kind: ItemKind::Impl(impl_item), span, .. - }) = cx.tcx.hir().get(id) + }) = cx.tcx.hir_node(id) { (!span.from_expansion() && impl_item.generics.params.is_empty() diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index e121da776b2..8c032b17023 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -8,8 +8,8 @@ use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::{ AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, - ImplicitSelfKind, Item, ItemKind, LangItem, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef, - TyKind, TypeBindingKind, + ImplicitSelfKind, Item, ItemKind, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef, + TyKind, TypeBindingKind, OpaqueTyOrigin, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; @@ -147,7 +147,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { && let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) { - let (name, kind) = match cx.tcx.hir().find(ty_hir_id) { + let (name, kind) = match cx.tcx.opt_hir_node(ty_hir_id) { Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"), Some(Node::Item(x)) => match x.kind { ItemKind::Struct(..) => (x.ident.name, "struct"), @@ -289,8 +289,10 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<& kind: ItemKind::OpaqueTy(opaque), .. } = item - && opaque.bounds.len() == 1 - && let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0] + && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin + && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(generic_args) = segment.args && generic_args.bindings.len() == 1 && let TypeBindingKind::Equality { term: diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 17ca48683b3..ffef84d1fad 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -195,7 +195,7 @@ fn check_fn_inner<'tcx>( .iter() // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a // `Node::GenericParam`. - .filter_map(|&def_id| cx.tcx.hir().get_by_def_id(def_id).ident()) + .filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident()) .map(|ident| ident.to_string()) .collect::<Vec<_>>() .join(", "); diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index 227096251a5..c4e60e98ad4 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -40,7 +40,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option<Span>) { fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId> { if let Some(hir_id) = path_to_local(bound) - && let Node::Pat(pat) = cx.tcx.hir().get(hir_id) + && let Node::Pat(pat) = cx.tcx.hir_node(hir_id) && let PatKind::Binding(BindingAnnotation::MUT, ..) = pat.kind { return Some(hir_id); diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs index f4eaf649f77..c245eaf1ab4 100644 --- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs +++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs @@ -58,12 +58,12 @@ pub(super) fn check<'tcx>( match cx.qpath_res(qpath, pushed_item.hir_id) { // immutable bindings that are initialized with literal or constant Res::Local(hir_id) => { - let node = cx.tcx.hir().get(hir_id); + let node = cx.tcx.hir_node(hir_id); if let Node::Pat(pat) = node && let PatKind::Binding(bind_ann, ..) = pat.kind && !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut)) && let parent_node = cx.tcx.hir().parent_id(hir_id) - && let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node) + && let Some(Node::Local(parent_let_expr)) = cx.tcx.opt_hir_node(parent_node) && let Some(init) = parent_let_expr.init { match init.kind { diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index ee053ffe4ec..eaaaea0be9f 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { && block.stmts.is_empty() && let Some(closure_body) = desugared_async_block(cx, block) && let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) = - cx.tcx.hir().get_by_def_id(def_id) + cx.tcx.hir_node_by_def_id(def_id) { let header_span = span.with_hi(ret_ty.span.hi()); diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs index e006df7d666..71a83a68db9 100644 --- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs +++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs @@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { // Also ensures the const is nonzero since zero can't be a divisor && const1 == const2 && const2 == const3 && let Some(hir_id) = path_to_local(expr3) - && let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id) + && let Some(Node::Pat(_)) = cx.tcx.opt_hir_node(hir_id) { // Apply only to params or locals with annotated types match cx.tcx.hir().find_parent(hir_id) { diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs index ac7bc9bcca4..9251130a305 100644 --- a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs +++ b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs @@ -44,7 +44,7 @@ pub(super) fn check<'tcx>( // add note if not multi-line span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| { let (applicability, pat) = if let Some(id) = path_to_local(recv) - && let Some(hir::Node::Pat(pat)) = cx.tcx.hir().find(id) + && let Some(hir::Node::Pat(pat)) = cx.tcx.opt_hir_node(id) && let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind { (Applicability::Unspecified, Some((pat.span, ident))) diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs index fbe20dfe54e..d1215290dad 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_skip_next.rs @@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr "called `skip(..).next()` on an iterator", |diag| { if let Some(id) = path_to_local(recv) - && let Node::Pat(pat) = cx.tcx.hir().get(id) + && let Node::Pat(pat) = cx.tcx.hir_node(id) && let PatKind::Binding(ann, _, _, _) = pat.kind && ann != BindingAnnotation::MUT { diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs index 826c3de1db5..63e64a5b35d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> { fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) { if let Res::Local(local_id) = path.res - && let Some(Node::Pat(pat)) = self.cx.tcx.hir().find(local_id) + && let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id) && let PatKind::Binding(_, local_id, ..) = pat.kind { self.identifiers.insert(local_id); @@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> { && let ExprKind::Path(ref path) = expr.kind && let QPath::Resolved(_, path) = path && let Res::Local(local_id) = path.res - && let Some(Node::Pat(pat)) = self.cx.tcx.hir().find(local_id) + && let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id) && let PatKind::Binding(_, local_id, ..) = pat.kind && self.identifiers.contains(&local_id) { diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs index f5b749c7f80..34b8e0dbe6a 100644 --- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs +++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs @@ -91,7 +91,7 @@ impl Visitor<'_> for IdentVisitor<'_, '_> { let node = if hir_id.local_id == ItemLocalId::from_u32(0) { // In this case, we can just use `find`, `Owner`'s `node` field is private anyway so we can't // reimplement it even if we wanted to - cx.tcx.hir().find(hir_id) + cx.tcx.opt_hir_node(hir_id) } else { let Some(owner) = cx.tcx.hir_owner_nodes(hir_id.owner).as_owner() else { return; diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index 5f736898159..acaa6be3009 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { { let parent = cx.tcx.hir().get_parent_item(hir_id).def_id; if parent != CRATE_DEF_ID { - if let hir::Node::Item(item) = cx.tcx.hir().get_by_def_id(parent) { + if let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent) { if let hir::ItemKind::Trait(..) = &item.kind { return; } diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index 8be45b8c2f3..88b331ddefd 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -220,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs() && let Some(self_adt) = self_ty.ty_adt_def() && let Some(self_def_id) = self_adt.did().as_local() - && let Some(Node::Item(self_item)) = cx.tcx.hir().find_by_def_id(self_def_id) + && let Some(Node::Item(self_item)) = cx.tcx.opt_hir_node_by_def_id(self_def_id) // NB: can't call cx.typeck_results() as we are not in a body && let typeck_results = cx.tcx.typeck_body(*body_id) && should_lint(cx, typeck_results, block) diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index cd180754113..34119c6911c 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -213,7 +213,7 @@ fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) { if parent_id == cur_id { break; } - let Some(parent_node) = map.find(parent_id) else { break }; + let Some(parent_node) = vis.cx.tcx.opt_hir_node(parent_id) else { break }; let stop_early = match parent_node { Node::Expr(expr) => check_expr(vis, expr), diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 13b736cd9ad..64ef709e2fa 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -113,8 +113,9 @@ fn check_closures<'tcx>( } ctx.prev_bind = None; ctx.prev_move_to_closure.clear(); - if let Some(body) = hir - .find_by_def_id(closure) + if let Some(body) = cx + .tcx + .opt_hir_node_by_def_id(closure) .and_then(associated_body) .map(|(_, body_id)| hir.body(body_id)) { @@ -412,7 +413,7 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> { ], ), .. - }) = self.tcx.hir().get(cmt.hir_id) + }) = self.tcx.hir_node(cmt.hir_id) { self.async_closures.insert(*def_id); } @@ -521,7 +522,7 @@ impl<'tcx> Visitor<'tcx> for FnNeedsMutVisitor<'_, 'tcx> { let Self { cx, used_fn_def_ids } = self; // #11182; do not lint if mutability is required elsewhere - if let Node::Expr(expr) = cx.tcx.hir().get(hir_id) + if let Node::Expr(expr) = cx.tcx.hir_node(hir_id) && let Some(parent) = get_parent_node(cx.tcx, expr.hir_id) && let ty::FnDef(def_id, _) = cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 4f8922aea17..4013cb34561 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -454,7 +454,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { if parent_id == cur_expr.hir_id { break; } - if let Some(Node::Expr(parent_expr)) = cx.tcx.hir().find(parent_id) { + if let Some(Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id) { match &parent_expr.kind { ExprKind::AddrOf(..) => { // `&e` => `e` must be referenced. diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index 352540d70b5..793a3a9545c 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -94,7 +94,6 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { { let mut non_send_fields = Vec::new(); - let hir_map = cx.tcx.hir(); for variant in adt_def.variants() { for field in &variant.fields { if let Some(field_hir_id) = field @@ -104,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { && !is_lint_allowed(cx, NON_SEND_FIELDS_IN_SEND_TY, field_hir_id) && let field_ty = field.ty(cx.tcx, impl_trait_args) && !ty_allowed_in_send(cx, field_ty, send_trait) - && let Node::Field(field_def) = hir_map.get(field_hir_id) + && let Node::Field(field_def) = cx.tcx.hir_node(field_hir_id) { non_send_fields.push(NonSendField { def: field_def, diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs index 8c374d7d6db..2c511ee0bc0 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs @@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals { && last_segment.ident == ident // resolve the path to its defining binding pattern && let Res::Local(binding_id) = cx.qpath_res(&qpath, expr.hir_id) - && let Node::Pat(binding_pat) = cx.tcx.hir().get(binding_id) + && let Node::Pat(binding_pat) = cx.tcx.hir_node(binding_id) // the previous binding has the same mutability && find_binding(binding_pat, ident).is_some_and(|bind| bind.1 == mutability) // the local does not change the effect of assignments to the binding. see #11290 diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 74193e0199f..1316343e0c2 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { Some(trait_ref) => { let mut methods_in_trait: BTreeSet<Symbol> = if let Some(Node::TraitRef(TraitRef { path, .. - })) = cx.tcx.hir().find(trait_ref.hir_ref_id) + })) = cx.tcx.opt_hir_node(trait_ref.hir_ref_id) && let Res::Def(DefKind::Trait, did) = path.res { // FIXME: if diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index 935dd4a3630..98f3235af10 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { if let Some(self_def) = self_ty.ty_adt_def() && let Some(self_local_did) = self_def.did().as_local() && let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did) - && let Some(Node::Item(x)) = cx.tcx.hir().find(self_id) + && let Some(Node::Item(x)) = cx.tcx.opt_hir_node(self_id) && let type_name = x.ident.name.as_str().to_lowercase() && (impl_item.ident.name.as_str() == type_name || impl_item.ident.name.as_str().replace('_', "") == type_name) diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs index 268c0c1b2df..8eab3f5874e 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { // Check for more than one binary operation in the implemented function // Linting when multiple operations are involved can result in false positives && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id - && let hir::Node::ImplItem(impl_item) = cx.tcx.hir().get_by_def_id(parent_fn) + && let hir::Node::ImplItem(impl_item) = cx.tcx.hir_node_by_def_id(parent_fn) && let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind && let body = cx.tcx.hir().body(body_id) && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 8e890b4df88..81efec65343 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -321,7 +321,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { _: Span, def_id: LocalDefId, ) { - let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx.tcx.hir().find_by_def_id( + let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id( cx.tcx .hir() .get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id)) @@ -368,8 +368,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { ImplItemKind::Const(ty, _) => { let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx .tcx - .hir() - .find_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id) + .opt_hir_node_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) } else { diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs b/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs index ed4d87ef8f8..333ea0c82df 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_struct_initialization.rs @@ -82,7 +82,7 @@ impl LateLintPass<'_> for UnnecessaryStruct { fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let Some(hir_id) = path_to_local(expr) - && let Node::Pat(pat) = cx.tcx.hir().get(hir_id) + && let Node::Pat(pat) = cx.tcx.hir_node(hir_id) { matches!(pat.kind, PatKind::Binding(BindingAnnotation::MUT, ..)) } else { diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 2ab24f70ae0..2e0a0f6cb3e 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -281,7 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { } if let Some(id) = path_to_local(recv) - && let Node::Pat(pat) = cx.tcx.hir().get(id) + && let Node::Pat(pat) = cx.tcx.hir_node(id) && let PatKind::Binding(ann, ..) = pat.kind && ann != BindingAnnotation::MUT { diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index 70ca1b206b4..31a81a52497 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -218,7 +218,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) { Res::Local(hir_id) => { let parent_id = cx.tcx.hir().parent_id(hir_id); - if let Some(Node::Local(Local { init: Some(init), .. })) = cx.tcx.hir().find(parent_id) { + if let Some(Node::Local(Local { init: Some(init), .. })) = cx.tcx.hir_node(parent_id) { path_to_matched_type(cx, init) } else { None diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index fba3808261a..b36c4ef91dc 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -74,7 +74,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool { let parent_id = cx.tcx.hir().get_parent_item(hir_id); let second_parent_id = cx.tcx.hir().get_parent_item(parent_id.into()).def_id; - if let Some(Node::Item(item)) = cx.tcx.hir().find_by_def_id(second_parent_id) { + if let Some(Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(second_parent_id) { if let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind { return true; } diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 3bac0626f88..3f68b6d75b5 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -269,7 +269,7 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")), FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, body.value).1), }; - let start_pat = match tcx.hir().get(hir_id) { + let start_pat = match tcx.hir_node(hir_id) { Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => { if vis_span.is_empty() { start_pat diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 35a8a7920a9..727f93c8327 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -531,7 +531,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { kind: ExprKind::Lit(_), span, .. - }) = self.lcx.tcx.hir().get(body_id.hir_id) + }) = self.lcx.tcx.hir_node(body_id.hir_id) && is_direct_expn_of(*span, "cfg").is_some() { return None; diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index fa56e5b0ba2..7562961538e 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -49,7 +49,6 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult #[expect(clippy::disallowed_methods)] cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { docs_link(diag, lint); - diag }); } @@ -90,7 +89,6 @@ pub fn span_lint_and_help<T: LintContext>( diag.help(help.to_string()); } docs_link(diag, lint); - diag }); } @@ -134,7 +132,6 @@ pub fn span_lint_and_note<T: LintContext>( diag.note(note); } docs_link(diag, lint); - diag }); } @@ -152,7 +149,6 @@ where cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); - diag }); } @@ -160,7 +156,6 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s #[expect(clippy::disallowed_methods)] cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { docs_link(diag, lint); - diag }); } @@ -176,7 +171,6 @@ pub fn span_lint_hir_and_then( cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); - diag }); } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index f3b63f1cdcf..70a3c6f82c1 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -176,10 +176,10 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr /// canonical binding `HirId`. pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> { let hir = cx.tcx.hir(); - if let Some(Node::Pat(pat)) = hir.find(hir_id) + if let Some(Node::Pat(pat)) = cx.tcx.opt_hir_node(hir_id) && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..)) && let parent = hir.parent_id(hir_id) - && let Some(Node::Local(local)) = hir.find(parent) + && let Some(Node::Local(local)) = cx.tcx.opt_hir_node(parent) { return local.init; } @@ -563,7 +563,7 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb let hir = tcx.hir(); let root_mod; - let item_kind = match hir.find_by_def_id(local_id) { + let item_kind = match tcx.opt_hir_node_by_def_id(local_id) { Some(Node::Crate(r#mod)) => { root_mod = ItemKind::Mod(r#mod); &root_mod @@ -712,7 +712,7 @@ pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, def_id: LocalDefId) -> let hir_id = cx.tcx.local_def_id_to_hir_id(def_id); let parent_impl = cx.tcx.hir().get_parent_item(hir_id); if parent_impl != hir::CRATE_OWNER_ID - && let hir::Node::Item(item) = cx.tcx.hir().get_by_def_id(parent_impl.def_id) + && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id) && let hir::ItemKind::Impl(impl_) = &item.kind { return impl_.of_trait.as_ref(); @@ -1242,7 +1242,7 @@ pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { /// Gets the name of the item the expression is in, if available. pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> { let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id).def_id; - match cx.tcx.hir().find_by_def_id(parent_id) { + match cx.tcx.opt_hir_node_by_def_id(parent_id) { Some( Node::Item(Item { ident, .. }) | Node::TraitItem(TraitItem { ident, .. }) @@ -1319,7 +1319,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio let map = &cx.tcx.hir(); let enclosing_node = map .get_enclosing_scope(hir_id) - .and_then(|enclosing_id| map.find(enclosing_id)); + .and_then(|enclosing_id| cx.tcx.opt_hir_node(enclosing_id)); enclosing_node.and_then(|node| match node { Node::Block(block) => Some(block), Node::Item(&Item { @@ -2691,7 +2691,7 @@ impl<'tcx> ExprUseNode<'tcx> { if let Some(Node::Expr(Expr { kind: ExprKind::Closure(c), .. - })) = cx.tcx.hir().find(hir_id) + })) = cx.tcx.opt_hir_node(hir_id) { match c.fn_decl.output { FnRetTy::DefaultReturn(_) => None, @@ -2757,7 +2757,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Optio walk_to_expr_usage(cx, e, &mut |parent, child_id| { // LocalTableInContext returns the wrong lifetime, so go use `expr_adjustments` instead. if adjustments.is_empty() - && let Node::Expr(e) = cx.tcx.hir().get(child_id) + && let Node::Expr(e) = cx.tcx.hir_node(child_id) { adjustments = cx.typeck_results().expr_adjustments(e); } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 055671afd14..5d53a4d28f2 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2543,10 +2543,10 @@ impl<'test> TestCx<'test> { rustc.args(&["-Zpolonius"]); } Some(CompareMode::NextSolver) => { - rustc.args(&["-Ztrait-solver=next"]); + rustc.args(&["-Znext-solver"]); } Some(CompareMode::NextSolverCoherence) => { - rustc.args(&["-Ztrait-solver=next-coherence"]); + rustc.args(&["-Znext-solver=coherence"]); } Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => { rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]); diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 504b6bd140e..8390309889d 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -144,7 +144,7 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { // Otherwise it may cause unexpected behaviours and ICEs // (https://github.com/rust-lang/rust/issues/86261). let is_reachable_non_generic = matches!( - tcx.hir().get(tcx.local_def_id_to_hir_id(local_def_id)), + tcx.hir_node_by_def_id(local_def_id), Node::Item(&hir::Item { kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..), .. diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index ef394b16310..e0f59144975 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -512,7 +512,7 @@ pub fn report_msg<'tcx>( } } - handler.emit_diagnostic(&mut err); + handler.emit_diagnostic(err); } impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.rs b/src/tools/miri/tests/fail/extern-type-field-offset.rs new file mode 100644 index 00000000000..139405fc374 --- /dev/null +++ b/src/tools/miri/tests/fail/extern-type-field-offset.rs @@ -0,0 +1,29 @@ +#![feature(extern_types)] + +extern "C" { + type Opaque; +} + +struct Newtype(Opaque); + +struct S { + i: i32, + j: i32, + a: Newtype, +} + +fn main() { + let buf = [0i32; 4]; + + let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) }; + // Projecting to the newtype works, because it is always at offset 0. + let _field = &x.0; + + let x: &S = unsafe { &*(&buf as *const _ as *const S) }; + // Accessing sized fields is perfectly fine, even at non-zero offsets. + let _field = &x.i; + let _field = &x.j; + // This needs to compute the field offset, but we don't know the type's alignment, + // so this panics. + let _field = &x.a; //~ERROR: does not have a known offset +} diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.stderr b/src/tools/miri/tests/fail/extern-type-field-offset.stderr new file mode 100644 index 00000000000..cbbf1b38361 --- /dev/null +++ b/src/tools/miri/tests/fail/extern-type-field-offset.stderr @@ -0,0 +1,14 @@ +error: unsupported operation: `extern type` does not have a known offset + --> $DIR/extern-type-field-offset.rs:LL:CC + | +LL | let _field = &x.a; + | ^^^^ `extern type` does not have a known offset + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = note: BACKTRACE: + = note: inside `main` at $DIR/extern-type-field-offset.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs b/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs new file mode 100644 index 00000000000..bb73c26c18a --- /dev/null +++ b/src/tools/miri/tests/pass/packed-struct-dyn-trait.rs @@ -0,0 +1,21 @@ +// run-pass +use std::ptr::addr_of; + +// When the unsized tail is a `dyn Trait`, its alignments is only dynamically known. This means the +// packed(2) needs to be applied at runtime: the actual alignment of the field is `min(2, +// usual_alignment)`. Here we check that we do this right by comparing size, alignment, and field +// offset before and after unsizing. +fn main() { + #[repr(C, packed(2))] + struct Packed<T: ?Sized>(u8, core::mem::ManuallyDrop<T>); + + let p = Packed(0, core::mem::ManuallyDrop::new(1)); + let p: &Packed<usize> = &p; + let sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) }; + let p: &Packed<dyn Send> = p; + let un_sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let un_sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) }; + assert_eq!(sized, un_sized); + assert_eq!(sized_offset, un_sized_offset); +} diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 0573df9de2f..06f9c4c6243 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -284,10 +284,8 @@ impl ParseSess { // Methods that should be restricted within the parse module. impl ParseSess { pub(super) fn emit_diagnostics(&self, diagnostics: Vec<Diagnostic>) { - for mut diagnostic in diagnostics { - self.parse_sess - .span_diagnostic - .emit_diagnostic(&mut diagnostic); + for diagnostic in diagnostics { + self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic); } } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index b38d5436477..3bfe811b58e 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -211,7 +211,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "crossbeam-epoch", "crossbeam-utils", "crypto-common", - "cstr", "darling", "darling_core", "darling_macro", @@ -255,7 +254,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "icu_provider_macros", "ident_case", "indexmap", - "instant", "intl-memoizer", "intl_pluralrules", "is-terminal", diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 40149f8f1c3..dfa386b49de 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1852; -const ROOT_ENTRY_LIMIT: usize = 866; +const ROOT_ENTRY_LIMIT: usize = 867; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/assembly/x86-stack-probes.rs b/tests/assembly/stack-probes.rs index 64a4efc0e18..6466df3ff7d 100644 --- a/tests/assembly/x86-stack-probes.rs +++ b/tests/assembly/stack-probes.rs @@ -1,10 +1,12 @@ -// revisions: x86_64 i686 +// revisions: x86_64 i686 aarch64 // assembly-output: emit-asm -//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //[x86_64] needs-llvm-components: x86 -//[i686] compile-flags: --target i686-unknown-linux-gnu +//[i686] compile-flags: --target i686-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel //[i686] needs-llvm-components: x86 -// compile-flags: -C llvm-args=-x86-asm-syntax=intel +//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//[aarch64] needs-llvm-components: aarch64 +//[aarch64] min-llvm-version: 18 #![feature(no_core, lang_items)] #![crate_type = "lib"] @@ -28,6 +30,7 @@ pub fn small_stack_probe(x: u8, f: fn(&mut [u8; 8192])) { // CHECK-NOT: __rust_probestack // x86_64: sub rsp, 4096 // i686: sub esp, 4096 + // aarch64: sub sp, sp, #1, lsl #12 f(&mut [x; 8192]); } @@ -37,5 +40,6 @@ pub fn big_stack_probe(x: u8, f: fn(&[u8; 65536])) { // CHECK-NOT: __rust_probestack // x86_64: sub rsp, 4096 // i686: sub esp, 4096 + // aarch64: sub sp, sp, #1, lsl #12 f(&mut [x; 65536]); } diff --git a/tests/codegen/debug-accessibility/crate-enum.rs b/tests/codegen/debug-accessibility/crate-enum.rs new file mode 100644 index 00000000000..eeea18dd815 --- /dev/null +++ b/tests/codegen/debug-accessibility/crate-enum.rs @@ -0,0 +1,26 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for crate-visibility enums. + +mod module { + use std::hint::black_box; + + pub(crate) enum CrateFooEnum { + A, + B(u32), + C { x: u32 }, + } + + // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooEnum"{{.*}}flags: DIFlagProtected{{.*}}) + // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<crate_enum::module::CrateFooEnum>"{{.*}}flags: DIFlagProtected{{.*}}) + pub fn use_everything() { + black_box(CrateFooEnum::A); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/crate-struct.rs b/tests/codegen/debug-accessibility/crate-struct.rs new file mode 100644 index 00000000000..68d126a3478 --- /dev/null +++ b/tests/codegen/debug-accessibility/crate-struct.rs @@ -0,0 +1,23 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for crate-visibility structs. + +mod module { + use std::hint::black_box; + + pub(crate) struct CrateFooStruct { + x: u32, + } + + // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooStruct"{{.*}}flags: DIFlagProtected{{.*}}) + + pub fn use_everything() { + black_box(CrateFooStruct { x: 2 }); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/private-enum.rs b/tests/codegen/debug-accessibility/private-enum.rs new file mode 100644 index 00000000000..7f81026ddec --- /dev/null +++ b/tests/codegen/debug-accessibility/private-enum.rs @@ -0,0 +1,21 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for private enums. + +use std::hint::black_box; + +enum PrivateFooEnum { + A, + B(u32), + C { x: u32 }, +} + +// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooEnum"{{.*}}flags: DIFlagPrivate{{.*}}) +// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<private_enum::PrivateFooEnum>"{{.*}}flags: DIFlagPrivate{{.*}}) + +fn main() { + black_box(PrivateFooEnum::A); +} diff --git a/tests/codegen/debug-accessibility/private-struct.rs b/tests/codegen/debug-accessibility/private-struct.rs new file mode 100644 index 00000000000..43b260f9024 --- /dev/null +++ b/tests/codegen/debug-accessibility/private-struct.rs @@ -0,0 +1,17 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for private structs. + +use std::hint::black_box; + +struct PrivateFooStruct { + x: u32, +} + +// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooStruct"{{.*}}flags: DIFlagPrivate{{.*}}) + +fn main() { + black_box(PrivateFooStruct { x: 1 }); +} diff --git a/tests/codegen/debug-accessibility/public-enum.rs b/tests/codegen/debug-accessibility/public-enum.rs new file mode 100644 index 00000000000..29ae5fd6421 --- /dev/null +++ b/tests/codegen/debug-accessibility/public-enum.rs @@ -0,0 +1,21 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for types and their fields. + +use std::hint::black_box; + +pub enum PublicFooEnum { + A, + B(u32), + C { x: u32 }, +} + +// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooEnum"{{.*}}flags: DIFlagPublic{{.*}}) +// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<public_enum::PublicFooEnum>"{{.*}}flags: DIFlagPublic{{.*}}) + +fn main() { + black_box(PublicFooEnum::A); +} diff --git a/tests/codegen/debug-accessibility/public-struct.rs b/tests/codegen/debug-accessibility/public-struct.rs new file mode 100644 index 00000000000..e7cd9b40d09 --- /dev/null +++ b/tests/codegen/debug-accessibility/public-struct.rs @@ -0,0 +1,17 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for public structs. + +use std::hint::black_box; + +pub struct PublicFooStruct { + x: u32, +} + +// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooStruct"{{.*}}flags: DIFlagPublic{{.*}}) + +fn main() { + black_box(PublicFooStruct { x: 4 }); +} diff --git a/tests/codegen/debug-accessibility/struct-fields.rs b/tests/codegen/debug-accessibility/struct-fields.rs new file mode 100644 index 00000000000..76831bdc6c6 --- /dev/null +++ b/tests/codegen/debug-accessibility/struct-fields.rs @@ -0,0 +1,30 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for struct fields. + +mod module { + use std::hint::black_box; + + struct StructFields { + a: u32, + pub(crate) b: u32, + pub(super) c: u32, + pub d: u32, + } + + // CHECK: [[StructFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "StructFields"{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: [[StructFields]]{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: [[StructFields]]{{.*}}flags: DIFlagPublic{{.*}}) + + pub fn use_everything() { + black_box(StructFields { a: 1, b: 2, c: 3, d: 4 }); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/super-enum.rs b/tests/codegen/debug-accessibility/super-enum.rs new file mode 100644 index 00000000000..9d83fb45bd0 --- /dev/null +++ b/tests/codegen/debug-accessibility/super-enum.rs @@ -0,0 +1,27 @@ +// compile-flags: -C debuginfo=2 +// ignore-tidy-linelength + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for super-visibility enums. + +mod module { + use std::hint::black_box; + + pub(super) enum SuperFooEnum { + A, + B(u32), + C { x: u32 }, + } + + // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooEnum"{{.*}}flags: DIFlagProtected{{.*}}) + // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<super_enum::module::SuperFooEnum>"{{.*}}flags: DIFlagProtected{{.*}}) + + pub fn use_everything() { + black_box(SuperFooEnum::A); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/super-struct.rs b/tests/codegen/debug-accessibility/super-struct.rs new file mode 100644 index 00000000000..481006c3965 --- /dev/null +++ b/tests/codegen/debug-accessibility/super-struct.rs @@ -0,0 +1,23 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for super-visibility structs. + +mod module { + use std::hint::black_box; + + pub(super) struct SuperFooStruct { + x: u32, + } + + // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooStruct"{{.*}}flags: DIFlagProtected{{.*}}) + + pub fn use_everything() { + black_box(SuperFooStruct { x: 3 }); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/debug-accessibility/tuple-fields.rs b/tests/codegen/debug-accessibility/tuple-fields.rs new file mode 100644 index 00000000000..1163ba2c7c3 --- /dev/null +++ b/tests/codegen/debug-accessibility/tuple-fields.rs @@ -0,0 +1,24 @@ +// compile-flags: -C debuginfo=2 + +#![allow(dead_code)] + +// Checks that visibility information is present in the debuginfo for tuple struct fields. + +mod module { + use std::hint::black_box; + + struct TupleFields(u32, pub(crate) u32, pub(super) u32, pub u32); + + // CHECK: [[TupleFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TupleFields"{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: [[TupleFields]]{{.*}}flags: DIFlagPrivate{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__2", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}}) + // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__3", scope: [[TupleFields]]{{.*}}flags: DIFlagPublic{{.*}}) + pub fn use_everything() { + black_box(TupleFields(1, 2, 3, 4)); + } +} + +fn main() { + module::use_everything(); +} diff --git a/tests/codegen/default-hidden-visibility.rs b/tests/codegen/default-hidden-visibility.rs new file mode 100644 index 00000000000..9e5e545f0d9 --- /dev/null +++ b/tests/codegen/default-hidden-visibility.rs @@ -0,0 +1,31 @@ +// Verifies that `Session::default_hidden_visibility` is affected when using the related cmdline +// flag. This is a regression test for https://github.com/rust-lang/compiler-team/issues/656. See +// also https://github.com/rust-lang/rust/issues/73295 and +// https://github.com/rust-lang/rust/issues/37530. + +// revisions:DEFAULT YES NO +//[YES] compile-flags: -Zdefault-hidden-visibility=yes +//[NO] compile-flags: -Zdefault-hidden-visibility=no + +// The test scenario is specifically about visibility of symbols exported out of dynamically linked +// libraries. +#![crate_type = "dylib"] + +// The test scenario needs to use a Rust-public, but non-explicitly-exported symbol +// (e.g. the test doesn't use `#[no_mangle]`, because currently it implies that +// the symbol should be exported; we don't want that - we want to test the *default* +// export setting instead). +#[used] +pub static tested_symbol: [u8; 6] = *b"foobar"; + +// Exact LLVM IR differs depending on the target triple (e.g. `hidden constant` +// vs `internal constant` vs `constant`). Because of this, we only apply the +// specific test expectations below to one specific target triple. If needed, +// additional targets can be covered by adding copies of this test file with +// a different `only-X` directive. +// +// only-x86_64-unknown-linux-gnu + +// DEFAULT: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant +// YES: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = hidden constant +// NO: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs index 7b1fb320894..e573b7d21bd 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs @@ -21,7 +21,7 @@ extern "platform-intrinsic" { #[no_mangle] pub unsafe fn load_f32x2(mask: Vec2<i32>, pointer: *const f32, values: Vec2<f32>) -> Vec2<f32> { - // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x float> {{.*}}) + // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> {{.*}}, <2 x float> {{.*}}) simd_masked_load(mask, pointer, values) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs index d8a37020f23..91656622216 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs @@ -20,7 +20,7 @@ extern "platform-intrinsic" { // CHECK-LABEL: @store_f32x2 #[no_mangle] pub unsafe fn store_f32x2(mask: Vec2<i32>, pointer: *mut f32, values: Vec2<f32>) { - // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}) + // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> {{.*}}) simd_masked_store(mask, pointer, values) } diff --git a/tests/codegen/stack-probes-inline.rs b/tests/codegen/stack-probes-inline.rs index 058c363969f..34027e91850 100644 --- a/tests/codegen/stack-probes-inline.rs +++ b/tests/codegen/stack-probes-inline.rs @@ -2,7 +2,9 @@ // or `StackProbeType::InlineOrCall` when running on newer LLVM. // compile-flags: -C no-prepopulate-passes -// revisions: powerpc powerpc64 powerpc64le s390x i686 x86_64 +// revisions: aarch64 powerpc powerpc64 powerpc64le s390x i686 x86_64 +//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//[aarch64] needs-llvm-components: aarch64 //[powerpc] compile-flags: --target powerpc-unknown-linux-gnu //[powerpc] needs-llvm-components: powerpc //[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index e4354a1af87..6bdcca40ed6 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -1,20 +1,20 @@ Function name: async::c -Raw bytes (9): 0x[01, 01, 00, 01, 01, 05, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 5, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 25) Function name: async::c::{closure#0} -Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 05, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02] +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 07, 19, 01, 0e, 05, 02, 09, 00, 0a, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 5, 25) to (start + 1, 14) +- Code(Counter(0)) at (prev + 7, 25) to (start + 1, 14) - Code(Counter(1)) at (prev + 2, 9) to (start + 0, 10) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c0 - c1) @@ -22,136 +22,84 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: async::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 20) Function name: async::d::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 13, 20) to (start + 0, 25) +- Code(Counter(0)) at (prev + 15, 20) to (start + 0, 25) Function name: async::e (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 15, 1) to (start + 0, 20) +- Code(Zero) at (prev + 17, 1) to (start + 0, 20) Function name: async::e::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 15, 20) to (start + 0, 25) - -Function name: async::executor::block_on::<core::pin::Pin<&mut async::i::{closure#0}>> -Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 6e, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 3 -- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 110, 5) to (start + 10, 54) -- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) - = ((c0 + c1) - c1) -- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) - = (c0 + c1) -- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) - = ((c0 + c1) - c1) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) - = ((c0 + c1) - c1) - -Function name: async::executor::block_on::VTABLE::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 72, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 114, 17) to (start + 0, 49) - -Function name: async::executor::block_on::VTABLE::{closure#1} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 73, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 115, 17) to (start + 0, 49) - -Function name: async::executor::block_on::VTABLE::{closure#2} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 74, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 116, 17) to (start + 0, 49) - -Function name: async::executor::block_on::VTABLE::{closure#3} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 75, 11, 00, 13] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 117, 17) to (start + 0, 19) +- Code(Zero) at (prev + 17, 20) to (start + 0, 25) Function name: async::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 00, 14] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 14] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 20) +- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 20) Function name: async::f::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 14, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 14, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 20) to (start + 0, 25) +- Code(Counter(0)) at (prev + 19, 20) to (start + 0, 25) Function name: async::foo (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 01, 00, 1e] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 01, 00, 1e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 19, 1) to (start + 0, 30) +- Code(Zero) at (prev + 21, 1) to (start + 0, 30) Function name: async::foo::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 1e, 00, 2d] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 15, 1e, 00, 2d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 19, 30) to (start + 0, 45) +- Code(Zero) at (prev + 21, 30) to (start + 0, 45) Function name: async::g -Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 23) Function name: async::g::{closure#0} (unused) -Raw bytes (69): 0x[01, 01, 00, 0d, 00, 15, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (69): 0x[01, 01, 00, 0d, 00, 17, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 13 -- Code(Zero) at (prev + 21, 23) to (start + 1, 12) +- Code(Zero) at (prev + 23, 23) to (start + 1, 12) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 17) - Code(Zero) at (prev + 0, 18) to (start + 0, 23) @@ -166,20 +114,20 @@ Number of file 0 mappings: 13 - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Function name: async::h -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 00, 16] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1f, 01, 00, 16] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 29, 1) to (start + 0, 22) +- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 22) Function name: async::h::{closure#0} (unused) -Raw bytes (44): 0x[01, 01, 00, 08, 00, 1d, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (44): 0x[01, 01, 00, 08, 00, 1f, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 8 -- Code(Zero) at (prev + 29, 22) to (start + 3, 12) +- Code(Zero) at (prev + 31, 22) to (start + 3, 12) - Code(Zero) at (prev + 4, 9) to (start + 0, 10) - Code(Zero) at (prev + 0, 14) to (start + 0, 19) - Code(Zero) at (prev + 0, 20) to (start + 0, 25) @@ -189,22 +137,22 @@ Number of file 0 mappings: 8 - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Function name: async::i -Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 01, 00, 13] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 28, 01, 00, 13] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 38, 1) to (start + 0, 19) +- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 19) Function name: async::i::{closure#0} -Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 28, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(8) - expression 1 operands: lhs = Counter(6), rhs = Counter(7) Number of file 0 mappings: 14 -- Code(Counter(0)) at (prev + 38, 19) to (start + 4, 12) +- Code(Counter(0)) at (prev + 40, 19) to (start + 4, 12) - Code(Counter(3)) at (prev + 5, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18) - Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24) @@ -221,14 +169,14 @@ Number of file 0 mappings: 14 = ((c6 + c7) + c8) Function name: async::j -Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 33, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 49, 1) to (start + 19, 12) +- Code(Counter(0)) at (prev + 51, 1) to (start + 19, 12) - Code(Counter(1)) at (prev + 20, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27) - Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39) @@ -240,14 +188,14 @@ Number of file 0 mappings: 9 = ((c1 + c2) + c3) Function name: async::j::c -Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 33, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06] +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 35, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 07, 02, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 51, 5) to (start + 1, 18) +- Code(Counter(0)) at (prev + 53, 5) to (start + 1, 18) - Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14) - Code(Expression(0, Sub)) at (prev + 10, 13) to (start + 0, 14) = (c0 - c1) @@ -255,35 +203,35 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: async::j::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 42, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 44, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 66, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 68, 5) to (start + 0, 23) Function name: async::j::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 43, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 45, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 67, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 69, 5) to (start + 0, 23) Function name: async::k (unused) -Raw bytes (29): 0x[01, 01, 00, 05, 00, 4b, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 4d, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 5 -- Code(Zero) at (prev + 75, 1) to (start + 1, 12) +- Code(Zero) at (prev + 77, 1) to (start + 1, 12) - Code(Zero) at (prev + 2, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Function name: async::l -Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 53, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] +Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 55, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 @@ -292,7 +240,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Expression(3, Add), rhs = Expression(0, Sub) - expression 3 operands: lhs = Counter(2), rhs = Counter(1) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 12) +- Code(Counter(0)) at (prev + 85, 1) to (start + 1, 12) - Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16) = (c0 - (c1 + c2)) - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16) @@ -301,26 +249,26 @@ Number of file 0 mappings: 5 = ((c2 + c1) + (c0 - (c1 + c2))) Function name: async::m -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 91, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 93, 1) to (start + 0, 25) Function name: async::m::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 5b, 19, 00, 22] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 5d, 19, 00, 22] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 91, 25) to (start + 0, 34) +- Code(Zero) at (prev + 93, 25) to (start + 0, 34) Function name: async::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 08, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 5f, 01, 08, 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 + 93, 1) to (start + 8, 2) +- Code(Counter(0)) at (prev + 95, 1) to (start + 8, 2) diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage index 07bc16c2d92..015e03d5165 100644 --- a/tests/coverage/async.coverage +++ b/tests/coverage/async.coverage @@ -1,6 +1,8 @@ + LL| |#![feature(coverage_attribute)] + LL| |#![feature(noop_waker)] LL| |#![allow(unused_assignments, dead_code)] - LL| | - LL| |// compile-flags: --edition=2018 -C opt-level=1 + LL| |// edition: 2018 + LL| |// compile-flags: -Copt-level=1 LL| | LL| 1|async fn c(x: u8) -> u8 { LL| 1| if x == 8 { @@ -108,32 +110,21 @@ LL| 1|} LL| | LL| |mod executor { - LL| | use core::{ - LL| | future::Future, - LL| | pin::Pin, - LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - LL| | }; - LL| | - LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { - LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - LL| 1| use std::hint::unreachable_unchecked; - LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - LL| 1| |_| unsafe { unreachable_unchecked() }, // clone - ^0 - LL| 1| |_| unsafe { unreachable_unchecked() }, // wake - ^0 - LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - ^0 - LL| 1| |_| (), - LL| 1| ); - LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - LL| 1| let mut context = Context::from_waker(&waker); + LL| | use core::future::Future; + LL| | use core::pin::pin; + LL| | use core::task::{Context, Poll, Waker}; + LL| | + LL| | #[coverage(off)] + LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { + LL| | let mut future = pin!(future); + LL| | let waker = Waker::noop(); + LL| | let mut context = Context::from_waker(&waker); LL| | LL| | loop { - LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - LL| 1| break val; - LL| 0| } + LL| | if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + LL| | break val; + LL| | } LL| | } - LL| 1| } + LL| | } LL| |} diff --git a/tests/coverage/async.rs b/tests/coverage/async.rs index efd9e62d64e..abc9e5f7f64 100644 --- a/tests/coverage/async.rs +++ b/tests/coverage/async.rs @@ -1,6 +1,8 @@ +#![feature(coverage_attribute)] +#![feature(noop_waker)] #![allow(unused_assignments, dead_code)] - -// compile-flags: --edition=2018 -C opt-level=1 +// edition: 2018 +// compile-flags: -Copt-level=1 async fn c(x: u8) -> u8 { if x == 8 { @@ -101,22 +103,14 @@ fn main() { } mod executor { - use core::{ - future::Future, - pin::Pin, - task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - }; + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll, Waker}; + #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - use std::hint::unreachable_unchecked; - static VTABLE: RawWakerVTable = RawWakerVTable::new( - |_| unsafe { unreachable_unchecked() }, // clone - |_| unsafe { unreachable_unchecked() }, // wake - |_| unsafe { unreachable_unchecked() }, // wake_by_ref - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut future = pin!(future); + let waker = Waker::noop(); let mut context = Context::from_waker(&waker); loop { diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map index 23f26ee4e5f..b120e28c464 100644 --- a/tests/coverage/async2.cov-map +++ b/tests/coverage/async2.cov-map @@ -1,20 +1,20 @@ Function name: async2::async_func -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 0d, 01, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 23) +- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 23) Function name: async2::async_func::{closure#0} -Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 0b, 17, 03, 09, 05, 03, 0a, 02, 06, 02, 02, 06, 00, 07, 07, 01, 01, 00, 02] +Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 0d, 17, 03, 09, 05, 03, 0a, 02, 06, 02, 02, 06, 00, 07, 07, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 11, 23) to (start + 3, 9) +- Code(Counter(0)) at (prev + 13, 23) to (start + 3, 9) - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) - Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7) = (c0 - c1) @@ -22,109 +22,37 @@ Number of file 0 mappings: 4 = (c1 + (c0 - c1)) Function name: async2::async_func_just_println -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 24] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 24] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 36) +- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 36) Function name: async2::async_func_just_println::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 24, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 24, 02, 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 + 19, 36) to (start + 2, 2) - -Function name: async2::executor::block_on::<async2::async_func::{closure#0}> -Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 3 -- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54) -- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) - = ((c0 + c1) - c1) -- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) - = (c0 + c1) -- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) - = ((c0 + c1) - c1) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) - = ((c0 + c1) - c1) - -Function name: async2::executor::block_on::<async2::async_func_just_println::{closure#0}> -Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 3 -- expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 6 -- Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54) -- Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35) - = ((c0 + c1) - c1) -- Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73) - = (c0 + c1) -- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26) - = ((c0 + c1) - c1) -- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6) - = ((c0 + c1) - c1) - -Function name: async2::executor::block_on::VTABLE::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2b, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 43, 17) to (start + 0, 49) - -Function name: async2::executor::block_on::VTABLE::{closure#1} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2c, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 44, 17) to (start + 0, 49) - -Function name: async2::executor::block_on::VTABLE::{closure#2} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2d, 11, 00, 31] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 45, 17) to (start + 0, 49) - -Function name: async2::executor::block_on::VTABLE::{closure#3} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 2e, 11, 00, 13] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 46, 17) to (start + 0, 19) +- Code(Counter(0)) at (prev + 21, 36) to (start + 2, 2) Function name: async2::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 17, 01, 07, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 19, 01, 07, 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 + 23, 1) to (start + 7, 2) +- Code(Counter(0)) at (prev + 25, 1) to (start + 7, 2) Function name: async2::non_async_func -Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 03, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02] +Raw bytes (26): 0x[01, 01, 01, 05, 00, 04, 01, 05, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 03, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(1), rhs = Zero Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 3, 1) to (start + 3, 9) +- Code(Counter(0)) at (prev + 5, 1) to (start + 3, 9) - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6) - Code(Zero) at (prev + 2, 6) to (start + 0, 7) - Code(Expression(0, Add)) at (prev + 1, 1) to (start + 0, 2) diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage index fcb0a3aed64..acd83de9493 100644 --- a/tests/coverage/async2.coverage +++ b/tests/coverage/async2.coverage @@ -1,4 +1,6 @@ - LL| |// compile-flags: --edition=2018 + LL| |#![feature(coverage_attribute)] + LL| |#![feature(noop_waker)] + LL| |// edition: 2018 LL| | LL| 1|fn non_async_func() { LL| 1| println!("non_async_func was covered"); @@ -32,73 +34,21 @@ LL| 1|} LL| | LL| |mod executor { - LL| | use core::{ - LL| | future::Future, - LL| | pin::Pin, - LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - LL| | }; + LL| | use core::future::Future; + LL| | use core::pin::pin; + LL| | use core::task::{Context, Poll, Waker}; LL| | - LL| 2| pub fn block_on<F: Future>(mut future: F) -> F::Output { - LL| 2| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - LL| 2| use std::hint::unreachable_unchecked; - LL| 2| static VTABLE: RawWakerVTable = RawWakerVTable::new( - LL| 2| |_| unsafe { unreachable_unchecked() }, // clone - ^0 - LL| 2| |_| unsafe { unreachable_unchecked() }, // wake - ^0 - LL| 2| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - ^0 - LL| 2| |_| (), - LL| 2| ); - LL| 2| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - LL| 2| let mut context = Context::from_waker(&waker); + LL| | #[coverage(off)] + LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { + LL| | let mut future = pin!(future); + LL| | let waker = Waker::noop(); + LL| | let mut context = Context::from_waker(&waker); LL| | LL| | loop { - LL| 2| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - LL| 2| break val; - LL| 0| } + LL| | if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + LL| | break val; + LL| | } LL| | } - LL| 2| } - ------------------ - | async2::executor::block_on::<async2::async_func::{closure#0}>: - | LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { - | LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - | LL| 1| use std::hint::unreachable_unchecked; - | LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - | LL| 1| |_| unsafe { unreachable_unchecked() }, // clone - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - | LL| 1| |_| (), - | LL| 1| ); - | LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - | LL| 1| let mut context = Context::from_waker(&waker); - | LL| | - | LL| | loop { - | LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - | LL| 1| break val; - | LL| 0| } - | LL| | } - | LL| 1| } - ------------------ - | async2::executor::block_on::<async2::async_func_just_println::{closure#0}>: - | LL| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { - | LL| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; - | LL| 1| use std::hint::unreachable_unchecked; - | LL| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( - | LL| 1| |_| unsafe { unreachable_unchecked() }, // clone - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake - | LL| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref - | LL| 1| |_| (), - | LL| 1| ); - | LL| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; - | LL| 1| let mut context = Context::from_waker(&waker); - | LL| | - | LL| | loop { - | LL| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { - | LL| 1| break val; - | LL| 0| } - | LL| | } - | LL| 1| } - ------------------ + LL| | } LL| |} diff --git a/tests/coverage/async2.rs b/tests/coverage/async2.rs index 2884ff297af..393573f7dc9 100644 --- a/tests/coverage/async2.rs +++ b/tests/coverage/async2.rs @@ -1,4 +1,6 @@ -// compile-flags: --edition=2018 +#![feature(coverage_attribute)] +#![feature(noop_waker)] +// edition: 2018 fn non_async_func() { println!("non_async_func was covered"); @@ -30,22 +32,14 @@ fn main() { } mod executor { - use core::{ - future::Future, - pin::Pin, - task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - }; + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll, Waker}; + #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - use std::hint::unreachable_unchecked; - static VTABLE: RawWakerVTable = RawWakerVTable::new( - |_| unsafe { unreachable_unchecked() }, // clone - |_| unsafe { unreachable_unchecked() }, // wake - |_| unsafe { unreachable_unchecked() }, // wake_by_ref - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut future = pin!(future); + let waker = Waker::noop(); let mut context = Context::from_waker(&waker); loop { diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index 7f8666948d9..14b1525ca0e 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -1,28 +1,28 @@ Function name: closure_macro_async::load_configuration_files -Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 02, 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 + 29, 1) to (start + 2, 2) +- Code(Counter(0)) at (prev + 30, 1) to (start + 2, 2) Function name: closure_macro_async::test -Raw bytes (9): 0x[01, 01, 00, 01, 01, 21, 01, 00, 2b] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 22, 01, 00, 2b] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 43) +- Code(Counter(0)) at (prev + 34, 1) to (start + 0, 43) Function name: closure_macro_async::test::{closure#0} -Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 21, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02] +Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 22, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) - expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub) Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 33, 43) to (start + 1, 33) +- Code(Counter(0)) at (prev + 34, 43) to (start + 1, 33) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) @@ -35,10 +35,10 @@ Number of file 0 mappings: 7 = (c1 + (c0 - c1)) Function name: closure_macro_async::test::{closure#0}::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 23, 12, 00, 54] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 24, 12, 00, 54] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 35, 18) to (start + 0, 84) +- Code(Counter(0)) at (prev + 36, 18) to (start + 0, 84) diff --git a/tests/coverage/closure_macro_async.coverage b/tests/coverage/closure_macro_async.coverage index 74247f1bc6f..2c9bd4ac97a 100644 --- a/tests/coverage/closure_macro_async.coverage +++ b/tests/coverage/closure_macro_async.coverage @@ -1,5 +1,6 @@ - LL| |// compile-flags: --edition=2018 LL| |#![feature(coverage_attribute)] + LL| |#![feature(noop_waker)] + LL| |// edition: 2018 LL| | LL| |macro_rules! bail { LL| | ($msg:literal $(,)?) => { @@ -46,27 +47,14 @@ LL| |} LL| | LL| |mod executor { - LL| | use core::{ - LL| | future::Future, - LL| | pin::Pin, - LL| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - LL| | }; + LL| | use core::future::Future; + LL| | use core::pin::pin; + LL| | use core::task::{Context, Poll, Waker}; LL| | LL| | #[coverage(off)] LL| | pub fn block_on<F: Future>(mut future: F) -> F::Output { - LL| | let mut future = unsafe { Pin::new_unchecked(&mut future) }; - LL| | use std::hint::unreachable_unchecked; - LL| | static VTABLE: RawWakerVTable = RawWakerVTable::new( - LL| | #[coverage(off)] - LL| | |_| unsafe { unreachable_unchecked() }, // clone - LL| | #[coverage(off)] - LL| | |_| unsafe { unreachable_unchecked() }, // wake - LL| | #[coverage(off)] - LL| | |_| unsafe { unreachable_unchecked() }, // wake_by_ref - LL| | #[coverage(off)] - LL| | |_| (), - LL| | ); - LL| | let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + LL| | let mut future = pin!(future); + LL| | let waker = Waker::noop(); LL| | let mut context = Context::from_waker(&waker); LL| | LL| | loop { diff --git a/tests/coverage/closure_macro_async.rs b/tests/coverage/closure_macro_async.rs index b4275599e59..a7f0cabb4c2 100644 --- a/tests/coverage/closure_macro_async.rs +++ b/tests/coverage/closure_macro_async.rs @@ -1,5 +1,6 @@ -// compile-flags: --edition=2018 #![feature(coverage_attribute)] +#![feature(noop_waker)] +// edition: 2018 macro_rules! bail { ($msg:literal $(,)?) => { @@ -45,27 +46,14 @@ fn main() { } mod executor { - use core::{ - future::Future, - pin::Pin, - task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, - }; + use core::future::Future; + use core::pin::pin; + use core::task::{Context, Poll, Waker}; #[coverage(off)] pub fn block_on<F: Future>(mut future: F) -> F::Output { - let mut future = unsafe { Pin::new_unchecked(&mut future) }; - use std::hint::unreachable_unchecked; - static VTABLE: RawWakerVTable = RawWakerVTable::new( - #[coverage(off)] - |_| unsafe { unreachable_unchecked() }, // clone - #[coverage(off)] - |_| unsafe { unreachable_unchecked() }, // wake - #[coverage(off)] - |_| unsafe { unreachable_unchecked() }, // wake_by_ref - #[coverage(off)] - |_| (), - ); - let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut future = pin!(future); + let waker = Waker::noop(); let mut context = Context::from_waker(&waker); loop { diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml new file mode 100644 index 00000000000..53f96ff086e --- /dev/null +++ b/tests/rustdoc-gui/globals.goml @@ -0,0 +1,24 @@ +// Make sure search stores its data in `window` +// It needs to use a global to avoid racing on search-index.js and search.js +// https://github.com/rust-lang/rust/pull/118961 + +// URL query +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa'%3Bda'%3Bds" +wait-for: "#search-tabs" +assert-window-property-false: {"searchIndex": null} +assert-window-property: {"srcIndex": null} + +// Form input +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +write: (".search-input", "Foo") +press-key: 'Enter' +wait-for: "#search-tabs" +assert-window-property-false: {"searchIndex": null} +assert-window-property: {"srcIndex": null} + +// source sidebar +go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" +click: "#src-sidebar-toggle" +wait-for: "#src-sidebar details" +assert-window-property-false: {"srcIndex": null} +assert-window-property: {"searchIndex": null} diff --git a/tests/rustdoc-gui/hide-mobile-topbar.goml b/tests/rustdoc-gui/hide-mobile-topbar.goml new file mode 100644 index 00000000000..46eb8acfe8c --- /dev/null +++ b/tests/rustdoc-gui/hide-mobile-topbar.goml @@ -0,0 +1,20 @@ +// Checks sidebar resizing stays synced with the setting +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (400, 600) + +// Verify that the "hide" option is unchecked +click: "#settings-menu" +wait-for: "#settings" +assert-css: ("#settings", {"display": "block"}) +assert-property: ("#hide-sidebar", {"checked": "false"}) +assert-css: (".mobile-topbar", {"display": "flex"}) + +// Toggle it +click: "#hide-sidebar" +assert-property: ("#hide-sidebar", {"checked": "true"}) +assert-css: (".mobile-topbar", {"display": "none"}) + +// Toggle it again +click: "#hide-sidebar" +assert-property: ("#hide-sidebar", {"checked": "false"}) +assert-css: (".mobile-topbar", {"display": "flex"}) diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml index 0789d785f58..d88ebfb40d7 100644 --- a/tests/rustdoc-gui/links-color.goml +++ b/tests/rustdoc-gui/links-color.goml @@ -26,12 +26,12 @@ define-function: ( assert-css: (".item-table .keyword", {"color": |keyword|}, ALL) // Checking sidebar elements. assert-css: ( - ".sidebar-elems a:not(.current)", + ".sidebar-elems li:not(.current) a", {"color": |sidebar|, "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"}, ALL, ) assert-css: ( - ".sidebar-elems a.current", + ".sidebar-elems li.current a", { "color": |sidebar_current|, "background-color": |sidebar_current_background|, diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml index 079d582a567..774fbcac1e2 100644 --- a/tests/rustdoc-gui/sidebar-links-color.goml +++ b/tests/rustdoc-gui/sidebar-links-color.goml @@ -17,10 +17,10 @@ define-function: ( reload: // Struct assert-css: ( - ".sidebar .block.struct a:not(.current)", + ".sidebar .block.struct li:not(.current) a", {"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"}, ) - move-cursor-to: ".sidebar .block.struct a:not(.current)" + move-cursor-to: ".sidebar .block.struct li:not(.current) a" assert-css: ( ".sidebar .block.struct a:hover", {"color": |struct_hover|, "background-color": |struct_hover_background|}, diff --git a/tests/rustdoc-gui/sidebar-resize-setting.goml b/tests/rustdoc-gui/sidebar-resize-setting.goml new file mode 100644 index 00000000000..2fdb2faa864 --- /dev/null +++ b/tests/rustdoc-gui/sidebar-resize-setting.goml @@ -0,0 +1,23 @@ +// Checks sidebar resizing stays synced with the setting +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +assert-property: (".sidebar", {"clientWidth": "200"}) +show-text: true + +// Verify that the "hide" option is unchecked +click: "#settings-menu" +wait-for: "#settings" +assert-css: ("#settings", {"display": "block"}) +assert-property: ("#hide-sidebar", {"checked": "false"}) +press-key: "Escape" +wait-for-css: ("#settings", {"display": "none"}) + +drag-and-drop: ((205, 100), (5, 100)) +assert-css: (".sidebar", {"display": "none"}) + +// Verify that the "hide" option is checked +focus: "#settings-menu a" +press-key: "Enter" +wait-for-css: ("#settings", {"display": "block"}) +assert-property: ("#hide-sidebar", {"checked": "true"}) +click: "#hide-sidebar" +wait-for-css: (".sidebar", {"display": "block"}) diff --git a/tests/rustdoc-gui/sidebar-resize-window.goml b/tests/rustdoc-gui/sidebar-resize-window.goml new file mode 100644 index 00000000000..fb6baafda71 --- /dev/null +++ b/tests/rustdoc-gui/sidebar-resize-window.goml @@ -0,0 +1,37 @@ +// Checks sidebar resizing +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 200}, [NEAR]) + +// resize past maximum (don't grow past 500) +drag-and-drop: ((205, 100), (600, 100)) +wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR]) + +// make the window small enough that the sidebar has to shrink +set-window-size: (750, 600) +wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR]) + +// grow the window again to make the sidebar bigger +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR]) + +// make the window small enough that the sidebar has to shrink +set-window-size: (750, 600) +wait-for-property: (".sidebar", {"clientWidth": 350}, [NEAR]) +assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"} +set-window-size: (400, 600) +wait-for-css: (".sidebar", {"display": "block", "left": "-1000px"}) +assert-local-storage: {"rustdoc-desktop-sidebar-width": "350"} + +// grow the window again to make the sidebar bigger +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 500}, [NEAR]) + +// shrink back down again, then reload the page +// the "desired size" is a bit of remembered implicit state, +// and rustdoc tries to minimize things like this +set-window-size: (800, 600) +wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR]) +reload: +set-window-size: (1280, 600) +wait-for-property: (".sidebar", {"clientWidth": 400}, [NEAR]) diff --git a/tests/rustdoc-gui/sidebar-resize.goml b/tests/rustdoc-gui/sidebar-resize.goml new file mode 100644 index 00000000000..543d5d390c7 --- /dev/null +++ b/tests/rustdoc-gui/sidebar-resize.goml @@ -0,0 +1,28 @@ +// Checks sidebar resizing +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +assert-property: (".sidebar", {"clientWidth": "200"}) +show-text: true +// normal resizing +drag-and-drop: ((205, 100), (185, 100)) +assert-property: (".sidebar", {"clientWidth": "182"}) +// resize past maximum (don't grow past 500) +drag-and-drop: ((185, 100), (600, 100)) +assert-property: (".sidebar", {"clientWidth": "500"}) +// resize past minimum (hide sidebar) +drag-and-drop: ((501, 100), (5, 100)) +assert-property: (".sidebar", {"clientWidth": "0"}) +assert-css: (".sidebar", {"display": "none"}) +assert-local-storage: {"rustdoc-hide-sidebar": "true"} +set-local-storage: {"rustdoc-hide-sidebar": "false"} + +// Now same thing, but for source code +go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" +assert-property: (".sidebar", {"clientWidth": "49"}) +drag-and-drop: ((52, 100), (185, 100)) +assert-property: (".sidebar", {"clientWidth": "181"}) +drag-and-drop: ((185, 100), (600, 100)) +assert-property: (".sidebar", {"clientWidth": "499"}) +drag-and-drop: ((500, 100), (5, 100)) +// instead of hiding the sidebar entirely, this +// will switch to the toggle mode +assert-property: (".sidebar", {"clientWidth": "49"}) diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml index 0d72e670cf4..9fc1409e86f 100644 --- a/tests/rustdoc-gui/sidebar-source-code.goml +++ b/tests/rustdoc-gui/sidebar-source-code.goml @@ -48,6 +48,7 @@ call-function: ( // Next, desktop mode layout. set-window-size: (1100, 800) +wait-for: "#src-sidebar-toggle" // We check that the sidebar isn't expanded and has the expected width. assert-css: ("nav.sidebar", {"width": "50px"}) // We now click on the button to expand the sidebar. @@ -58,7 +59,7 @@ assert-css: (".src-sidebar-expanded nav.sidebar a", {"font-size": "14px"}) // We collapse the sidebar. click: (10, 10) // We ensure that the class has been removed. -wait-for: "html:not(.expanded)" +wait-for: "html:not(.src-sidebar-expanded)" assert: "nav.sidebar" // Checking that only the path to the current file is "open". diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index eff66d803d2..82b4f2e9429 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -57,7 +57,7 @@ assert-count: (".sidebar h2", 1) assert-text: ("#all-types", "All Items") assert-css: ("#all-types", {"color": "#356da4"}) // We check that we have the crates list and that the "current" on is "test_docs". -assert-text: (".sidebar-elems ul.crate > li > a.current", "test_docs") +assert-text: (".sidebar-elems ul.crate > li.current > a", "test_docs") // And we're also supposed to have the list of items in the current module. assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Re-exports") assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Modules") @@ -98,7 +98,7 @@ assert-property: (".sidebar", {"clientWidth": "200"}) assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2") assert-count: (".sidebar .location", 0) // We check that we have the crates list and that the "current" on is now "lib2". -assert-text: (".sidebar-elems ul.crate > li > a.current", "lib2") +assert-text: (".sidebar-elems ul.crate > li.current > a", "lib2") // We now go to the "foobar" function page. assert-text: (".sidebar-elems > section ul.block > li:nth-child(1)", "Modules") assert-text: (".sidebar-elems > section ul.block > li:nth-child(2)", "Structs") diff --git a/tests/rustdoc-gui/src/theme_css/custom-theme.css b/tests/rustdoc-gui/src/theme_css/custom-theme.css index 260ef87f6ea..49227d9ea11 100644 --- a/tests/rustdoc-gui/src/theme_css/custom-theme.css +++ b/tests/rustdoc-gui/src/theme_css/custom-theme.css @@ -96,4 +96,6 @@ --scrape-example-help-hover-color: #000; --scrape-example-code-wrapper-background-start: rgba(255, 255, 255, 1); --scrape-example-code-wrapper-background-end: rgba(255, 255, 255, 0); + --sidebar-resizer-hover: hsl(207, 90%, 66%); + --sidebar-resizer-active: hsl(207, 90%, 54%); } diff --git a/tests/rustdoc-js/assoc-type.js b/tests/rustdoc-js/assoc-type.js index 47776656e32..eec4e7a8258 100644 --- a/tests/rustdoc-js/assoc-type.js +++ b/tests/rustdoc-js/assoc-type.js @@ -7,16 +7,16 @@ const EXPECTED = [ 'query': 'iterator<something> -> u32', 'correction': null, 'others': [ - { 'path': 'assoc_type', 'name': 'my_fn' }, { 'path': 'assoc_type::my', 'name': 'other_fn' }, + { 'path': 'assoc_type', 'name': 'my_fn' }, ], }, { 'query': 'iterator<something>', 'correction': null, 'in_args': [ - { 'path': 'assoc_type', 'name': 'my_fn' }, { 'path': 'assoc_type::my', 'name': 'other_fn' }, + { 'path': 'assoc_type', 'name': 'my_fn' }, ], }, { @@ -26,8 +26,8 @@ const EXPECTED = [ { 'path': 'assoc_type', 'name': 'Something' }, ], 'in_args': [ - { 'path': 'assoc_type', 'name': 'my_fn' }, { 'path': 'assoc_type::my', 'name': 'other_fn' }, + { 'path': 'assoc_type', 'name': 'my_fn' }, ], }, // if I write an explicit binding, only it shows up diff --git a/tests/rustdoc-js/big-result.js b/tests/rustdoc-js/big-result.js new file mode 100644 index 00000000000..07961d196f4 --- /dev/null +++ b/tests/rustdoc-js/big-result.js @@ -0,0 +1,39 @@ +// exact-check + +const EXPECTED = [ + { + 'query': 'First', + 'in_args': (function() { + // Generate the list of 200 items that should match. + const results = []; + function generate(lx, ly) { + for (const x of lx) { + for (const y of ly) { + results.push({ + 'path': `big_result::${y}`, + 'name': x, + }); + } + } + } + // Fewest parameters that still match go on top. + generate( + ['u', 'v', 'w', 'x', 'y'], + ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] + ); + generate( + ['p', 'q', 'r', 's', 't'], + ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] + ); + generate( + ['k', 'l', 'm', 'n', 'o'], + ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] + ); + generate( + ['f', 'g', 'h', 'i', 'j'], + ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] + ); + return results; + })(), + }, +]; diff --git a/tests/rustdoc-js/big-result.rs b/tests/rustdoc-js/big-result.rs new file mode 100644 index 00000000000..4dfecd6aaad --- /dev/null +++ b/tests/rustdoc-js/big-result.rs @@ -0,0 +1,61 @@ +#![feature(concat_idents)] +#![allow(nonstandard_style)] +/// Generate 250 items that all match the query, starting with the longest. +/// Those long items should be dropped from the result set, and the short ones +/// should be shown instead. +macro_rules! generate { + ([$($x:ident),+], $y:tt, $z:tt) => { + $( + generate!(@ $x, $y, $z); + )+ + }; + (@ $x:ident , [$($y:ident),+], $z:tt) => { + pub struct $x; + $( + generate!(@@ $x, $y, $z); + )+ + }; + (@@ $x:ident , $y:ident, [$($z:ident: $zt:ident),+]) => { + impl $y { + pub fn $x($($z: $zt,)+) {} + } + } +} + +pub struct First; +pub struct Second; +pub struct Third; +pub struct Fourth; +pub struct Fifth; + +generate!( + [a, b, c, d, e], + [a, b, c, d, e, f, g, h, i, j], + [a: First, b: Second, c: Third, d: Fourth, e: Fifth] +); + +generate!( + [f, g, h, i, j], + [a, b, c, d, e, f, g, h, i, j], + [a: First, b: Second, c: Third, d: Fourth] +); + +generate!( + [k, l, m, n, o], + [a, b, c, d, e, f, g, h, i, j], + [a: First, b: Second, c: Third] +); + +generate!( + // reverse it, just to make sure they're alphabetized + // in the result set when all else is equal + [t, s, r, q, p], + [a, b, c, d, e, f, g, h, i, j], + [a: First, b: Second] +); + +generate!( + [u, v, w, x, y], + [a, b, c, d, e, f, g, h, i, j], + [a: First] +); diff --git a/tests/rustdoc-js/full-path-function.js b/tests/rustdoc-js/full-path-function.js index 48be51b156f..0464f792217 100644 --- a/tests/rustdoc-js/full-path-function.js +++ b/tests/rustdoc-js/full-path-function.js @@ -4,16 +4,16 @@ const EXPECTED = [ { 'query': 'sac -> usize', 'others': [ - { 'path': 'full_path_function::b::Sac', 'name': 'bar' }, { 'path': 'full_path_function::b::Sac', 'name': 'len' }, { 'path': 'full_path_function::sac::Sac', 'name': 'len' }, + { 'path': 'full_path_function::b::Sac', 'name': 'bar' }, ], }, { 'query': 'b::sac -> usize', 'others': [ - { 'path': 'full_path_function::b::Sac', 'name': 'bar' }, { 'path': 'full_path_function::b::Sac', 'name': 'len' }, + { 'path': 'full_path_function::b::Sac', 'name': 'bar' }, ], }, { diff --git a/tests/rustdoc-js/generics.js b/tests/rustdoc-js/generics.js index ebc92ccfc05..b3ca0af3056 100644 --- a/tests/rustdoc-js/generics.js +++ b/tests/rustdoc-js/generics.js @@ -1,4 +1,5 @@ // exact-check +// ignore-order const EXPECTED = [ { diff --git a/tests/rustdoc-js/impl-trait.js b/tests/rustdoc-js/impl-trait.js index 00d67d639bd..8bb3f2d3e99 100644 --- a/tests/rustdoc-js/impl-trait.js +++ b/tests/rustdoc-js/impl-trait.js @@ -39,8 +39,8 @@ const EXPECTED = [ { 'path': 'impl_trait', 'name': 'Aaaaaaa' }, ], 'in_args': [ - { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' }, { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' }, + { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' }, ], 'returned': [ { 'path': 'impl_trait', 'name': 'bbbbbbb' }, diff --git a/tests/rustdoc-js/type-parameters.js b/tests/rustdoc-js/type-parameters.js index e695f189bb6..e045409e507 100644 --- a/tests/rustdoc-js/type-parameters.js +++ b/tests/rustdoc-js/type-parameters.js @@ -1,20 +1,19 @@ // exact-check -// ignore-order const EXPECTED = [ { query: '-> trait:Some', others: [ - { path: 'foo', name: 'alef' }, { path: 'foo', name: 'alpha' }, + { path: 'foo', name: 'alef' }, ], }, { query: '-> generic:T', others: [ + { path: 'foo', name: 'beta' }, { path: 'foo', name: 'bet' }, { path: 'foo', name: 'alef' }, - { path: 'foo', name: 'beta' }, ], }, { @@ -44,38 +43,40 @@ const EXPECTED = [ { query: 'Other, Other', others: [ - { path: 'foo', name: 'other' }, { path: 'foo', name: 'alternate' }, + { path: 'foo', name: 'other' }, ], }, { query: 'generic:T', in_args: [ - { path: 'foo', name: 'bet' }, { path: 'foo', name: 'beta' }, - { path: 'foo', name: 'other' }, + { path: 'foo', name: 'bet' }, { path: 'foo', name: 'alternate' }, + { path: 'foo', name: 'other' }, ], }, { query: 'generic:Other', in_args: [ - { path: 'foo', name: 'bet' }, { path: 'foo', name: 'beta' }, - { path: 'foo', name: 'other' }, + { path: 'foo', name: 'bet' }, { path: 'foo', name: 'alternate' }, + { path: 'foo', name: 'other' }, ], }, { query: 'trait:Other', in_args: [ - { path: 'foo', name: 'other' }, { path: 'foo', name: 'alternate' }, + { path: 'foo', name: 'other' }, ], }, { query: 'Other', in_args: [ + // because function is called "other", it's sorted first + // even though it has higher type distance { path: 'foo', name: 'other' }, { path: 'foo', name: 'alternate' }, ], diff --git a/tests/rustdoc-ui/check-cfg/check-cfg.stderr b/tests/rustdoc-ui/check-cfg/check-cfg.stderr index d010c1f7ec6..3bca5dd0834 100644 --- a/tests/rustdoc-ui/check-cfg/check-cfg.stderr +++ b/tests/rustdoc-ui/check-cfg/check-cfg.stderr @@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `uniz` LL | #[cfg(uniz)] | ^^^^ help: there is a config with a similar name: `unix` | + = help: to expect this configuration use `--check-cfg=cfg(uniz)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/rustdoc-ui/doctest/check-attr-test.stderr b/tests/rustdoc-ui/doctest/check-attr-test.stderr index 01beba1ffc4..10f763a6f9d 100644 --- a/tests/rustdoc-ui/doctest/check-attr-test.stderr +++ b/tests/rustdoc-ui/doctest/check-attr-test.stderr @@ -1,4 +1,4 @@ -error: unknown attribute `compile-fail`. Did you mean `compile_fail`? +error: unknown attribute `compile-fail` --> $DIR/check-attr-test.rs:5:1 | 5 | / /// foo @@ -8,6 +8,7 @@ error: unknown attribute `compile-fail`. Did you mean `compile_fail`? 9 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `compile_fail` = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully note: the lint level is defined here --> $DIR/check-attr-test.rs:3:9 @@ -15,7 +16,7 @@ note: the lint level is defined here 3 | #![deny(rustdoc::invalid_codeblock_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unknown attribute `compilefail`. Did you mean `compile_fail`? +error: unknown attribute `compilefail` --> $DIR/check-attr-test.rs:5:1 | 5 | / /// foo @@ -25,9 +26,10 @@ error: unknown attribute `compilefail`. Did you mean `compile_fail`? 9 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `compile_fail` = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully -error: unknown attribute `comPile_fail`. Did you mean `compile_fail`? +error: unknown attribute `comPile_fail` --> $DIR/check-attr-test.rs:5:1 | 5 | / /// foo @@ -37,9 +39,10 @@ error: unknown attribute `comPile_fail`. Did you mean `compile_fail`? 9 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `compile_fail` = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully -error: unknown attribute `should-panic`. Did you mean `should_panic`? +error: unknown attribute `should-panic` --> $DIR/check-attr-test.rs:12:1 | 12 | / /// bar @@ -49,9 +52,10 @@ error: unknown attribute `should-panic`. Did you mean `should_panic`? 16 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `should_panic` = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running -error: unknown attribute `shouldpanic`. Did you mean `should_panic`? +error: unknown attribute `shouldpanic` --> $DIR/check-attr-test.rs:12:1 | 12 | / /// bar @@ -61,9 +65,10 @@ error: unknown attribute `shouldpanic`. Did you mean `should_panic`? 16 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `should_panic` = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running -error: unknown attribute `shOuld_panic`. Did you mean `should_panic`? +error: unknown attribute `shOuld_panic` --> $DIR/check-attr-test.rs:12:1 | 12 | / /// bar @@ -73,9 +78,10 @@ error: unknown attribute `shOuld_panic`. Did you mean `should_panic`? 16 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `should_panic` = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running -error: unknown attribute `no-run`. Did you mean `no_run`? +error: unknown attribute `no-run` --> $DIR/check-attr-test.rs:19:1 | 19 | / /// foobar @@ -85,9 +91,10 @@ error: unknown attribute `no-run`. Did you mean `no_run`? 23 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `no_run` = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) -error: unknown attribute `norun`. Did you mean `no_run`? +error: unknown attribute `norun` --> $DIR/check-attr-test.rs:19:1 | 19 | / /// foobar @@ -97,9 +104,10 @@ error: unknown attribute `norun`. Did you mean `no_run`? 23 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `no_run` = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) -error: unknown attribute `nO_run`. Did you mean `no_run`? +error: unknown attribute `nO_run` --> $DIR/check-attr-test.rs:19:1 | 19 | / /// foobar @@ -109,9 +117,10 @@ error: unknown attribute `nO_run`. Did you mean `no_run`? 23 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `no_run` = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) -error: unknown attribute `test-harness`. Did you mean `test_harness`? +error: unknown attribute `test-harness` --> $DIR/check-attr-test.rs:26:1 | 26 | / /// b @@ -121,9 +130,10 @@ error: unknown attribute `test-harness`. Did you mean `test_harness`? 30 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function -error: unknown attribute `testharness`. Did you mean `test_harness`? +error: unknown attribute `testharness` --> $DIR/check-attr-test.rs:26:1 | 26 | / /// b @@ -133,9 +143,10 @@ error: unknown attribute `testharness`. Did you mean `test_harness`? 30 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function -error: unknown attribute `tesT_harness`. Did you mean `test_harness`? +error: unknown attribute `tesT_harness` --> $DIR/check-attr-test.rs:26:1 | 26 | / /// b @@ -145,6 +156,7 @@ error: unknown attribute `tesT_harness`. Did you mean `test_harness`? 30 | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function error: aborting due to 12 previous errors diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.stderr b/tests/rustdoc-ui/doctest/check-cfg-test.stderr index 0bfd569e381..5524f582d56 100644 --- a/tests/rustdoc-ui/doctest/check-cfg-test.stderr +++ b/tests/rustdoc-ui/doctest/check-cfg-test.stderr @@ -5,6 +5,8 @@ LL | #[cfg(feature = "invalid")] | ^^^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `test` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("invalid"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/rustdoc-ui/lints/check-attr.rs b/tests/rustdoc-ui/lints/check-attr.rs index 0b3f7bedda5..3c06e6c076b 100644 --- a/tests/rustdoc-ui/lints/check-attr.rs +++ b/tests/rustdoc-ui/lints/check-attr.rs @@ -39,3 +39,20 @@ pub fn foobar() {} /// boo /// ``` pub fn b() {} + +/// b +//~^ ERROR +/// +/// ```rust2018 +/// boo +/// ``` +pub fn c() {} + +/// b +//~^ ERROR +//~| ERROR +/// +/// ```rust2018 shouldpanic +/// boo +/// ``` +pub fn d() {} diff --git a/tests/rustdoc-ui/lints/check-attr.stderr b/tests/rustdoc-ui/lints/check-attr.stderr index f66e63ab727..d640125ab51 100644 --- a/tests/rustdoc-ui/lints/check-attr.stderr +++ b/tests/rustdoc-ui/lints/check-attr.stderr @@ -1,4 +1,4 @@ -error: unknown attribute `compile-fail`. Did you mean `compile_fail`? +error: unknown attribute `compile-fail` --> $DIR/check-attr.rs:3:1 | LL | / /// foo @@ -10,6 +10,7 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `compile_fail` = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully note: the lint level is defined here --> $DIR/check-attr.rs:1:9 @@ -17,7 +18,7 @@ note: the lint level is defined here LL | #![deny(rustdoc::invalid_codeblock_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unknown attribute `compilefail`. Did you mean `compile_fail`? +error: unknown attribute `compilefail` --> $DIR/check-attr.rs:3:1 | LL | / /// foo @@ -29,9 +30,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `compile_fail` = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully -error: unknown attribute `comPile_fail`. Did you mean `compile_fail`? +error: unknown attribute `comPile_fail` --> $DIR/check-attr.rs:3:1 | LL | / /// foo @@ -43,9 +45,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `compile_fail` = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully -error: unknown attribute `should-panic`. Did you mean `should_panic`? +error: unknown attribute `should-panic` --> $DIR/check-attr.rs:13:1 | LL | / /// bar @@ -57,9 +60,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `should_panic` = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running -error: unknown attribute `shouldpanic`. Did you mean `should_panic`? +error: unknown attribute `shouldpanic` --> $DIR/check-attr.rs:13:1 | LL | / /// bar @@ -71,9 +75,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `should_panic` = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running -error: unknown attribute `sHould_panic`. Did you mean `should_panic`? +error: unknown attribute `sHould_panic` --> $DIR/check-attr.rs:13:1 | LL | / /// bar @@ -85,9 +90,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `should_panic` = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running -error: unknown attribute `no-run`. Did you mean `no_run`? +error: unknown attribute `no-run` --> $DIR/check-attr.rs:23:1 | LL | / /// foobar @@ -99,9 +105,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `no_run` = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) -error: unknown attribute `norun`. Did you mean `no_run`? +error: unknown attribute `norun` --> $DIR/check-attr.rs:23:1 | LL | / /// foobar @@ -113,9 +120,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `no_run` = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) -error: unknown attribute `no_Run`. Did you mean `no_run`? +error: unknown attribute `no_Run` --> $DIR/check-attr.rs:23:1 | LL | / /// foobar @@ -127,9 +135,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `no_run` = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) -error: unknown attribute `test-harness`. Did you mean `test_harness`? +error: unknown attribute `test-harness` --> $DIR/check-attr.rs:33:1 | LL | / /// b @@ -141,9 +150,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function -error: unknown attribute `testharness`. Did you mean `test_harness`? +error: unknown attribute `testharness` --> $DIR/check-attr.rs:33:1 | LL | / /// b @@ -155,9 +165,10 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function -error: unknown attribute `teSt_harness`. Did you mean `test_harness`? +error: unknown attribute `teSt_harness` --> $DIR/check-attr.rs:33:1 | LL | / /// b @@ -169,7 +180,50 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function -error: aborting due to 12 previous errors +error: unknown attribute `rust2018` + --> $DIR/check-attr.rs:43:1 + | +LL | / /// b +LL | | +LL | | /// +LL | | /// ```rust2018 +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: there is an attribute with a similar name: `edition2018` + +error: unknown attribute `rust2018` + --> $DIR/check-attr.rs:51:1 + | +LL | / /// b +LL | | +LL | | +LL | | /// +LL | | /// ```rust2018 shouldpanic +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: there is an attribute with a similar name: `edition2018` + +error: unknown attribute `shouldpanic` + --> $DIR/check-attr.rs:51:1 + | +LL | / /// b +LL | | +LL | | +LL | | /// +LL | | /// ```rust2018 shouldpanic +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: there is an attribute with a similar name: `should_panic` + = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running + +error: aborting due to 15 previous errors diff --git a/tests/rustdoc-ui/lints/check-fail.stderr b/tests/rustdoc-ui/lints/check-fail.stderr index f05e457af64..99b01bac598 100644 --- a/tests/rustdoc-ui/lints/check-fail.stderr +++ b/tests/rustdoc-ui/lints/check-fail.stderr @@ -22,7 +22,7 @@ note: the lint level is defined here LL | #![deny(rustdoc::missing_doc_code_examples)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unknown attribute `testharness`. Did you mean `test_harness`? +error: unknown attribute `testharness` --> $DIR/check-fail.rs:8:1 | LL | / //! ```rust,testharness @@ -31,6 +31,7 @@ LL | | //! let x = 12; LL | | //! ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function note: the lint level is defined here --> $DIR/check-fail.rs:6:9 @@ -39,7 +40,7 @@ LL | #![deny(rustdoc::all)] | ^^^^^^^^^^^^ = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]` -error: unknown attribute `testharness`. Did you mean `test_harness`? +error: unknown attribute `testharness` --> $DIR/check-fail.rs:17:1 | LL | / /// hello @@ -50,6 +51,7 @@ LL | | /// let x = 12; LL | | /// ``` | |_______^ | + = help: there is an attribute with a similar name: `test_harness` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function error: aborting due to 4 previous errors diff --git a/tests/rustdoc/reexport-cfg.rs b/tests/rustdoc/reexport-cfg.rs new file mode 100644 index 00000000000..a6179fad873 --- /dev/null +++ b/tests/rustdoc/reexport-cfg.rs @@ -0,0 +1,30 @@ +// This test ensures that only the re-export `cfg` will be displayed and that it won't +// include `cfg`s from the previous chained items. + +#![crate_name = "foo"] +#![feature(doc_auto_cfg, doc_cfg)] + +mod foo { + #[cfg(not(feature = "foo"))] + pub struct Bar; + + #[doc(cfg(not(feature = "bar")))] + pub struct Bar2; +} + +// @has 'foo/index.html' +// @has - '//*[@class="item-name"]' 'BabarNon-lie' +#[cfg(not(feature = "lie"))] +pub use crate::foo::Bar as Babar; + +// @has - '//*[@class="item-name"]' 'Babar2Non-cake' +#[doc(cfg(not(feature = "cake")))] +pub use crate::foo::Bar2 as Babar2; + +// @has - '//*[@class="item-table"]/li' 'pub use crate::Babar as Elephant;Non-robot' +#[cfg(not(feature = "robot"))] +pub use crate::Babar as Elephant; + +// @has - '//*[@class="item-table"]/li' 'pub use crate::Babar2 as Elephant2;Non-cat' +#[doc(cfg(not(feature = "cat")))] +pub use crate::Babar2 as Elephant2; diff --git a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs b/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs index a79d05904e3..c81c654a20e 100644 --- a/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs +++ b/tests/rustdoc/reexport-stability-tags-deprecated-and-portability.rs @@ -27,7 +27,7 @@ pub mod mod1 { pub mod mod2 { // @has - '//code' 'pub use tag::Portability;' // @!has - '//span' 'Deprecated' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' pub use tag::Portability; } @@ -35,7 +35,7 @@ pub mod mod2 { pub mod mod3 { // @has - '//code' 'pub use tag::Both;' // @has - '//span' 'Deprecated' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' pub use tag::Both; } diff --git a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs b/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs index ff8a910f59f..423838e251b 100644 --- a/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs +++ b/tests/rustdoc/reexport-stability-tags-unstable-and-portability.rs @@ -35,7 +35,7 @@ pub mod mod1 { pub mod mod2 { // @has - '//code' 'pub use tag::Portability;' // @!has - '//span' 'Experimental' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' #[stable(feature = "rust1", since = "1.0.0")] pub use tag::Portability; } @@ -45,7 +45,7 @@ pub mod mod2 { pub mod mod3 { // @has - '//code' 'pub use tag::Both;' // @has - '//span' 'Experimental' - // @has - '//span' 'sync' + // @!has - '//span' 'sync' #[stable(feature = "rust1", since = "1.0.0")] pub use tag::Both; } diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs index d311be5982d..ad667511332 100644 --- a/tests/ui-fulldeps/stable-mir/check_defs.rs +++ b/tests/ui-fulldeps/stable-mir/check_defs.rs @@ -69,7 +69,7 @@ fn extract_elem_ty(ty: Ty) -> Ty { /// Check signature and type of `Vec::<u8>::new` and its generic version. fn test_vec_new(instance: mir::mono::Instance) { - let sig = instance.fn_sig(); + let sig = instance.ty().kind().fn_sig().unwrap().skip_binder(); assert_matches!(sig.inputs(), &[]); let elem_ty = extract_elem_ty(sig.output()); assert_matches!(elem_ty.kind(), TyKind::RigidTy(RigidTy::Uint(UintTy::U8))); diff --git a/tests/ui/abi/stack-probes-lto.rs b/tests/ui/abi/stack-probes-lto.rs index 7282d09706c..fb478671754 100644 --- a/tests/ui/abi/stack-probes-lto.rs +++ b/tests/ui/abi/stack-probes-lto.rs @@ -1,5 +1,7 @@ -// revisions: x32 x64 +// revisions: aarch64 x32 x64 // run-pass +//[aarch64] only-aarch64 +//[aarch64] min-llvm-version: 18 //[x32] only-x86 //[x64] only-x86_64 // ignore-sgx no processes diff --git a/tests/ui/abi/stack-probes.rs b/tests/ui/abi/stack-probes.rs index 4b8a79a4b68..e5c7a1a6804 100644 --- a/tests/ui/abi/stack-probes.rs +++ b/tests/ui/abi/stack-probes.rs @@ -1,5 +1,7 @@ -// revisions: x32 x64 +// revisions: aarch64 x32 x64 // run-pass +//[aarch64] only-aarch64 +//[aarch64] min-llvm-version: 18 //[x32] only-x86 //[x64] only-x86_64 // ignore-emscripten no processes diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs index 66f879c5a71..054034b4c28 100644 --- a/tests/ui/associated-inherent-types/inference.rs +++ b/tests/ui/associated-inherent-types/inference.rs @@ -1,7 +1,7 @@ // Testing inference capabilities. // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(inherent_associated_types)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout index b0447a58261..47b39e5246d 100644 --- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout +++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout @@ -52,10 +52,16 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.arg`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop<bool>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes +print-type-size field `.value`: 1 bytes print-type-size type: `std::mem::MaybeUninit<bool>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes +print-type-size variant `MaybeUninit`: 1 bytes +print-type-size field `.uninit`: 0 bytes +print-type-size field `.value`: 1 bytes print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Ready`: 0 bytes diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs index c8fd2d8f6c2..491dfcc6ae0 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs @@ -1,6 +1,7 @@ // run-pass // edition:2021 +#![feature(noop_waker)] use std::future::Future; @@ -32,33 +33,18 @@ async fn async_main() { // ------------------------------------------------------------------------- // // Implementation Details Below... -use std::pin::Pin; +use std::pin::pin; use std::task::*; -pub fn noop_waker() -> Waker { - let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE); - - // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld - unsafe { Waker::from_raw(raw) } -} - -const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); - -unsafe fn noop_clone(_p: *const ()) -> RawWaker { - RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE) -} - -unsafe fn noop(_p: *const ()) {} - fn main() { - let mut fut = async_main(); + let mut fut = pin!(async_main()); // Poll loop, just to test the future... - let waker = noop_waker(); + let waker = Waker::noop(); let ctx = &mut Context::from_waker(&waker); loop { - match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } { + match fut.as_mut().poll(ctx) { Poll::Pending => {} Poll::Ready(()) => break, } diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs index 18b0fa4856d..f21abf012ba 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs @@ -2,6 +2,7 @@ // known-bug: #108309 #![feature(min_specialization)] +#![feature(noop_waker)] struct MyStruct; @@ -35,34 +36,18 @@ async fn indirection<T>(x: T) -> &'static str { // ------------------------------------------------------------------------- // // Implementation Details Below... -use std::future::Future; -use std::pin::Pin; +use std::pin::{pin, Pin}; use std::task::*; -pub fn noop_waker() -> Waker { - let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE); - - // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld - unsafe { Waker::from_raw(raw) } -} - -const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); - -unsafe fn noop_clone(_p: *const ()) -> RawWaker { - RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE) -} - -unsafe fn noop(_p: *const ()) {} - fn main() { - let mut fut = async_main(); + let mut fut = pin!(async_main()); // Poll loop, just to test the future... - let waker = noop_waker(); + let waker = Waker::noop(); let ctx = &mut Context::from_waker(&waker); loop { - match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } { + match fut.as_mut().poll(ctx) { Poll::Pending => {} Poll::Ready(()) => break, } diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr index 5e2be08623b..0560cd9c5fe 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -1,11 +1,11 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/dont-project-to-specializable-projection.rs:13:5 + --> $DIR/dont-project-to-specializable-projection.rs:14:5 | LL | default async fn foo(_: T) -> &'static str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found future | note: type in trait - --> $DIR/dont-project-to-specializable-projection.rs:9:5 + --> $DIR/dont-project-to-specializable-projection.rs:10:5 | LL | async fn foo(_: T) -> &'static str; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,13 +13,29 @@ LL | async fn foo(_: T) -> &'static str; found signature `fn(_) -> impl Future<Output = &'static str>` error: async associated function in trait cannot be specialized - --> $DIR/dont-project-to-specializable-projection.rs:13:5 + --> $DIR/dont-project-to-specializable-projection.rs:14:5 | LL | default async fn foo(_: T) -> &'static str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: specialization behaves in inconsistent and surprising ways with async functions in traits, and for now is disallowed -error: aborting due to 2 previous errors +error[E0599]: no method named `poll` found for struct `Pin<&mut impl Future<Output = ()>>` in the current scope + --> $DIR/dont-project-to-specializable-projection.rs:50:28 + | +LL | match fut.as_mut().poll(ctx) { + | ^^^^ method not found in `Pin<&mut impl Future<Output = ()>>` + --> $SRC_DIR/core/src/future/future.rs:LL:COL + | + = note: the method is available for `Pin<&mut impl Future<Output = ()>>` here + | + = help: items from traits can only be used if the trait is in scope +help: the following trait is implemented but not in scope; perhaps add a `use` for it: + | +LL + use std::future::Future; + | + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0053`. +Some errors have detailed explanations: E0053, E0599. +For more information about an error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr index 95731b67ccf..8e573b512ad 100644 --- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr @@ -1,7 +1,9 @@ -error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}` +error[E0391]: cycle detected when computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>` | - = note: ...which requires computing layout of `<<A as First>::Second as Second>::{opaque#0}`... - = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`, completing the cycle + = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`... + = note: ...which requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}`... + = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<<<A as First>::Second as Second>::{opaque#0}>`... + = note: ...which again requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:33:27: 35:6}>`, completing the cycle = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:6:13: 8:6}` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/async-await/normalize-output-in-signature-deduction.rs b/tests/ui/async-await/normalize-output-in-signature-deduction.rs index 960065a83a4..e07fe9e98ec 100644 --- a/tests/ui/async-await/normalize-output-in-signature-deduction.rs +++ b/tests/ui/async-await/normalize-output-in-signature-deduction.rs @@ -1,6 +1,6 @@ // edition:2021 // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs index e581e5ffda7..6097c7f1073 100644 --- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs +++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs @@ -1,7 +1,7 @@ // revisions: current next //[current] known-bug: #109924 //[next] check-pass -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // edition:2021 #![feature(return_type_notation)] diff --git a/tests/ui/auto-traits/issue-23080-2.rs b/tests/ui/auto-traits/issue-23080-2.rs index 882b8f39384..d63cd9d5dd6 100644 --- a/tests/ui/auto-traits/issue-23080-2.rs +++ b/tests/ui/auto-traits/issue-23080-2.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(auto_traits)] #![feature(negative_impls)] diff --git a/tests/ui/check-cfg/allow-same-level.stderr b/tests/ui/check-cfg/allow-same-level.stderr index 652efc3f591..7f0faa0700d 100644 --- a/tests/ui/check-cfg/allow-same-level.stderr +++ b/tests/ui/check-cfg/allow-same-level.stderr @@ -5,6 +5,8 @@ LL | #[cfg(FALSE)] | ^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(FALSE)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/cargo-feature.none.stderr b/tests/ui/check-cfg/cargo-feature.none.stderr new file mode 100644 index 00000000000..44c8f7e3072 --- /dev/null +++ b/tests/ui/check-cfg/cargo-feature.none.stderr @@ -0,0 +1,31 @@ +warning: unexpected `cfg` condition name: `feature` + --> $DIR/cargo-feature.rs:13:7 + | +LL | #[cfg(feature = "serde")] + | ^^^^^^^^^^^^^^^^^ + | + = help: consider defining some features in `Cargo.toml` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `tokio_unstable` + --> $DIR/cargo-feature.rs:18:7 + | +LL | #[cfg(tokio_unstable)] + | ^^^^^^^^^^^^^^ + | + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(tokio_unstable)");` to the top of a `build.rs` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `CONFIG_NVME` + --> $DIR/cargo-feature.rs:22:7 + | +LL | #[cfg(CONFIG_NVME = "m")] + | ^^^^^^^^^^^^^^^^^ + | + = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of a `build.rs` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + +warning: 3 warnings emitted + diff --git a/tests/ui/check-cfg/cargo-feature.rs b/tests/ui/check-cfg/cargo-feature.rs index ea48c6ea201..fe343d0a678 100644 --- a/tests/ui/check-cfg/cargo-feature.rs +++ b/tests/ui/check-cfg/cargo-feature.rs @@ -3,12 +3,25 @@ // list of all the expected names // // check-pass +// revisions: some none // rustc-env:CARGO=/usr/bin/cargo // compile-flags: --check-cfg=cfg() -Z unstable-options -// error-pattern:Cargo.toml +// [some]compile-flags: --check-cfg=cfg(feature,values("bitcode")) +// [some]compile-flags: --check-cfg=cfg(CONFIG_NVME,values("y")) +// [none]error-pattern:Cargo.toml #[cfg(feature = "serde")] -//~^ WARNING unexpected `cfg` condition name +//[none]~^ WARNING unexpected `cfg` condition name +//[some]~^^ WARNING unexpected `cfg` condition value fn ser() {} +#[cfg(tokio_unstable)] +//~^ WARNING unexpected `cfg` condition name +fn tokio() {} + +#[cfg(CONFIG_NVME = "m")] +//[none]~^ WARNING unexpected `cfg` condition name +//[some]~^^ WARNING unexpected `cfg` condition value +fn tokio() {} + fn main() {} diff --git a/tests/ui/check-cfg/cargo-feature.some.stderr b/tests/ui/check-cfg/cargo-feature.some.stderr new file mode 100644 index 00000000000..92d63d01534 --- /dev/null +++ b/tests/ui/check-cfg/cargo-feature.some.stderr @@ -0,0 +1,35 @@ +warning: unexpected `cfg` condition value: `serde` + --> $DIR/cargo-feature.rs:13:7 + | +LL | #[cfg(feature = "serde")] + | ^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: `bitcode` + = help: consider adding `serde` as a feature in `Cargo.toml` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `tokio_unstable` + --> $DIR/cargo-feature.rs:18:7 + | +LL | #[cfg(tokio_unstable)] + | ^^^^^^^^^^^^^^ + | + = help: expected names are: `CONFIG_NVME`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(tokio_unstable)");` to the top of a `build.rs` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + +warning: unexpected `cfg` condition value: `m` + --> $DIR/cargo-feature.rs:22:7 + | +LL | #[cfg(CONFIG_NVME = "m")] + | ^^^^^^^^^^^^^^--- + | | + | help: there is a expected value with a similar name: `"y"` + | + = note: expected values for `CONFIG_NVME` are: `y` + = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(CONFIG_NVME, values(\"m\"))");` to the top of a `build.rs` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + +warning: 3 warnings emitted + diff --git a/tests/ui/check-cfg/cargo-feature.stderr b/tests/ui/check-cfg/cargo-feature.stderr deleted file mode 100644 index 619410a28f3..00000000000 --- a/tests/ui/check-cfg/cargo-feature.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: unexpected `cfg` condition name: `feature` - --> $DIR/cargo-feature.rs:10:7 - | -LL | #[cfg(feature = "serde")] - | ^^^^^^^^^^^^^^^^^ - | - = help: consider defining some features in `Cargo.toml` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/check-cfg/compact-names.stderr b/tests/ui/check-cfg/compact-names.stderr index d3bfb9f7100..dfa26f5dde0 100644 --- a/tests/ui/check-cfg/compact-names.stderr +++ b/tests/ui/check-cfg/compact-names.stderr @@ -5,6 +5,8 @@ LL | #[cfg(target(os = "linux", architecture = "arm"))] | ^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(target_architecture, values("arm"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/compact-values.stderr b/tests/ui/check-cfg/compact-values.stderr index 819b789c3e5..10276af4d8f 100644 --- a/tests/ui/check-cfg/compact-values.stderr +++ b/tests/ui/check-cfg/compact-values.stderr @@ -5,6 +5,8 @@ LL | #[cfg(target(os = "linux", pointer_width = "X"))] | ^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_pointer_width` are: `16`, `32`, `64` + = help: to expect this configuration use `--check-cfg=cfg(target_pointer_width, values("X"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/concat-values.stderr b/tests/ui/check-cfg/concat-values.stderr index da2bd7d6ad9..dec43f5bda3 100644 --- a/tests/ui/check-cfg/concat-values.stderr +++ b/tests/ui/check-cfg/concat-values.stderr @@ -5,6 +5,8 @@ LL | #[cfg(my_cfg)] | ^^^^^^ | = note: expected values for `my_cfg` are: `bar`, `foo` + = help: to expect this configuration use `--check-cfg=cfg(my_cfg)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `unk` @@ -14,6 +16,8 @@ LL | #[cfg(my_cfg = "unk")] | ^^^^^^^^^^^^^^ | = note: expected values for `my_cfg` are: `bar`, `foo` + = help: to expect this configuration use `--check-cfg=cfg(my_cfg, values("unk"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/diagnotics.cargo.stderr b/tests/ui/check-cfg/diagnotics.cargo.stderr new file mode 100644 index 00000000000..05c52bf59fa --- /dev/null +++ b/tests/ui/check-cfg/diagnotics.cargo.stderr @@ -0,0 +1,71 @@ +warning: unexpected `cfg` condition name: `featur` + --> $DIR/diagnotics.rs:7:7 + | +LL | #[cfg(featur)] + | ^^^^^^ help: there is a config with a similar name: `feature` + | + = help: expected values for `feature` are: `foo` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `featur` + --> $DIR/diagnotics.rs:11:7 + | +LL | #[cfg(featur = "foo")] + | ^^^^^^^^^^^^^^ + | + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration +help: there is a config with a similar name and value + | +LL | #[cfg(feature = "foo")] + | ~~~~~~~ + +warning: unexpected `cfg` condition name: `featur` + --> $DIR/diagnotics.rs:15:7 + | +LL | #[cfg(featur = "fo")] + | ^^^^^^^^^^^^^ + | + = help: expected values for `feature` are: `foo` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration +help: there is a config with a similar name and different values + | +LL | #[cfg(feature = "foo")] + | ~~~~~~~~~~~~~~~ + +warning: unexpected `cfg` condition name: `no_value` + --> $DIR/diagnotics.rs:22:7 + | +LL | #[cfg(no_value)] + | ^^^^^^^^ help: there is a config with a similar name: `no_values` + | + = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_value)");` to the top of a `build.rs` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `no_value` + --> $DIR/diagnotics.rs:26:7 + | +LL | #[cfg(no_value = "foo")] + | ^^^^^^^^^^^^^^^^ + | + = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_value, values(\"foo\"))");` to the top of a `build.rs` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration +help: there is a config with a similar name and no value + | +LL | #[cfg(no_values)] + | ~~~~~~~~~ + +warning: unexpected `cfg` condition value: `bar` + --> $DIR/diagnotics.rs:30:7 + | +LL | #[cfg(no_values = "bar")] + | ^^^^^^^^^-------- + | | + | help: remove the value + | + = note: no expected value for `no_values` + = help: consider using a Cargo feature instead or adding `println!("cargo:rustc-check-cfg=cfg(no_values, values(\"bar\"))");` to the top of a `build.rs` + = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration + +warning: 6 warnings emitted + diff --git a/tests/ui/check-cfg/diagnotics.rs b/tests/ui/check-cfg/diagnotics.rs index 45875bddc17..33073f05f69 100644 --- a/tests/ui/check-cfg/diagnotics.rs +++ b/tests/ui/check-cfg/diagnotics.rs @@ -1,4 +1,7 @@ // check-pass +// revisions: cargo rustc +// [rustc]unset-rustc-env:CARGO +// [cargo]rustc-env:CARGO=/usr/bin/cargo // compile-flags: --check-cfg=cfg(feature,values("foo")) --check-cfg=cfg(no_values) -Z unstable-options #[cfg(featur)] diff --git a/tests/ui/check-cfg/diagnotics.rustc.stderr b/tests/ui/check-cfg/diagnotics.rustc.stderr new file mode 100644 index 00000000000..2b1129a3920 --- /dev/null +++ b/tests/ui/check-cfg/diagnotics.rustc.stderr @@ -0,0 +1,74 @@ +warning: unexpected `cfg` condition name: `featur` + --> $DIR/diagnotics.rs:7:7 + | +LL | #[cfg(featur)] + | ^^^^^^ help: there is a config with a similar name: `feature` + | + = help: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(featur)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `featur` + --> $DIR/diagnotics.rs:11:7 + | +LL | #[cfg(featur = "foo")] + | ^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(featur, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration +help: there is a config with a similar name and value + | +LL | #[cfg(feature = "foo")] + | ~~~~~~~ + +warning: unexpected `cfg` condition name: `featur` + --> $DIR/diagnotics.rs:15:7 + | +LL | #[cfg(featur = "fo")] + | ^^^^^^^^^^^^^ + | + = help: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(featur, values("fo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration +help: there is a config with a similar name and different values + | +LL | #[cfg(feature = "foo")] + | ~~~~~~~~~~~~~~~ + +warning: unexpected `cfg` condition name: `no_value` + --> $DIR/diagnotics.rs:22:7 + | +LL | #[cfg(no_value)] + | ^^^^^^^^ help: there is a config with a similar name: `no_values` + | + = help: to expect this configuration use `--check-cfg=cfg(no_value)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `no_value` + --> $DIR/diagnotics.rs:26:7 + | +LL | #[cfg(no_value = "foo")] + | ^^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(no_value, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration +help: there is a config with a similar name and no value + | +LL | #[cfg(no_values)] + | ~~~~~~~~~ + +warning: unexpected `cfg` condition value: `bar` + --> $DIR/diagnotics.rs:30:7 + | +LL | #[cfg(no_values = "bar")] + | ^^^^^^^^^-------- + | | + | help: remove the value + | + = note: no expected value for `no_values` + = help: to expect this configuration use `--check-cfg=cfg(no_values, values("bar"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + +warning: 6 warnings emitted + diff --git a/tests/ui/check-cfg/diagnotics.stderr b/tests/ui/check-cfg/diagnotics.stderr deleted file mode 100644 index 31c0db03a7e..00000000000 --- a/tests/ui/check-cfg/diagnotics.stderr +++ /dev/null @@ -1,61 +0,0 @@ -warning: unexpected `cfg` condition name: `featur` - --> $DIR/diagnotics.rs:4:7 - | -LL | #[cfg(featur)] - | ^^^^^^ help: there is a config with a similar name: `feature` - | - = help: expected values for `feature` are: `foo` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition name: `featur` - --> $DIR/diagnotics.rs:8:7 - | -LL | #[cfg(featur = "foo")] - | ^^^^^^^^^^^^^^ - | -help: there is a config with a similar name and value - | -LL | #[cfg(feature = "foo")] - | ~~~~~~~ - -warning: unexpected `cfg` condition name: `featur` - --> $DIR/diagnotics.rs:12:7 - | -LL | #[cfg(featur = "fo")] - | ^^^^^^^^^^^^^ - | - = help: expected values for `feature` are: `foo` -help: there is a config with a similar name and different values - | -LL | #[cfg(feature = "foo")] - | ~~~~~~~~~~~~~~~ - -warning: unexpected `cfg` condition name: `no_value` - --> $DIR/diagnotics.rs:19:7 - | -LL | #[cfg(no_value)] - | ^^^^^^^^ help: there is a config with a similar name: `no_values` - -warning: unexpected `cfg` condition name: `no_value` - --> $DIR/diagnotics.rs:23:7 - | -LL | #[cfg(no_value = "foo")] - | ^^^^^^^^^^^^^^^^ - | -help: there is a config with a similar name and no value - | -LL | #[cfg(no_values)] - | ~~~~~~~~~ - -warning: unexpected `cfg` condition value: `bar` - --> $DIR/diagnotics.rs:27:7 - | -LL | #[cfg(no_values = "bar")] - | ^^^^^^^^^-------- - | | - | help: remove the value - | - = note: no expected value for `no_values` - -warning: 6 warnings emitted - diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr index 9501c134bac..27af8212026 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr @@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -16,18 +18,26 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` --> $DIR/exhaustive-names-values.rs:18:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` --> $DIR/exhaustive-names-values.rs:25:7 | LL | #[cfg(feature = "std")] | ^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(feature, values("std"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr deleted file mode 100644 index e37a222f52a..00000000000 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr +++ /dev/null @@ -1,33 +0,0 @@ -warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:11:7 - | -LL | #[cfg(unknown_key = "value")] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:15:7 - | -LL | #[cfg(test = "value")] - | ^^^^---------- - | | - | help: remove the value - | - = note: no expected value for `test` - -warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:19:7 - | -LL | #[cfg(feature = "unk")] - | ^^^^^^^^^^^^^^^ - -warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:26:7 - | -LL | #[cfg(feature = "std")] - | ^^^^^^^^^^^^^^^ - -warning: 4 warnings emitted - diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr index ea204eaff1b..a5aa80ef8e5 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr @@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -16,6 +18,8 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` --> $DIR/exhaustive-names-values.rs:18:7 @@ -24,6 +28,8 @@ LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `std` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 3 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr index ea204eaff1b..a5aa80ef8e5 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr @@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -16,6 +18,8 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` --> $DIR/exhaustive-names-values.rs:18:7 @@ -24,6 +28,8 @@ LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `std` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 3 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr b/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr deleted file mode 100644 index b5c8cad275f..00000000000 --- a/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names.rs:8:7 - | -LL | #[cfg(unknown_key = "value")] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/check-cfg/exhaustive-names.stderr b/tests/ui/check-cfg/exhaustive-names.stderr index c5f6d537c5e..cfac28cd9b9 100644 --- a/tests/ui/check-cfg/exhaustive-names.stderr +++ b/tests/ui/check-cfg/exhaustive-names.stderr @@ -5,6 +5,8 @@ LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr index 745646bda1c..0a7bd81b8aa 100644 --- a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr @@ -7,6 +7,8 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-values.without_names.stderr b/tests/ui/check-cfg/exhaustive-values.without_names.stderr index 745646bda1c..0a7bd81b8aa 100644 --- a/tests/ui/check-cfg/exhaustive-values.without_names.stderr +++ b/tests/ui/check-cfg/exhaustive-values.without_names.stderr @@ -7,6 +7,8 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("value"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/mix.cfg.stderr b/tests/ui/check-cfg/mix.cfg.stderr deleted file mode 100644 index 046d40f36b0..00000000000 --- a/tests/ui/check-cfg/mix.cfg.stderr +++ /dev/null @@ -1,184 +0,0 @@ -warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:15:7 - | -LL | #[cfg(widnows)] - | ^^^^^^^ help: there is a config with a similar name: `windows` - | - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition value: (none) - --> $DIR/mix.rs:19:7 - | -LL | #[cfg(feature)] - | ^^^^^^^- help: specify a config value: `= "foo"` - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition value: `bar` - --> $DIR/mix.rs:26:7 - | -LL | #[cfg(feature = "bar")] - | ^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:30:7 - | -LL | #[cfg(feature = "zebra")] - | ^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition name: `uu` - --> $DIR/mix.rs:34:12 - | -LL | #[cfg_attr(uu, test)] - | ^^ - | - = help: expected names are: `cfg`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `names_values`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` - -warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:43:10 - | -LL | cfg!(widnows); - | ^^^^^^^ help: there is a config with a similar name: `windows` - -warning: unexpected `cfg` condition value: `bar` - --> $DIR/mix.rs:46:10 - | -LL | cfg!(feature = "bar"); - | ^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:48:10 - | -LL | cfg!(feature = "zebra"); - | ^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:50:10 - | -LL | cfg!(xxx = "foo"); - | ^^^^^^^^^^^ - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:52:10 - | -LL | cfg!(xxx); - | ^^^ - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:54:14 - | -LL | cfg!(any(xxx, windows)); - | ^^^ - -warning: unexpected `cfg` condition value: `bad` - --> $DIR/mix.rs:56:14 - | -LL | cfg!(any(feature = "bad", windows)); - | ^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:58:23 - | -LL | cfg!(any(windows, xxx)); - | ^^^ - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:60:20 - | -LL | cfg!(all(unix, xxx)); - | ^^^ - -warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:62:14 - | -LL | cfg!(all(aa, bb)); - | ^^ - -warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:62:18 - | -LL | cfg!(all(aa, bb)); - | ^^ - -warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:65:14 - | -LL | cfg!(any(aa, bb)); - | ^^ - -warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:65:18 - | -LL | cfg!(any(aa, bb)); - | ^^ - -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:68:20 - | -LL | cfg!(any(unix, feature = "zebra")); - | ^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:70:14 - | -LL | cfg!(any(xxx, feature = "zebra")); - | ^^^ - -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:70:19 - | -LL | cfg!(any(xxx, feature = "zebra")); - | ^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:73:14 - | -LL | cfg!(any(xxx, unix, xxx)); - | ^^^ - -warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:73:25 - | -LL | cfg!(any(xxx, unix, xxx)); - | ^^^ - -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:14 - | -LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); - | ^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:33 - | -LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); - | ^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:52 - | -LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); - | ^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `foo` - -warning: 26 warnings emitted - diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 25b8f95ae2f..39660a2fd6e 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `widnows` LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` | + = help: to expect this configuration use `--check-cfg=cfg(widnows)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) @@ -13,6 +15,8 @@ LL | #[cfg(feature)] | ^^^^^^^- help: specify a config value: `= "foo"` | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bar` --> $DIR/mix.rs:23:7 @@ -21,6 +25,8 @@ LL | #[cfg(feature = "bar")] | ^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:27:7 @@ -29,6 +35,8 @@ LL | #[cfg(feature = "zebra")] | ^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `uu` --> $DIR/mix.rs:31:12 @@ -37,12 +45,17 @@ LL | #[cfg_attr(uu, test)] | ^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(uu)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `widnows` --> $DIR/mix.rs:40:10 | LL | cfg!(widnows); | ^^^^^^^ help: there is a config with a similar name: `windows` + | + = help: to expect this configuration use `--check-cfg=cfg(widnows)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bar` --> $DIR/mix.rs:43:10 @@ -51,6 +64,8 @@ LL | cfg!(feature = "bar"); | ^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:45:10 @@ -59,24 +74,35 @@ LL | cfg!(feature = "zebra"); | ^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:47:10 | LL | cfg!(xxx = "foo"); | ^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:49:10 | LL | cfg!(xxx); | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:51:14 | LL | cfg!(any(xxx, windows)); | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bad` --> $DIR/mix.rs:53:14 @@ -85,42 +111,62 @@ LL | cfg!(any(feature = "bad", windows)); | ^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("bad"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:55:23 | LL | cfg!(any(windows, xxx)); | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:57:20 | LL | cfg!(all(unix, xxx)); | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `aa` --> $DIR/mix.rs:59:14 | LL | cfg!(all(aa, bb)); | ^^ + | + = help: to expect this configuration use `--check-cfg=cfg(aa)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `bb` --> $DIR/mix.rs:59:18 | LL | cfg!(all(aa, bb)); | ^^ + | + = help: to expect this configuration use `--check-cfg=cfg(bb)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `aa` --> $DIR/mix.rs:62:14 | LL | cfg!(any(aa, bb)); | ^^ + | + = help: to expect this configuration use `--check-cfg=cfg(aa)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `bb` --> $DIR/mix.rs:62:18 | LL | cfg!(any(aa, bb)); | ^^ + | + = help: to expect this configuration use `--check-cfg=cfg(bb)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:65:20 @@ -129,12 +175,17 @@ LL | cfg!(any(unix, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:67:14 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:67:19 @@ -143,18 +194,26 @@ LL | cfg!(any(xxx, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:70:14 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:70:25 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(xxx)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:14 @@ -163,6 +222,8 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:33 @@ -171,6 +232,8 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:52 @@ -179,6 +242,8 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `foo` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 26 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.empty.stderr b/tests/ui/check-cfg/no-expected-values.empty.stderr index 0969d61dd40..ae55c95c0b1 100644 --- a/tests/ui/check-cfg/no-expected-values.empty.stderr +++ b/tests/ui/check-cfg/no-expected-values.empty.stderr @@ -7,6 +7,8 @@ LL | #[cfg(feature = "foo")] | help: remove the value | = note: no expected value for `feature` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` @@ -18,6 +20,8 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.mixed.stderr b/tests/ui/check-cfg/no-expected-values.mixed.stderr index 0969d61dd40..ae55c95c0b1 100644 --- a/tests/ui/check-cfg/no-expected-values.mixed.stderr +++ b/tests/ui/check-cfg/no-expected-values.mixed.stderr @@ -7,6 +7,8 @@ LL | #[cfg(feature = "foo")] | help: remove the value | = note: no expected value for `feature` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` @@ -18,6 +20,8 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.simple.stderr b/tests/ui/check-cfg/no-expected-values.simple.stderr index 0969d61dd40..ae55c95c0b1 100644 --- a/tests/ui/check-cfg/no-expected-values.simple.stderr +++ b/tests/ui/check-cfg/no-expected-values.simple.stderr @@ -7,6 +7,8 @@ LL | #[cfg(feature = "foo")] | help: remove the value | = note: no expected value for `feature` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` @@ -18,6 +20,8 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/order-independant.values_after.stderr b/tests/ui/check-cfg/order-independant.values_after.stderr index ed162fb5489..d1de26ba303 100644 --- a/tests/ui/check-cfg/order-independant.values_after.stderr +++ b/tests/ui/check-cfg/order-independant.values_after.stderr @@ -5,6 +5,8 @@ LL | #[cfg(a = "unk")] | ^^^^^^^^^ | = note: expected values for `a` are: (none), `b` + = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/order-independant.values_before.stderr b/tests/ui/check-cfg/order-independant.values_before.stderr index ed162fb5489..d1de26ba303 100644 --- a/tests/ui/check-cfg/order-independant.values_before.stderr +++ b/tests/ui/check-cfg/order-independant.values_before.stderr @@ -5,6 +5,8 @@ LL | #[cfg(a = "unk")] | ^^^^^^^^^ | = note: expected values for `a` are: (none), `b` + = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/stmt-no-ice.stderr b/tests/ui/check-cfg/stmt-no-ice.stderr index c2483fe4a06..112367606dc 100644 --- a/tests/ui/check-cfg/stmt-no-ice.stderr +++ b/tests/ui/check-cfg/stmt-no-ice.stderr @@ -5,6 +5,8 @@ LL | #[cfg(crossbeam_loom)] | ^^^^^^^^^^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(crossbeam_loom)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/unexpected-cfg-name.stderr b/tests/ui/check-cfg/unexpected-cfg-name.stderr index 0874ccfc461..8748b324fb6 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-name.stderr @@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `widnows` LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` | + = help: to expect this configuration use `--check-cfg=cfg(widnows)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr b/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr deleted file mode 100644 index 2855aa75966..00000000000 --- a/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr +++ /dev/null @@ -1,21 +0,0 @@ -warning: unexpected `cfg` condition value: `sedre` - --> $DIR/unexpected-cfg-value.rs:9:7 - | -LL | #[cfg(feature = "sedre")] - | ^^^^^^^^^^------- - | | - | help: there is a expected value with a similar name: `"serde"` - | - = note: expected values for `feature` are: `full`, `serde` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition value: `rand` - --> $DIR/unexpected-cfg-value.rs:16:7 - | -LL | #[cfg(feature = "rand")] - | ^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: `full`, `serde` - -warning: 2 warnings emitted - diff --git a/tests/ui/check-cfg/unexpected-cfg-value.stderr b/tests/ui/check-cfg/unexpected-cfg-value.stderr index 31c473a08cb..e5435d37670 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-value.stderr @@ -7,6 +7,8 @@ LL | #[cfg(feature = "sedre")] | help: there is a expected value with a similar name: `"serde"` | = note: expected values for `feature` are: `full`, `serde` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("sedre"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `rand` @@ -16,6 +18,8 @@ LL | #[cfg(feature = "rand")] | ^^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `full`, `serde` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("rand"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/well-known-names.stderr b/tests/ui/check-cfg/well-known-names.stderr index 6040663074d..763ba4646c3 100644 --- a/tests/ui/check-cfg/well-known-names.stderr +++ b/tests/ui/check-cfg/well-known-names.stderr @@ -4,6 +4,8 @@ warning: unexpected `cfg` condition name: `target_oz` LL | #[cfg(target_oz = "linux")] | ^^^^^^^^^^^^^^^^^^^ | + = help: to expect this configuration use `--check-cfg=cfg(target_oz, values("linux"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default help: there is a config with a similar name and value | @@ -17,18 +19,26 @@ LL | #[cfg(features = "foo")] | ^^^^^^^^^^^^^^^^ | = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(features, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` --> $DIR/well-known-names.rs:17:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `uniw` --> $DIR/well-known-names.rs:21:7 | LL | #[cfg(uniw)] | ^^^^ help: there is a config with a similar name: `unix` + | + = help: to expect this configuration use `--check-cfg=cfg(uniw)` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.rs b/tests/ui/check-cfg/well-known-values.rs index 39a470c202f..21268bf10d5 100644 --- a/tests/ui/check-cfg/well-known-values.rs +++ b/tests/ui/check-cfg/well-known-values.rs @@ -51,7 +51,8 @@ //~^ WARN unexpected `cfg` condition value target_family = "_UNEXPECTED_VALUE", //~^ WARN unexpected `cfg` condition value - target_feature = "_UNEXPECTED_VALUE", // currently *any* values are "expected" + target_feature = "_UNEXPECTED_VALUE", + //~^ WARN unexpected `cfg` condition value target_has_atomic = "_UNEXPECTED_VALUE", //~^ WARN unexpected `cfg` condition value target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", @@ -90,6 +91,9 @@ fn target_os_linux_misspell() {} #[cfg(target_os = "linux")] fn target_os_linux() {} +#[cfg(target_feature = "crt-static")] // pure rustc feature +fn target_feature() {} + #[cfg(target_has_atomic = "8")] fn target_has_atomic_8() {} diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index a6b9c75a142..4f708e62cd3 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -7,6 +7,8 @@ LL | debug_assertions = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `debug_assertions` + = help: to expect this configuration use `--check-cfg=cfg(debug_assertions, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -18,6 +20,8 @@ LL | doc = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `doc` + = help: to expect this configuration use `--check-cfg=cfg(doc, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:30:5 @@ -28,6 +32,8 @@ LL | doctest = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `doctest` + = help: to expect this configuration use `--check-cfg=cfg(doctest, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:32:5 @@ -38,6 +44,8 @@ LL | miri = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `miri` + = help: to expect this configuration use `--check-cfg=cfg(miri, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:34:5 @@ -48,6 +56,8 @@ LL | overflow_checks = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `overflow_checks` + = help: to expect this configuration use `--check-cfg=cfg(overflow_checks, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:36:5 @@ -56,6 +66,8 @@ LL | panic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `panic` are: `abort`, `unwind` + = help: to expect this configuration use `--check-cfg=cfg(panic, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:38:5 @@ -66,6 +78,8 @@ LL | proc_macro = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `proc_macro` + = help: to expect this configuration use `--check-cfg=cfg(proc_macro, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:40:5 @@ -74,6 +88,8 @@ LL | relocation_model = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `relocation_model` are: `dynamic-no-pic`, `pic`, `pie`, `ropi`, `ropi-rwpi`, `rwpi`, `static` + = help: to expect this configuration use `--check-cfg=cfg(relocation_model, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:42:5 @@ -82,6 +98,8 @@ LL | sanitize = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `sanitize` are: `address`, `cfi`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread` + = help: to expect this configuration use `--check-cfg=cfg(sanitize, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:44:5 @@ -90,6 +108,8 @@ LL | target_abi = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_abi` are: ``, `abi64`, `abiv2`, `abiv2hf`, `eabi`, `eabihf`, `elf`, `fortanix`, `ilp32`, `llvm`, `macabi`, `sim`, `softfloat`, `spe`, `uwp`, `vec-extabi`, `x32` + = help: to expect this configuration use `--check-cfg=cfg(target_abi, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:46:5 @@ -98,6 +118,8 @@ LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` + = help: to expect this configuration use `--check-cfg=cfg(target_arch, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:48:5 @@ -106,6 +128,8 @@ LL | target_endian = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_endian` are: `big`, `little` + = help: to expect this configuration use `--check-cfg=cfg(target_endian, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:50:5 @@ -114,6 +138,8 @@ LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_env` are: ``, `eabihf`, `gnu`, `gnueabihf`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `psx`, `relibc`, `sgx`, `uclibc` + = help: to expect this configuration use `--check-cfg=cfg(target_env, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:52:5 @@ -122,49 +148,71 @@ LL | target_family = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_family` are: `unix`, `wasm`, `windows` + = help: to expect this configuration use `--check-cfg=cfg(target_family, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:55:5 + --> $DIR/well-known-values.rs:54:5 + | +LL | target_feature = "_UNEXPECTED_VALUE", + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt` + = help: to expect this configuration use `--check-cfg=cfg(target_feature, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + +warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` + --> $DIR/well-known-values.rs:56:5 | LL | target_has_atomic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` + = help: to expect this configuration use `--check-cfg=cfg(target_has_atomic, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:57:5 + --> $DIR/well-known-values.rs:58:5 | LL | target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic_equal_alignment` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` + = help: to expect this configuration use `--check-cfg=cfg(target_has_atomic_equal_alignment, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:59:5 + --> $DIR/well-known-values.rs:60:5 | LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic_load_store` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` + = help: to expect this configuration use `--check-cfg=cfg(target_has_atomic_load_store, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:61:5 + --> $DIR/well-known-values.rs:62:5 | LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` + = help: to expect this configuration use `--check-cfg=cfg(target_os, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:63:5 + --> $DIR/well-known-values.rs:64:5 | LL | target_pointer_width = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_pointer_width` are: `16`, `32`, `64` + = help: to expect this configuration use `--check-cfg=cfg(target_pointer_width, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:65:5 + --> $DIR/well-known-values.rs:66:5 | LL | target_thread_local = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^---------------------- @@ -172,17 +220,21 @@ LL | target_thread_local = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `target_thread_local` + = help: to expect this configuration use `--check-cfg=cfg(target_thread_local, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:67:5 + --> $DIR/well-known-values.rs:68:5 | LL | target_vendor = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `nintendo`, `nvidia`, `pc`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, `wrs` + = help: to expect this configuration use `--check-cfg=cfg(target_vendor, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:69:5 + --> $DIR/well-known-values.rs:70:5 | LL | test = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -190,9 +242,11 @@ LL | test = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `test` + = help: to expect this configuration use `--check-cfg=cfg(test, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:71:5 + --> $DIR/well-known-values.rs:72:5 | LL | unix = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -200,9 +254,11 @@ LL | unix = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `unix` + = help: to expect this configuration use `--check-cfg=cfg(unix, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:73:5 + --> $DIR/well-known-values.rs:74:5 | LL | windows = "_UNEXPECTED_VALUE", | ^^^^^^^---------------------- @@ -210,9 +266,11 @@ LL | windows = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `windows` + = help: to expect this configuration use `--check-cfg=cfg(windows, values("_UNEXPECTED_VALUE"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `linuz` - --> $DIR/well-known-values.rs:79:7 + --> $DIR/well-known-values.rs:80:7 | LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | ^^^^^^^^^^^^------- @@ -220,6 +278,8 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | help: there is a expected value with a similar name: `"linux"` | = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` + = help: to expect this configuration use `--check-cfg=cfg(target_os, values("linuz"))` + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration -warning: 25 warnings emitted +warning: 26 warnings emitted diff --git a/tests/ui/closures/infer-signature-from-impl.rs b/tests/ui/closures/infer-signature-from-impl.rs index 6e8c94177bf..8b18e4ef9e7 100644 --- a/tests/ui/closures/infer-signature-from-impl.rs +++ b/tests/ui/closures/infer-signature-from-impl.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[next] known-bug: trait-system-refactor-initiative#71 //[current] check-pass diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs index 2c3ef4fd3f7..94a7ecbe11f 100644 --- a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs +++ b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even // though no impls are found. diff --git a/tests/ui/coherence/coherence-overlap-downstream.rs b/tests/ui/coherence/coherence-overlap-downstream.rs index a4e559604a0..171b2a32fc5 100644 --- a/tests/ui/coherence/coherence-overlap-downstream.rs +++ b/tests/ui/coherence/coherence-overlap-downstream.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even // though no impls are found. diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs index a7c90a6b8c8..6f5cc980491 100644 --- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs +++ b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // Tests that we consider `Box<U>: !Sugar` to be ambiguous, even // though we see no impl of `Sugar` for `Box`. Therefore, an overlap diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.rs b/tests/ui/coherence/coherence-overlap-issue-23516.rs index c846d39716b..4daaed4366f 100644 --- a/tests/ui/coherence/coherence-overlap-issue-23516.rs +++ b/tests/ui/coherence/coherence-overlap-issue-23516.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // Tests that we consider `Box<U>: !Sugar` to be ambiguous, even // though we see no impl of `Sugar` for `Box`. Therefore, an overlap diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs index 743e80d3f18..0f785b4e5f6 100644 --- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs +++ b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver struct S; diff --git a/tests/ui/coherence/normalize-for-errors.rs b/tests/ui/coherence/normalize-for-errors.rs index 367d34251ae..30723518bce 100644 --- a/tests/ui/coherence/normalize-for-errors.rs +++ b/tests/ui/coherence/normalize-for-errors.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver struct MyType; trait MyTrait<S> {} diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index 69f541cba05..f64e8b39798 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -1,11 +1,11 @@ -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index c2c951af0db..8e852ec796e 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,11 +1,11 @@ -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) -WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }) error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.rs b/tests/ui/coherence/occurs-check/associated-type.rs index 909551f65be..227b6684785 100644 --- a/tests/ui/coherence/occurs-check/associated-type.rs +++ b/tests/ui/coherence/occurs-check/associated-type.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // A regression test for #105787 diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs index 9d31a3dc82d..2fa9dcebfde 100644 --- a/tests/ui/coherence/occurs-check/opaques.rs +++ b/tests/ui/coherence/occurs-check/opaques.rs @@ -1,5 +1,5 @@ //revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // A regression test for #105787 diff --git a/tests/ui/coinduction/canonicalization-rerun.rs b/tests/ui/coinduction/canonicalization-rerun.rs index c68895fc4e6..bbd8d802630 100644 --- a/tests/ui/coinduction/canonicalization-rerun.rs +++ b/tests/ui/coinduction/canonicalization-rerun.rs @@ -1,6 +1,6 @@ // check-pass // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // If we use canonical goals during trait solving we have to reevaluate // the root goal of a cycle until we hit a fixpoint. diff --git a/tests/ui/const-generics/defaults/default-param-wf-concrete.rs b/tests/ui/const-generics/defaults/default-param-wf-concrete.rs index 09a00dd8e70..aa3307b92e4 100644 --- a/tests/ui/const-generics/defaults/default-param-wf-concrete.rs +++ b/tests/ui/const-generics/defaults/default-param-wf-concrete.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver struct Foo<const N: u8 = { 255 + 1 }>; //~^ ERROR evaluation of constant value failed diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs new file mode 100644 index 00000000000..c6960fa7259 --- /dev/null +++ b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs @@ -0,0 +1,43 @@ +// Test that we can handle unsized types with an extern type tail part. +// Regression test for issue #91827. + +#![feature(extern_types)] + +use std::ptr::addr_of; + +extern "C" { + type Opaque; +} + +struct Newtype(Opaque); + +struct S { + i: i32, + j: i32, + a: Newtype, +} + +const NEWTYPE: () = unsafe { + let buf = [0i32; 4]; + let x: &Newtype = &*(&buf as *const _ as *const Newtype); + + // Projecting to the newtype works, because it is always at offset 0. + let field = &x.0; +}; + +const OFFSET: () = unsafe { + let buf = [0i32; 4]; + let x: &S = &*(&buf as *const _ as *const S); + + // Accessing sized fields is perfectly fine, even at non-zero offsets. + let field = &x.i; + let field = &x.j; + + // This needs to compute the field offset, but we don't know the type's alignment, so this + // fails. + let field = &x.a; + //~^ ERROR: evaluation of constant value failed + //~| does not have a known offset +}; + +fn main() {} diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr new file mode 100644 index 00000000000..99f37fedd3d --- /dev/null +++ b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/issue-91827-extern-types-field-offset.rs:38:17 + | +LL | let field = &x.a; + | ^^^^ `extern type` does not have a known offset + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types.rs b/tests/ui/consts/const-eval/issue-91827-extern-types.rs deleted file mode 100644 index c9aaa6e5587..00000000000 --- a/tests/ui/consts/const-eval/issue-91827-extern-types.rs +++ /dev/null @@ -1,59 +0,0 @@ -// run-pass -// -// Test that we can handle unsized types with an extern type tail part. -// Regression test for issue #91827. - -#![feature(extern_types)] - -use std::ptr::addr_of; - -extern "C" { - type Opaque; -} - -unsafe impl Sync for Opaque {} - -#[repr(C)] -pub struct List<T> { - len: usize, - data: [T; 0], - tail: Opaque, -} - -#[repr(C)] -pub struct ListImpl<T, const N: usize> { - len: usize, - data: [T; N], -} - -impl<T> List<T> { - const fn as_slice(&self) -> &[T] { - unsafe { - let ptr = addr_of!(self.tail) as *const T; - std::slice::from_raw_parts(ptr, self.len) - } - } -} - -impl<T, const N: usize> ListImpl<T, N> { - const fn as_list(&self) -> &List<T> { - unsafe { std::mem::transmute(self) } - } -} - -pub static A: ListImpl<u128, 3> = ListImpl { - len: 3, - data: [5, 6, 7], -}; -pub static A_REF: &'static List<u128> = A.as_list(); -pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list()); - -const fn tail_offset<T>(list: &List<T>) -> isize { - unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) } -} - -fn main() { - assert_eq!(A_REF.as_slice(), &[5, 6, 7]); - // Check that interpreter and code generation agree about the position of the tail field. - assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF)); -} diff --git a/tests/ui/consts/const-len-underflow-separate-spans.rs b/tests/ui/consts/const-len-underflow-separate-spans.rs index 55704b64154..bd37be21576 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.rs +++ b/tests/ui/consts/const-len-underflow-separate-spans.rs @@ -3,7 +3,7 @@ // overall context for what caused the evaluation. // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver const ONE: usize = 1; const TWO: usize = 2; diff --git a/tests/ui/coroutine/async-gen-deduce-yield.rs b/tests/ui/coroutine/async-gen-deduce-yield.rs new file mode 100644 index 00000000000..9ccc8ee41f6 --- /dev/null +++ b/tests/ui/coroutine/async-gen-deduce-yield.rs @@ -0,0 +1,14 @@ +// compile-flags: --edition 2024 -Zunstable-options +// check-pass + +#![feature(async_iterator, gen_blocks)] + +use std::async_iter::AsyncIterator; + +fn deduce() -> impl AsyncIterator<Item = ()> { + async gen { + yield Default::default(); + } +} + +fn main() {} diff --git a/tests/ui/coroutine/async_gen_fn_iter.rs b/tests/ui/coroutine/async_gen_fn_iter.rs index 4fa29e1095a..ec6464d0048 100644 --- a/tests/ui/coroutine/async_gen_fn_iter.rs +++ b/tests/ui/coroutine/async_gen_fn_iter.rs @@ -3,6 +3,7 @@ // run-pass #![feature(gen_blocks, async_iterator)] +#![feature(noop_waker)] // make sure that a ridiculously simple async gen fn works as an iterator. @@ -42,7 +43,7 @@ async fn async_main() { // ------------------------------------------------------------------------- // // Implementation Details Below... -use std::pin::Pin; +use std::pin::{Pin, pin}; use std::task::*; use std::async_iter::AsyncIterator; use std::future::Future; @@ -69,30 +70,15 @@ impl<'s, S: AsyncIterator> Future for Next<'s, S> where S: Unpin { } } -pub fn noop_waker() -> Waker { - let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE); - - // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld - unsafe { Waker::from_raw(raw) } -} - -const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); - -unsafe fn noop_clone(_p: *const ()) -> RawWaker { - RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE) -} - -unsafe fn noop(_p: *const ()) {} - fn main() { - let mut fut = async_main(); + let mut fut = pin!(async_main()); // Poll loop, just to test the future... - let waker = noop_waker(); + let waker = Waker::noop(); let ctx = &mut Context::from_waker(&waker); loop { - match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } { + match fut.as_mut().poll(ctx) { Poll::Pending => {} Poll::Ready(()) => break, } diff --git a/tests/ui/coroutine/clone-rpit.rs b/tests/ui/coroutine/clone-rpit.rs index e0061e1c6bb..cbd28f88fcb 100644 --- a/tests/ui/coroutine/clone-rpit.rs +++ b/tests/ui/coroutine/clone-rpit.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass #![feature(coroutines, coroutine_trait, coroutine_clone)] diff --git a/tests/ui/coroutine/gen_block_is_iter.rs b/tests/ui/coroutine/gen_block_is_iter.rs index 92625cf7c28..d43eef4a18d 100644 --- a/tests/ui/coroutine/gen_block_is_iter.rs +++ b/tests/ui/coroutine/gen_block_is_iter.rs @@ -1,6 +1,6 @@ // revisions: next old //compile-flags: --edition 2024 -Zunstable-options -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/gen_block_iterate.rs b/tests/ui/coroutine/gen_block_iterate.rs index 18e1bb88772..8e72b00d99d 100644 --- a/tests/ui/coroutine/gen_block_iterate.rs +++ b/tests/ui/coroutine/gen_block_iterate.rs @@ -1,6 +1,6 @@ // revisions: next old //compile-flags: --edition 2024 -Zunstable-options -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // run-pass #![feature(gen_blocks)] diff --git a/tests/ui/coroutine/non-static-is-unpin.rs b/tests/ui/coroutine/non-static-is-unpin.rs index d77fe659f08..238e49bbfdf 100644 --- a/tests/ui/coroutine/non-static-is-unpin.rs +++ b/tests/ui/coroutine/non-static-is-unpin.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // run-pass #![feature(coroutines, coroutine_trait)] diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs index 6ce78046dcc..f27183d11db 100644 --- a/tests/ui/coroutine/static-not-unpin.rs +++ b/tests/ui/coroutine/static-not-unpin.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(coroutines)] diff --git a/tests/ui/coroutine/uninhabited-field.rs b/tests/ui/coroutine/uninhabited-field.rs new file mode 100644 index 00000000000..d9570c2fed8 --- /dev/null +++ b/tests/ui/coroutine/uninhabited-field.rs @@ -0,0 +1,37 @@ +// Test that uninhabited saved local doesn't make the entire variant uninhabited. +// run-pass +#![allow(unused)] +#![feature(assert_matches)] +#![feature(coroutine_trait)] +#![feature(coroutines)] +#![feature(never_type)] +use std::assert_matches::assert_matches; +use std::ops::Coroutine; +use std::ops::CoroutineState; +use std::pin::Pin; + +fn conjure<T>() -> T { loop {} } + +fn run<T>(x: bool, y: bool) { + let mut c = || { + if x { + let a : T; + if y { + a = conjure::<T>(); + } + yield (); + } else { + let a : T; + if y { + a = conjure::<T>(); + } + yield (); + } + }; + assert_matches!(Pin::new(&mut c).resume(()), CoroutineState::Yielded(())); + assert_matches!(Pin::new(&mut c).resume(()), CoroutineState::Complete(())); +} + +fn main() { + run::<!>(false, false); +} diff --git a/tests/ui/destructuring-assignment/bad-expr-lhs.rs b/tests/ui/destructuring-assignment/bad-expr-lhs.rs index 53794783a3c..90e1ac19943 100644 --- a/tests/ui/destructuring-assignment/bad-expr-lhs.rs +++ b/tests/ui/destructuring-assignment/bad-expr-lhs.rs @@ -4,6 +4,4 @@ fn main() { (1, 2) = (3, 4); //~^ ERROR invalid left-hand side of assignment //~| ERROR invalid left-hand side of assignment - - None = Some(3); //~ ERROR invalid left-hand side of assignment } diff --git a/tests/ui/destructuring-assignment/bad-expr-lhs.stderr b/tests/ui/destructuring-assignment/bad-expr-lhs.stderr index d2986747480..2916d6d9f11 100644 --- a/tests/ui/destructuring-assignment/bad-expr-lhs.stderr +++ b/tests/ui/destructuring-assignment/bad-expr-lhs.stderr @@ -30,15 +30,7 @@ LL | (1, 2) = (3, 4); | | | cannot assign to this expression -error[E0070]: invalid left-hand side of assignment - --> $DIR/bad-expr-lhs.rs:8:10 - | -LL | None = Some(3); - | ---- ^ - | | - | cannot assign to this expression - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0067, E0070. For more information about an error, try `rustc --explain E0067`. diff --git a/tests/ui/destructuring-assignment/non-exhaustive-destructure.rs b/tests/ui/destructuring-assignment/non-exhaustive-destructure.rs new file mode 100644 index 00000000000..39939f2bad6 --- /dev/null +++ b/tests/ui/destructuring-assignment/non-exhaustive-destructure.rs @@ -0,0 +1,4 @@ +fn main() { + None = Some(3); + //~^ ERROR refutable pattern in local binding +} diff --git a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr new file mode 100644 index 00000000000..b9ceaa4af7b --- /dev/null +++ b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr @@ -0,0 +1,17 @@ +error[E0005]: refutable pattern in local binding + --> $DIR/non-exhaustive-destructure.rs:2:5 + | +LL | None = Some(3); + | ^^^^ pattern `Some(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `Option<i32>` +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if None = Some(3) { todo!() }; + | ++ +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0005`. diff --git a/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs b/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs index 8da7f90c524..f82e029983b 100644 --- a/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs +++ b/tests/ui/destructuring-assignment/struct-or-enum-variant-path.rs @@ -11,17 +11,22 @@ type A = E; fn main() { let mut a; + S = S; (S, a) = (S, ()); + E::V = E::V; (E::V, a) = (E::V, ()); + <E>::V = E::V; (<E>::V, a) = (E::V, ()); + A::V = A::V; (A::V, a) = (E::V, ()); } impl S { fn check() { let a; + Self = S; (Self, a) = (S, ()); } } @@ -29,6 +34,7 @@ impl S { impl E { fn check() { let a; + Self::V = E::V; (Self::V, a) = (E::V, ()); } } diff --git a/tests/ui/diagnostic-width/long-E0308.stderr b/tests/ui/diagnostic-width/long-E0308.stderr index 20b018b9f77..1e5966a1c5d 100644 --- a/tests/ui/diagnostic-width/long-E0308.stderr +++ b/tests/ui/diagnostic-width/long-E0308.stderr @@ -19,9 +19,8 @@ LL | | )))))))))))))))))))))))))))))); | |__________________________________^ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>` | = note: expected struct `Atype<Btype<..., ...>, ...>` - the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' found enum `Result<Result<..., ...>, ...>` - the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' error[E0308]: mismatched types --> $DIR/long-E0308.rs:57:26 @@ -35,9 +34,8 @@ LL | | )))))))))))))))))))))))); | |____________________________^ expected `Option<Result<..., ...>>`, found `Result<Result<..., ...>, ...>` | = note: expected enum `Option<Result<..., ...>>` - the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' found enum `Result<Result<..., ...>, ...>` - the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' error[E0308]: mismatched types --> $DIR/long-E0308.rs:88:9 @@ -55,8 +53,8 @@ LL | | > = (); | expected due to this | = note: expected struct `Atype<Btype<..., ...>, ...>` - the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' found unit type `()` + = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' error[E0308]: mismatched types --> $DIR/long-E0308.rs:91:17 @@ -73,7 +71,7 @@ LL | | )))))))))))))))))))))))); | = note: expected unit type `()` found enum `Result<Result<..., ...>, ...>` - the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' + = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt' error: aborting due to 4 previous errors diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr index 592640a884c..3b5998df353 100644 --- a/tests/ui/duplicate_entry_error.stderr +++ b/tests/ui/duplicate_entry_error.stderr @@ -1,8 +1,11 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/duplicate_entry_error.rs:11:1 | -LL | fn panic_impl(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic_impl(info: &PanicInfo) -> ! { +LL | | +LL | | loop {} +LL | | } + | |_^ | = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib diff --git a/tests/ui/dyn-star/box.rs b/tests/ui/dyn-star/box.rs index 87c8356a174..8b2f46bd1b2 100644 --- a/tests/ui/dyn-star/box.rs +++ b/tests/ui/dyn-star/box.rs @@ -1,7 +1,7 @@ // run-pass // revisions: current next //[current] compile-flags: -C opt-level=0 -//[next] compile-flags: -Ztrait-solver=next -C opt-level=0 +//[next] compile-flags: -Znext-solver -C opt-level=0 #![feature(dyn_star)] #![allow(incomplete_features)] diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs index 9846f871424..dffe6ae8a36 100644 --- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs +++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(dyn_star)] #![allow(incomplete_features)] diff --git a/tests/ui/dyn-star/dispatch-on-pin-mut.rs b/tests/ui/dyn-star/dispatch-on-pin-mut.rs index 5774c8b2a67..c4ae279e6c1 100644 --- a/tests/ui/dyn-star/dispatch-on-pin-mut.rs +++ b/tests/ui/dyn-star/dispatch-on-pin-mut.rs @@ -4,6 +4,7 @@ #![feature(dyn_star)] //~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes +#![feature(noop_waker)] use std::future::Future; @@ -18,33 +19,18 @@ async fn async_main() { // ------------------------------------------------------------------------- // // Implementation Details Below... -use std::pin::Pin; use std::task::*; - -pub fn noop_waker() -> Waker { - let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE); - - // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld - unsafe { Waker::from_raw(raw) } -} - -const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); - -unsafe fn noop_clone(_p: *const ()) -> RawWaker { - RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE) -} - -unsafe fn noop(_p: *const ()) {} +use std::pin::pin; fn main() { - let mut fut = async_main(); + let mut fut = pin!(async_main()); // Poll loop, just to test the future... - let waker = noop_waker(); + let waker = Waker::noop(); let ctx = &mut Context::from_waker(&waker); loop { - match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } { + match fut.as_mut().poll(ctx) { Poll::Pending => {} Poll::Ready(()) => break, } diff --git a/tests/ui/dyn-star/param-env-region-infer.rs b/tests/ui/dyn-star/param-env-region-infer.rs index 50dec94d25b..1e331777765 100644 --- a/tests/ui/dyn-star/param-env-region-infer.rs +++ b/tests/ui/dyn-star/param-env-region-infer.rs @@ -1,7 +1,7 @@ // revisions: current // incremental -// FIXME(-Ztrait-solver=next): THis currently results in unstable query results: +// FIXME(-Znext-solver): THis currently results in unstable query results: // `normalizes-to(opaque, opaque)` changes from `Maybe(Ambiguous)` to `Maybe(Overflow)` // once the hidden type of the opaque is already defined to be itself. diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr index 816ba2d569b..dbea7e6d27f 100644 --- a/tests/ui/error-codes/E0152.stderr +++ b/tests/ui/error-codes/E0152.stderr @@ -2,7 +2,7 @@ error[E0152]: found duplicate lang item `owned_box` --> $DIR/E0152.rs:5:1 | LL | struct Foo<T>(T); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `alloc` (which `std` depends on) = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib diff --git a/tests/ui/error-codes/E0264.stderr b/tests/ui/error-codes/E0264.stderr index 14a4ffbe316..3503fb229e4 100644 --- a/tests/ui/error-codes/E0264.stderr +++ b/tests/ui/error-codes/E0264.stderr @@ -2,7 +2,7 @@ error[E0264]: unknown external lang item: `cake` --> $DIR/E0264.rs:5:5 | LL | fn cake(); - | ^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs index e9afc756726..d87916198c5 100644 --- a/tests/ui/error-codes/E0476.rs +++ b/tests/ui/error-codes/E0476.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next-coherence +//[next] compile-flags: -Znext-solver=coherence #![feature(coerce_unsized)] #![feature(unsize)] diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs new file mode 100644 index 00000000000..bfbc1e9bffa --- /dev/null +++ b/tests/ui/extern/extern-types-field-offset.rs @@ -0,0 +1,33 @@ +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 +// normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +#![feature(extern_types)] + +extern "C" { + type Opaque; +} + +struct Newtype(Opaque); + +struct S { + i: i32, + j: i32, + a: Newtype, +} + +fn main() { + let buf = [0i32; 4]; + + let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) }; + // Projecting to the newtype works, because it is always at offset 0. + let field = &x.0; + + let x: &S = unsafe { &*(&buf as *const _ as *const S) }; + // Accessing sized fields is perfectly fine, even at non-zero offsets. + let field = &x.i; + let field = &x.j; + // This needs to compute the field offset, but we don't know the type's alignment, + // so this panics. + let field = &x.a; +} diff --git a/tests/ui/extern/extern-types-field-offset.run.stderr b/tests/ui/extern/extern-types-field-offset.run.stderr new file mode 100644 index 00000000000..1b04b860db5 --- /dev/null +++ b/tests/ui/extern/extern-types-field-offset.run.stderr @@ -0,0 +1,4 @@ +thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL: +attempted to compute the size or alignment of extern type `Opaque` +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +thread caused non-unwinding panic. aborting. diff --git a/tests/ui/extern/extern-types-size_of_val.align.run.stderr b/tests/ui/extern/extern-types-size_of_val.align.run.stderr new file mode 100644 index 00000000000..20c4d8785e8 --- /dev/null +++ b/tests/ui/extern/extern-types-size_of_val.align.run.stderr @@ -0,0 +1,4 @@ +thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL: +attempted to compute the size or alignment of extern type `A` +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +thread caused non-unwinding panic. aborting. diff --git a/tests/ui/extern/extern-types-size_of_val.rs b/tests/ui/extern/extern-types-size_of_val.rs index 3b02ea28eaa..4c4de873b7f 100644 --- a/tests/ui/extern/extern-types-size_of_val.rs +++ b/tests/ui/extern/extern-types-size_of_val.rs @@ -1,4 +1,8 @@ -// run-pass +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 +// normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +// revisions: size align #![feature(extern_types)] use std::mem::{align_of_val, size_of_val}; @@ -10,6 +14,10 @@ extern "C" { fn main() { let x: &A = unsafe { &*(1usize as *const A) }; - assert_eq!(size_of_val(x), 0); - assert_eq!(align_of_val(x), 1); + // These don't have a dynamic size, so this should panic. + if cfg!(size) { + assert_eq!(size_of_val(x), 0); + } else { + assert_eq!(align_of_val(x), 1); + } } diff --git a/tests/ui/extern/extern-types-size_of_val.size.run.stderr b/tests/ui/extern/extern-types-size_of_val.size.run.stderr new file mode 100644 index 00000000000..20c4d8785e8 --- /dev/null +++ b/tests/ui/extern/extern-types-size_of_val.size.run.stderr @@ -0,0 +1,4 @@ +thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL: +attempted to compute the size or alignment of extern type `A` +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +thread caused non-unwinding panic. aborting. diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr index 1462c41e957..c582ca7ba3d 100644 --- a/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.e2024.stderr @@ -2,16 +2,34 @@ error[E0658]: gen blocks are experimental --> $DIR/feature-gate-gen_blocks.rs:5:5 | LL | gen {}; - | ^^^^^ + | ^^^ | = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information = help: add `#![feature(gen_blocks)]` to the crate attributes to enable error[E0658]: gen blocks are experimental - --> $DIR/feature-gate-gen_blocks.rs:13:5 + --> $DIR/feature-gate-gen_blocks.rs:12:5 + | +LL | async gen {}; + | ^^^^^^^^^ + | + = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information + = help: add `#![feature(gen_blocks)]` to the crate attributes to enable + +error[E0658]: gen blocks are experimental + --> $DIR/feature-gate-gen_blocks.rs:22:5 | LL | gen {}; - | ^^^^^ + | ^^^ + | + = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information + = help: add `#![feature(gen_blocks)]` to the crate attributes to enable + +error[E0658]: gen blocks are experimental + --> $DIR/feature-gate-gen_blocks.rs:25:5 + | +LL | async gen {}; + | ^^^^^^^^^ | = note: see issue #117078 <https://github.com/rust-lang/rust/issues/117078> for more information = help: add `#![feature(gen_blocks)]` to the crate attributes to enable @@ -22,7 +40,13 @@ error[E0282]: type annotations needed LL | gen {}; | ^^ cannot infer type -error: aborting due to 3 previous errors +error[E0282]: type annotations needed + --> $DIR/feature-gate-gen_blocks.rs:12:15 + | +LL | async gen {}; + | ^^ cannot infer type + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0282, E0658. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr index 56f8309a69f..b4b37f0e638 100644 --- a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr @@ -1,9 +1,21 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen` + --> $DIR/feature-gate-gen_blocks.rs:12:11 + | +LL | async gen {}; + | ^^^ expected one of 8 possible tokens + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen` + --> $DIR/feature-gate-gen_blocks.rs:25:11 + | +LL | async gen {}; + | ^^^ expected one of 8 possible tokens + error[E0422]: cannot find struct, variant or union type `gen` in this scope --> $DIR/feature-gate-gen_blocks.rs:5:5 | LL | gen {}; | ^^^ not found in this scope -error: aborting due to 1 previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0422`. diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.rs b/tests/ui/feature-gates/feature-gate-gen_blocks.rs index e2e1574a36a..ff9a0b139c0 100644 --- a/tests/ui/feature-gates/feature-gate-gen_blocks.rs +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.rs @@ -1,15 +1,28 @@ // revisions: e2024 none //[e2024] compile-flags: --edition 2024 -Zunstable-options -fn main() { +fn test_gen() { gen {}; //[none]~^ ERROR: cannot find struct, variant or union type `gen` //[e2024]~^^ ERROR: gen blocks are experimental //[e2024]~| ERROR: type annotations needed } +fn test_async_gen() { + async gen {}; + //[none]~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen` + //[e2024]~^^ ERROR: gen blocks are experimental + //[e2024]~| ERROR: type annotations needed +} + +fn main() {} + #[cfg(FALSE)] fn foo() { gen {}; //[e2024]~^ ERROR: gen blocks are experimental + + async gen {}; + //[e2024]~^ ERROR: gen blocks are experimental + //[none]~^^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `gen` } diff --git a/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr b/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr index d2ad372dfbc..1b87ebd9f20 100644 --- a/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr @@ -95,7 +95,7 @@ LL | fn unsized_local() where Dst<dyn A>: Sized { | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `Dst<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` -note: required because it appears within the type `Dst<dyn A>` +note: required because it appears within the type `Dst<(dyn A + 'static)>` --> $DIR/feature-gate-trivial_bounds.rs:48:8 | LL | struct Dst<X: ?Sized> { diff --git a/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr index e3ebe6cdcb8..6c9c7941eb3 100644 --- a/tests/ui/fmt/send-sync.stderr +++ b/tests/ui/fmt/send-sync.stderr @@ -8,9 +8,9 @@ LL | send(format_args!("{:?}", c)); | = help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque` = note: required because it appears within the type `&core::fmt::rt::Opaque` -note: required because it appears within the type `Argument<'_>` +note: required because it appears within the type `core::fmt::rt::Argument<'_>` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL - = note: required because it appears within the type `[Argument<'_>]` + = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]` = note: required for `&[core::fmt::rt::Argument<'_>]` to implement `Send` note: required because it appears within the type `Arguments<'_>` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL @@ -30,10 +30,10 @@ LL | sync(format_args!("{:?}", c)); | = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque` = note: required because it appears within the type `&core::fmt::rt::Opaque` -note: required because it appears within the type `Argument<'_>` +note: required because it appears within the type `core::fmt::rt::Argument<'_>` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL - = note: required because it appears within the type `[Argument<'_>]` - = note: required because it appears within the type `&[Argument<'_>]` + = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]` + = note: required because it appears within the type `&[core::fmt::rt::Argument<'_>]` note: required because it appears within the type `Arguments<'_>` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL note: required by a bound in `sync` diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs index 50d4c3fddb5..8ae9494faf8 100644 --- a/tests/ui/for/issue-20605.rs +++ b/tests/ui/for/issue-20605.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) { for item in *things { *item = 0 } @@ -13,7 +13,7 @@ fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) { //[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed //[next]~| ERROR the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time //[next]~| ERROR type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced - // FIXME(-Ztrait-solver=next): these error messages are horrible and have to be + // FIXME(-Znext-solver): these error messages are horrible and have to be // improved before we stabilize the new solver. } diff --git a/tests/ui/function-pointer/unsized-ret.stderr b/tests/ui/function-pointer/unsized-ret.stderr index dcfec53eeb9..66116273ff4 100644 --- a/tests/ui/function-pointer/unsized-ret.stderr +++ b/tests/ui/function-pointer/unsized-ret.stderr @@ -19,7 +19,7 @@ LL | foo::<for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)` - = note: required because it appears within the type `fn(&()) -> dyn Display` + = note: required because it appears within the type `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)` note: required by a bound in `foo` --> $DIR/unsized-ret.rs:5:11 | diff --git a/tests/ui/generic-associated-types/issue-102114.rs b/tests/ui/generic-associated-types/issue-102114.rs index bb6622c0a5f..bb6369d7f8f 100644 --- a/tests/ui/generic-associated-types/issue-102114.rs +++ b/tests/ui/generic-associated-types/issue-102114.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver trait A { type B<'b>; diff --git a/tests/ui/higher-ranked/leak-check-in-selection.rs b/tests/ui/higher-ranked/leak-check-in-selection.rs index e8d6cff856c..5b36902ffdf 100644 --- a/tests/ui/higher-ranked/leak-check-in-selection.rs +++ b/tests/ui/higher-ranked/leak-check-in-selection.rs @@ -1,6 +1,6 @@ // run-pass // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![allow(coherence_leak_check)] trait Trait: Sized { diff --git a/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs index adb19c035bc..41f24dde01a 100644 --- a/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs +++ b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs @@ -1,5 +1,5 @@ // revisions: classic next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[next] check-pass fn ice() diff --git a/tests/ui/higher-ranked/trait-bounds/future.rs b/tests/ui/higher-ranked/trait-bounds/future.rs index 61d86a9cb23..baeb56e5d78 100644 --- a/tests/ui/higher-ranked/trait-bounds/future.rs +++ b/tests/ui/higher-ranked/trait-bounds/future.rs @@ -1,7 +1,7 @@ // ignore-tidy-linelength // edition:2021 // revisions: classic next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[next] check-pass //[classic] known-bug: #112347 //[classic] build-fail diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs index 49a1584d54e..027644a280b 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs +++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[old] check-pass //[next] known-bug: #109764 diff --git a/tests/ui/hygiene/cross-crate-define-and-use.rs b/tests/ui/hygiene/cross-crate-define-and-use.rs index 94f1adff626..62b1820235c 100644 --- a/tests/ui/hygiene/cross-crate-define-and-use.rs +++ b/tests/ui/hygiene/cross-crate-define-and-use.rs @@ -6,7 +6,6 @@ // check-pass // aux-build:use_by_macro.rs -#![feature(type_name_of_val)] extern crate use_by_macro; use use_by_macro::*; diff --git a/tests/ui/impl-trait/auto-trait-coherence.rs b/tests/ui/impl-trait/auto-trait-coherence.rs index a5cd01a87ff..e4226b20074 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.rs +++ b/tests/ui/impl-trait/auto-trait-coherence.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // Tests that type alias impls traits do not leak auto-traits for // the purposes of coherence checking diff --git a/tests/ui/impl-trait/autoderef.rs b/tests/ui/impl-trait/autoderef.rs index cd2cdd9e3b3..48ff8be6549 100644 --- a/tests/ui/impl-trait/autoderef.rs +++ b/tests/ui/impl-trait/autoderef.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass use std::path::Path; diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index ed9261d0de5..4a52f82540d 100644 --- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -16,7 +16,7 @@ LL | fn fuz() -> (usize, Trait) { (42, Struct) } | doesn't have a size known at compile-time | = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)` - = note: required because it appears within the type `(usize, dyn Trait)` + = note: required because it appears within the type `(usize, (dyn Trait + 'static))` = note: the return type of a function must have a statically known size error[E0308]: mismatched types @@ -37,7 +37,7 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } | doesn't have a size known at compile-time | = help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)` - = note: required because it appears within the type `(usize, dyn Trait)` + = note: required because it appears within the type `(usize, (dyn Trait + 'static))` = note: the return type of a function must have a statically known size error[E0746]: return type cannot have an unboxed trait object diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs index 698123a932d..b1f36fc247f 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs @@ -1,6 +1,6 @@ // revisions: current next // compile-flags: -Zverbose -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // normalize-stderr-test "DefId\([^\)]+\)" -> "DefId(..)" #![feature(rustc_attrs)] diff --git a/tests/ui/impl-trait/in-trait/object-safety-sized.rs b/tests/ui/impl-trait/in-trait/object-safety-sized.rs index 35afe80c97f..1a23493a94d 100644 --- a/tests/ui/impl-trait/in-trait/object-safety-sized.rs +++ b/tests/ui/impl-trait/in-trait/object-safety-sized.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver fn main() { diff --git a/tests/ui/impl-trait/in-trait/opaque-variances.rs b/tests/ui/impl-trait/in-trait/opaque-variances.rs index 60bfab0deb5..63e56051d1a 100644 --- a/tests/ui/impl-trait/in-trait/opaque-variances.rs +++ b/tests/ui/impl-trait/in-trait/opaque-variances.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver fn foo<'a: 'a>(x: &'a Vec<i32>) -> impl Sized { () diff --git a/tests/ui/impl-trait/issue-103181-1.rs b/tests/ui/impl-trait/issue-103181-1.rs index 5154abcd690..14c813cf00f 100644 --- a/tests/ui/impl-trait/issue-103181-1.rs +++ b/tests/ui/impl-trait/issue-103181-1.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // edition:2021 mod hyper { diff --git a/tests/ui/impl-trait/recursive-coroutine.rs b/tests/ui/impl-trait/recursive-coroutine.rs index f0bee4f120f..b82fe134a40 100644 --- a/tests/ui/impl-trait/recursive-coroutine.rs +++ b/tests/ui/impl-trait/recursive-coroutine.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(coroutines, coroutine_trait)] use std::ops::{Coroutine, CoroutineState}; diff --git a/tests/ui/impl-trait/reveal-during-codegen.rs b/tests/ui/impl-trait/reveal-during-codegen.rs index 11463772eb3..7b2ca9c33f6 100644 --- a/tests/ui/impl-trait/reveal-during-codegen.rs +++ b/tests/ui/impl-trait/reveal-during-codegen.rs @@ -1,6 +1,6 @@ // build-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver fn test() -> Option<impl Sized> { Some("") diff --git a/tests/ui/impl-trait/two_tait_defining_each_other.rs b/tests/ui/impl-trait/two_tait_defining_each_other.rs index b43a7cabd05..6a9e33500e5 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[next] check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs index 817de109fbe..8a79af19776 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(type_alias_impl_trait)] type A = impl Foo; //[current]~ ERROR unconstrained opaque type diff --git a/tests/ui/impl-trait/two_tait_defining_each_other3.rs b/tests/ui/impl-trait/two_tait_defining_each_other3.rs index 6fb9e6e7188..55def937f48 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other3.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other3.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[next] check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs index c177655c5ac..27c8f30ec32 100644 --- a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs +++ b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs @@ -1,5 +1,5 @@ // A test exploiting the bug behind #25860 except with -// implied trait bounds which currently don't exist without `-Ztrait-solver=chalk`. +// implied trait bounds which currently don't exist. use std::marker::PhantomData; struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) where diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs index 6ccbb5bb266..280856805e5 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs @@ -1,5 +1,3 @@ -#![deny(implied_bounds_entailment)] - trait Project { type Ty; } @@ -11,8 +9,7 @@ trait Trait { } impl Trait for () { fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { - //~^ ERROR impl method assumes more implied bounds than the corresponding trait method - //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements s } } diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr index 86b12cf8fa2..c8d1614a7f3 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr @@ -1,31 +1,28 @@ -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5 | LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9 - | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -Future incompatibility report: Future breakage diagnostic: -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31 +note: first, the lifetime cannot outlive the lifetime `'s` as defined here... + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12 | LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()` + | ^^ +note: ...so that the method type is compatible with trait + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9 +LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `fn(&'s _, ()) -> &'static _` + found `fn(&_, ()) -> &'static _` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the reference type `&'static &()` does not outlive the data it points at + --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5 | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs index d097bc16a22..7f3817b326a 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs @@ -1,5 +1,3 @@ -#![deny(implied_bounds_entailment)] - use std::cell::RefCell; pub struct MessageListeners<'a> { @@ -12,8 +10,7 @@ pub trait MessageListenersInterface { impl<'a> MessageListenersInterface for MessageListeners<'a> { fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { - //~^ ERROR impl method assumes more implied bounds than the corresponding trait method - //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements self } } diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr index a89645c128b..6a412eb5e4b 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr @@ -1,31 +1,32 @@ -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility.rs:14:35 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility.rs:1:9 +note: first, the lifetime cannot outlive the lifetime `'c` as defined here... + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -Future incompatibility report: Future breakage diagnostic: -error: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/impl-implied-bounds-compatibility.rs:14:35 +LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...so that the method type is compatible with trait + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `fn(&'c MessageListeners<'_>) -> &'c MessageListeners<'c>` + found `fn(&MessageListeners<'_>) -> &'a MessageListeners<'_>` +note: but, the lifetime must be valid for the lifetime `'a` as defined here... + --> $DIR/impl-implied-bounds-compatibility.rs:11:6 | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/impl-implied-bounds-compatibility.rs:1:9 +LL | impl<'a> MessageListenersInterface for MessageListeners<'a> { + | ^^ +note: ...so that the reference type `&'a MessageListeners<'_>` does not outlive the data it points at + --> $DIR/impl-implied-bounds-compatibility.rs:12:5 | -LL | #![deny(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/inference/issue-103587.stderr b/tests/ui/inference/issue-103587.stderr index b373fbfbb94..589cb7ea7b1 100644 --- a/tests/ui/inference/issue-103587.stderr +++ b/tests/ui/inference/issue-103587.stderr @@ -26,14 +26,10 @@ error[E0308]: mismatched types LL | if None = x { } | ^^^^^^^^ expected `bool`, found `()` | -help: you might have meant to use pattern matching +help: consider adding `let` | LL | if let None = x { } | +++ -help: you might have meant to compare for equality - | -LL | if None == x { } - | + error: aborting due to 3 previous errors diff --git a/tests/ui/inference/type-infer-generalize-ty-var.rs b/tests/ui/inference/type-infer-generalize-ty-var.rs index 8b4a8c32bb2..6bf3c61ada8 100644 --- a/tests/ui/inference/type-infer-generalize-ty-var.rs +++ b/tests/ui/inference/type-infer-generalize-ty-var.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![allow(non_upper_case_globals)] #![allow(dead_code)] diff --git a/tests/ui/issues/issue-13167.rs b/tests/ui/issues/issue-13167.rs index 9a9f129ec3a..747f652d4af 100644 --- a/tests/ui/issues/issue-13167.rs +++ b/tests/ui/issues/issue-13167.rs @@ -1,7 +1,7 @@ // check-pass // pretty-expanded FIXME #23616 // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver use std::slice; diff --git a/tests/ui/issues/issue-13407.rs b/tests/ui/issues/issue-13407.rs index 7ea81ffb59e..7794be37b85 100644 --- a/tests/ui/issues/issue-13407.rs +++ b/tests/ui/issues/issue-13407.rs @@ -4,6 +4,6 @@ mod A { fn main() { A::C = 1; - //~^ ERROR: invalid left-hand side of assignment - //~| ERROR: struct `C` is private + //~^ ERROR: mismatched types + //~| ERROR: unit struct `C` is private } diff --git a/tests/ui/issues/issue-13407.stderr b/tests/ui/issues/issue-13407.stderr index 54b6c640d9d..ac2eb6581fe 100644 --- a/tests/ui/issues/issue-13407.stderr +++ b/tests/ui/issues/issue-13407.stderr @@ -10,15 +10,18 @@ note: the unit struct `C` is defined here LL | struct C; | ^^^^^^^^^ -error[E0070]: invalid left-hand side of assignment - --> $DIR/issue-13407.rs:6:10 +error[E0308]: mismatched types + --> $DIR/issue-13407.rs:6:5 | +LL | struct C; + | -------- unit struct defined here +... LL | A::C = 1; - | ---- ^ + | ^^^^ - this expression has type `{integer}` | | - | cannot assign to this expression + | expected integer, found `C` error: aborting due to 2 previous errors -Some errors have detailed explanations: E0070, E0603. -For more information about an error, try `rustc --explain E0070`. +Some errors have detailed explanations: E0308, E0603. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-15734.rs b/tests/ui/issues/issue-15734.rs index 27410d4c3b0..77517f61813 100644 --- a/tests/ui/issues/issue-15734.rs +++ b/tests/ui/issues/issue-15734.rs @@ -1,6 +1,6 @@ // run-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver use std::ops::Index; diff --git a/tests/ui/issues/issue-21763.stderr b/tests/ui/issues/issue-21763.stderr index 3d623985cbb..135b705eeef 100644 --- a/tests/ui/issues/issue-21763.stderr +++ b/tests/ui/issues/issue-21763.stderr @@ -7,7 +7,7 @@ LL | foo::<HashMap<Rc<()>, Rc<()>>>(); = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` = note: required because it appears within the type `(Rc<()>, Rc<()>)` = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` -note: required because it appears within the type `HashMap<Rc<()>, Rc<()>, RandomState>` +note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>` --> $HASHBROWN_SRC_LOCATION note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr index 269193f73b4..c0d516e3f62 100644 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ b/tests/ui/kindck/kindck-send-object1.stderr @@ -20,7 +20,7 @@ LL | assert_send::<Box<dyn Dummy + 'a>>(); | = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` -note: required because it appears within the type `Box<dyn Dummy>` +note: required because it appears within the type `Box<(dyn Dummy + 'a)>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` --> $DIR/kindck-send-object1.rs:5:18 diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index 3d33adf6831..21bd7187e15 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -22,6 +22,8 @@ trait MyIndex<'a, T> {} #[lang = "phantom_data"] //~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument struct MyPhantomData<T, U>; +//~^ ERROR parameter `T` is never used +//~| ERROR parameter `U` is never used #[lang = "owned_box"] //~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument @@ -40,6 +42,7 @@ fn ice() { let r = 5; let a = 6; r + a; + //~^ ERROR cannot add `{integer}` to `{integer}` // Use drop in place my_ptr_drop(); diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index 4d349a25f9c..8072e6797e4 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>; | ------ this struct has 2 generic arguments error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:26:1 + --> $DIR/lang-item-generic-requirements.rs:28:1 | LL | #[lang = "owned_box"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | struct Foo; | - this struct has 0 generic arguments error[E0718]: `start` language item must be applied to a function with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:32:1 + --> $DIR/lang-item-generic-requirements.rs:34:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ @@ -50,6 +50,35 @@ LL | LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments -error: aborting due to 6 previous errors +error[E0392]: parameter `T` is never used + --> $DIR/lang-item-generic-requirements.rs:24:22 + | +LL | struct MyPhantomData<T, U>; + | ^ unused parameter + | + = help: consider removing `T` or referring to it in a field + = help: if you intended `T` to be a const parameter, use `const T: usize` instead + +error[E0392]: parameter `U` is never used + --> $DIR/lang-item-generic-requirements.rs:24:25 + | +LL | struct MyPhantomData<T, U>; + | ^ unused parameter + | + = help: consider removing `U` or referring to it in a field + = help: if you intended `U` to be a const parameter, use `const U: usize` instead + +error[E0369]: cannot add `{integer}` to `{integer}` + --> $DIR/lang-item-generic-requirements.rs:44:7 + | +LL | r + a; + | - ^ - {integer} + | | + | {integer} + +error: requires `copy` lang_item + +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0718`. +Some errors have detailed explanations: E0369, E0392, E0718. +For more information about an error, try `rustc --explain E0369`. diff --git a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs index 745eadb9625..ec9a6739975 100644 --- a/tests/ui/lazy-type-alias/coerce-behind-lazy.rs +++ b/tests/ui/lazy-type-alias/coerce-behind-lazy.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(lazy_type_alias)] //~^ WARN the feature `lazy_type_alias` is incomplete diff --git a/tests/ui/lint/ptr_null_checks.rs b/tests/ui/lint/ptr_null_checks.rs index 3028084e962..4925019be1e 100644 --- a/tests/ui/lint/ptr_null_checks.rs +++ b/tests/ui/lint/ptr_null_checks.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(ptr_from_ref)] - use std::ptr; extern "C" fn c_fn() {} diff --git a/tests/ui/lint/ptr_null_checks.stderr b/tests/ui/lint/ptr_null_checks.stderr index 0edc1b86536..70a27790c5b 100644 --- a/tests/ui/lint/ptr_null_checks.stderr +++ b/tests/ui/lint/ptr_null_checks.stderr @@ -1,5 +1,5 @@ warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:14:8 + --> $DIR/ptr_null_checks.rs:12:8 | LL | if (fn_ptr as *mut ()).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | if (fn_ptr as *mut ()).is_null() {} = note: `#[warn(useless_ptr_null_checks)]` on by default warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:16:8 + --> $DIR/ptr_null_checks.rs:14:8 | LL | if (fn_ptr as *const u8).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | if (fn_ptr as *const u8).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:18:8 + --> $DIR/ptr_null_checks.rs:16:8 | LL | if (fn_ptr as *const ()) == std::ptr::null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | if (fn_ptr as *const ()) == std::ptr::null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:20:8 + --> $DIR/ptr_null_checks.rs:18:8 | LL | if (fn_ptr as *mut ()) == std::ptr::null_mut() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | if (fn_ptr as *mut ()) == std::ptr::null_mut() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:22:8 + --> $DIR/ptr_null_checks.rs:20:8 | LL | if (fn_ptr as *const ()) == (0 as *const ()) {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | if (fn_ptr as *const ()) == (0 as *const ()) {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:24:8 + --> $DIR/ptr_null_checks.rs:22:8 | LL | if <*const _>::is_null(fn_ptr as *const ()) {} | ^^^^^^^^^^^^^^^^^^^^------^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | if <*const _>::is_null(fn_ptr as *const ()) {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:26:8 + --> $DIR/ptr_null_checks.rs:24:8 | LL | if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:28:8 + --> $DIR/ptr_null_checks.rs:26:8 | LL | if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:30:8 + --> $DIR/ptr_null_checks.rs:28:8 | LL | if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() {} | ^^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() { = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:32:8 + --> $DIR/ptr_null_checks.rs:30:8 | LL | if (fn_ptr as fn() as *const ()).is_null() {} | ^--------------^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | if (fn_ptr as fn() as *const ()).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: function pointers are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:34:8 + --> $DIR/ptr_null_checks.rs:32:8 | LL | if (c_fn as *const fn()).is_null() {} | ^----^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +110,7 @@ LL | if (c_fn as *const fn()).is_null() {} = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:38:8 + --> $DIR/ptr_null_checks.rs:36:8 | LL | if (&mut 8 as *mut i32).is_null() {} | ^------^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,13 +118,13 @@ LL | if (&mut 8 as *mut i32).is_null() {} | expression has type `&mut i32` warning: returned pointer of `from_mut` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:40:8 + --> $DIR/ptr_null_checks.rs:38:8 | LL | if ptr::from_mut(&mut 8).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:42:8 + --> $DIR/ptr_null_checks.rs:40:8 | LL | if (&8 as *const i32).is_null() {} | ^--^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,25 +132,25 @@ LL | if (&8 as *const i32).is_null() {} | expression has type `&i32` warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:44:8 + --> $DIR/ptr_null_checks.rs:42:8 | LL | if ptr::from_ref(&8).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:46:8 + --> $DIR/ptr_null_checks.rs:44:8 | LL | if ptr::from_ref(&8).cast_mut().is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:48:8 + --> $DIR/ptr_null_checks.rs:46:8 | LL | if (ptr::from_ref(&8).cast_mut() as *mut i32).is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:50:8 + --> $DIR/ptr_null_checks.rs:48:8 | LL | if (&8 as *const i32) == std::ptr::null() {} | ^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,7 +158,7 @@ LL | if (&8 as *const i32) == std::ptr::null() {} | expression has type `&i32` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:53:8 + --> $DIR/ptr_null_checks.rs:51:8 | LL | if (ref_num as *const i32) == std::ptr::null() {} | ^-------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ LL | if (ref_num as *const i32) == std::ptr::null() {} | expression has type `&i32` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:55:8 + --> $DIR/ptr_null_checks.rs:53:8 | LL | if (b"\0" as *const u8).is_null() {} | ^-----^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +174,7 @@ LL | if (b"\0" as *const u8).is_null() {} | expression has type `&[u8; 1]` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:57:8 + --> $DIR/ptr_null_checks.rs:55:8 | LL | if ("aa" as *const str).is_null() {} | ^----^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | if ("aa" as *const str).is_null() {} | expression has type `&str` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:59:8 + --> $DIR/ptr_null_checks.rs:57:8 | LL | if (&[1, 2] as *const i32).is_null() {} | ^-------^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -190,7 +190,7 @@ LL | if (&[1, 2] as *const i32).is_null() {} | expression has type `&[i32; 2]` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:61:8 + --> $DIR/ptr_null_checks.rs:59:8 | LL | if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {} | ^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +198,7 @@ LL | if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {} | expression has type `&mut [i32; 2]` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:63:8 + --> $DIR/ptr_null_checks.rs:61:8 | LL | if (static_i32() as *const i32).is_null() {} | ^------------^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +206,7 @@ LL | if (static_i32() as *const i32).is_null() {} | expression has type `&i32` warning: references are not nullable, so checking them for null will always return false - --> $DIR/ptr_null_checks.rs:65:8 + --> $DIR/ptr_null_checks.rs:63:8 | LL | if (&*{ static_i32() } as *const i32).is_null() {} | ^------------------^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,13 +214,13 @@ LL | if (&*{ static_i32() } as *const i32).is_null() {} | expression has type `&i32` warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:69:8 + --> $DIR/ptr_null_checks.rs:67:8 | LL | if ptr::NonNull::new(&mut 8).unwrap().as_ptr().is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false - --> $DIR/ptr_null_checks.rs:71:8 + --> $DIR/ptr_null_checks.rs:69:8 | LL | if ptr::NonNull::<u8>::dangling().as_ptr().is_null() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 25e0c75f70d..84267c0af03 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -1,7 +1,5 @@ // check-fail -#![feature(ptr_from_ref)] - extern "C" { // N.B., mutability can be easily incorrect in FFI calls -- as // in C, the default is mutable pointers. @@ -116,6 +114,13 @@ unsafe fn assign_to_ref() { let value = num as *const i32 as *mut i32; *value = 1; //~^ ERROR assigning to `&T` is undefined behavior + let value = num as *const i32; + let value = value as *mut i32; + *value = 1; + //~^ ERROR assigning to `&T` is undefined behavior + let value = num as *const i32 as *mut i32; + *value = 1; + //~^ ERROR assigning to `&T` is undefined behavior let value_rebind = value; *value_rebind = 1; //~^ ERROR assigning to `&T` is undefined behavior diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index 8d5f8da6852..374a58d7b7b 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -1,5 +1,5 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:19:16 + --> $DIR/reference_casting.rs:17:16 | LL | let _num = &mut *(num as *const i32 as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _num = &mut *(num as *const i32 as *mut i32); = note: `#[deny(invalid_reference_casting)]` on by default error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:21:16 + --> $DIR/reference_casting.rs:19:16 | LL | let _num = &mut *(num as *const i32).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let _num = &mut *(num as *const i32).cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:23:16 + --> $DIR/reference_casting.rs:21:16 | LL | let _num = &mut *std::ptr::from_ref(num).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | let _num = &mut *std::ptr::from_ref(num).cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:25:16 + --> $DIR/reference_casting.rs:23:16 | LL | let _num = &mut *std::ptr::from_ref({ num }).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | let _num = &mut *std::ptr::from_ref({ num }).cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:27:16 + --> $DIR/reference_casting.rs:25:16 | LL | let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:29:16 + --> $DIR/reference_casting.rs:27:16 | LL | let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:31:16 + --> $DIR/reference_casting.rs:29:16 | LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut(); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:33:16 + --> $DIR/reference_casting.rs:31:16 | LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_const().cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_cons = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:35:16 + --> $DIR/reference_casting.rs:33:16 | LL | let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:37:16 + --> $DIR/reference_casting.rs:35:16 | LL | let _num = &mut *std::mem::transmute::<_, *mut i32>(num); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | let _num = &mut *std::mem::transmute::<_, *mut i32>(num); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:39:16 + --> $DIR/reference_casting.rs:37:16 | LL | let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:41:16 + --> $DIR/reference_casting.rs:39:16 | LL | let _num = &mut *std::cell::UnsafeCell::raw_get( | ________________^ @@ -100,7 +100,7 @@ LL | | ); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:47:16 + --> $DIR/reference_casting.rs:45:16 | LL | let deferred = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -110,7 +110,7 @@ LL | let _num = &mut *deferred; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:50:16 + --> $DIR/reference_casting.rs:48:16 | LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; | ---------------------------------------------------------------------------- casting happend here @@ -120,7 +120,7 @@ LL | let _num = &mut *deferred; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:53:16 + --> $DIR/reference_casting.rs:51:16 | LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; | ---------------------------------------------------------------------------- casting happend here @@ -131,7 +131,7 @@ LL | let _num = &mut *deferred_rebind; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:55:16 + --> $DIR/reference_casting.rs:53:16 | LL | let _num = &mut *(num as *const _ as usize as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | let _num = &mut *(num as *const _ as usize as *mut i32); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:57:16 + --> $DIR/reference_casting.rs:55:16 | LL | let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -147,7 +147,7 @@ LL | let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) a = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:64:16 + --> $DIR/reference_casting.rs:62:16 | LL | let num = NUM as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -158,7 +158,7 @@ LL | let _num = &mut *num; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:68:16 + --> $DIR/reference_casting.rs:66:16 | LL | let _num = &mut *(cell as *const _ as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | let _num = &mut *(cell as *const _ as *mut i32); = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:72:9 + --> $DIR/reference_casting.rs:70:9 | LL | &mut *((this as *const _) as *mut _) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -175,7 +175,7 @@ LL | &mut *((this as *const _) as *mut _) = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:77:18 + --> $DIR/reference_casting.rs:75:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:82:18 + --> $DIR/reference_casting.rs:80:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -191,7 +191,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:92:5 + --> $DIR/reference_casting.rs:90:5 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | *(a as *const _ as *mut _) = String::from("Replaced"); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:94:5 + --> $DIR/reference_casting.rs:92:5 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL | *(a as *const _ as *mut String) += " world"; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:96:5 + --> $DIR/reference_casting.rs:94:5 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -215,7 +215,7 @@ LL | *std::ptr::from_ref(num).cast_mut() += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:98:5 + --> $DIR/reference_casting.rs:96:5 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +223,7 @@ LL | *std::ptr::from_ref({ num }).cast_mut() += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:100:5 + --> $DIR/reference_casting.rs:98:5 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:102:5 + --> $DIR/reference_casting.rs:100:5 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -239,7 +239,7 @@ LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:104:5 + --> $DIR/reference_casting.rs:102:5 | LL | *std::mem::transmute::<_, *mut i32>(num) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -247,7 +247,7 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:106:5 + --> $DIR/reference_casting.rs:104:5 | LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:108:5 + --> $DIR/reference_casting.rs:106:5 | LL | / std::ptr::write( LL | | @@ -267,7 +267,7 @@ LL | | ); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:113:5 + --> $DIR/reference_casting.rs:111:5 | LL | *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -276,7 +276,27 @@ LL | *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5; = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get` error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:117:5 + --> $DIR/reference_casting.rs:115:5 + | +LL | let value = num as *const i32 as *mut i32; + | ----------------------------- casting happend here +LL | *value = 1; + | ^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:119:5 + | +LL | let value = value as *mut i32; + | ----------------- casting happend here +LL | *value = 1; + | ^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:122:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -286,7 +306,7 @@ LL | *value = 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:120:5 + --> $DIR/reference_casting.rs:125:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -297,7 +317,7 @@ LL | *value_rebind = 1; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:122:5 + --> $DIR/reference_casting.rs:127:5 | LL | *(num as *const i32).cast::<i32>().cast_mut() = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -305,7 +325,7 @@ LL | *(num as *const i32).cast::<i32>().cast_mut() = 2; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:124:5 + --> $DIR/reference_casting.rs:129:5 | LL | *(num as *const _ as usize as *mut i32) = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +333,7 @@ LL | *(num as *const _ as usize as *mut i32) = 2; = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:126:5 + --> $DIR/reference_casting.rs:131:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -324,7 +344,7 @@ LL | std::ptr::write(value, 2); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:128:5 + --> $DIR/reference_casting.rs:133:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -335,7 +355,7 @@ LL | std::ptr::write_unaligned(value, 2); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:130:5 + --> $DIR/reference_casting.rs:135:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -346,12 +366,12 @@ LL | std::ptr::write_volatile(value, 2); = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:134:9 + --> $DIR/reference_casting.rs:139:9 | LL | *(this as *const _ as *mut _) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> -error: aborting due to 40 previous errors +error: aborting due to 42 previous errors diff --git a/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs b/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs index ab8d95a41d0..1b8ce10ccce 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs @@ -10,11 +10,11 @@ fn main() { $( // inner-most repetition $( - ${ignore(l)} ${index()}, ${length()}, + ${ignore($l)} ${index()}, ${length()}, )* - ${count(l)}, ${index()}, ${length()}, + ${count($l)}, ${index()}, ${length()}, )* - ${count(l)}, + ${count($l)}, ] }; } @@ -72,30 +72,30 @@ fn main() { &[ $( $( $( &[ - ${ignore(i)} ${count(i, 0)}, + ${ignore($i)} ${count($i, 0)}, ][..], )* )* )* $( $( &[ - ${ignore(i)} ${count(i, 0)}, - ${ignore(i)} ${count(i, 1)}, + ${ignore($i)} ${count($i, 0)}, + ${ignore($i)} ${count($i, 1)}, ][..], )* )* $( &[ - ${ignore(i)} ${count(i, 0)}, - ${ignore(i)} ${count(i, 1)}, - ${ignore(i)} ${count(i, 2)}, + ${ignore($i)} ${count($i, 0)}, + ${ignore($i)} ${count($i, 1)}, + ${ignore($i)} ${count($i, 2)}, ][..], )* &[ - ${count(i, 0)}, - ${count(i, 1)}, - ${count(i, 2)}, - ${count(i, 3)}, + ${count($i, 0)}, + ${count($i, 1)}, + ${count($i, 2)}, + ${count($i, 3)}, ][..] ][..] } @@ -133,23 +133,23 @@ fn main() { &[7][..], // (a b c) (d e f) - &[2, 6][..], + &[6, 2][..], // (g h) (i j k l m) - &[2, 7][..], + &[7, 2][..], // (n) &[1, 1][..], // (o) (p q) (r s) - &[3, 5][..], + &[5, 3][..], // (t u v w x y z) - &[1, 7][..], + &[7, 1][..], // [ (a b c) (d e f) ] // [ (g h) (i j k l m) ] // [ (n) ] - &[3, 5, 14][..], + &[14, 5, 3][..], // [ (o) (p q) (r s) ] // [ (t u v w x y z) ] - &[2, 4, 12][..], + &[12, 4, 2][..], // { // [ (a b c) (d e f) ] @@ -160,7 +160,7 @@ fn main() { // [ (o) (p q) (r s) ] // [ (t u v w x y z) ] // } - &[2, 5, 9, 26][..] + &[26, 9, 5, 2][..] ][..] ); @@ -170,31 +170,31 @@ fn main() { &[ $( $( $( $( &[ - ${ignore(i)} ${length(3)}, - ${ignore(i)} ${length(2)}, - ${ignore(i)} ${length(1)}, - ${ignore(i)} ${length(0)}, + ${ignore($i)} ${length(3)}, + ${ignore($i)} ${length(2)}, + ${ignore($i)} ${length(1)}, + ${ignore($i)} ${length(0)}, ][..], )* )* )* )* $( $( $( &[ - ${ignore(i)} ${length(2)}, - ${ignore(i)} ${length(1)}, - ${ignore(i)} ${length(0)}, + ${ignore($i)} ${length(2)}, + ${ignore($i)} ${length(1)}, + ${ignore($i)} ${length(0)}, ][..], )* )* )* $( $( &[ - ${ignore(i)} ${length(1)}, - ${ignore(i)} ${length(0)}, + ${ignore($i)} ${length(1)}, + ${ignore($i)} ${length(0)}, ][..], )* )* $( &[ - ${ignore(i)} ${length(0)}, + ${ignore($i)} ${length(0)}, ][..], )* ][..] diff --git a/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs b/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs index d05cd1b31bc..950e70153ba 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs @@ -5,14 +5,14 @@ /// Count the number of idents in a macro repetition. macro_rules! count_idents { ( $( $i:ident ),* ) => { - ${count(i)} + ${count($i)} }; } /// Count the number of idents in a 2-dimensional macro repetition. macro_rules! count_idents_2 { ( $( [ $( $i:ident ),* ] ),* ) => { - ${count(i)} + ${count($i)} }; } @@ -21,17 +21,17 @@ macro_rules! count_depth_limits { ( $( { $( [ $( $outer:ident : ( $( $inner:ident )* ) )* ] )* } )* ) => { ( ( - ${count(inner)}, - ${count(inner, 0)}, - ${count(inner, 1)}, - ${count(inner, 2)}, - ${count(inner, 3)}, + ${count($inner)}, + ${count($inner, 0)}, + ${count($inner, 1)}, + ${count($inner, 2)}, + ${count($inner, 3)}, ), ( - ${count(outer)}, - ${count(outer, 0)}, - ${count(outer, 1)}, - ${count(outer, 2)}, + ${count($outer)}, + ${count($outer, 0)}, + ${count($outer, 1)}, + ${count($outer, 2)}, ), ) }; @@ -43,7 +43,7 @@ macro_rules! count_depth_limits { /// repetition binding. macro_rules! enumerate_literals { ( $( ($l:stmt) ),* ) => { - [$( ${ignore(l)} (${index()}, ${length()}) ),*] + [$( ${ignore($l)} (${index()}, ${length()}) ),*] }; } @@ -77,7 +77,7 @@ macro_rules! make_count_adders { $( macro_rules! $i { ( $$( $$j:ident ),* ) => { - $b + $${count(j)} + $b + $${count($j)} }; } )* @@ -122,7 +122,7 @@ fn main() { [ T: (t u v w x y z) ] } }, - ((26, 2, 5, 9, 26), (9, 2, 5, 9)) + ((26, 26, 9, 5, 2), (9, 9, 5, 2)) ); assert_eq!(enumerate_literals![("foo"), ("bar")], [(0, 2), (1, 2)]); assert_eq!( diff --git a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs index 9cc572c23a1..3000bfed6a8 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs @@ -1,7 +1,7 @@ #![feature(macro_metavar_expr)] macro_rules! foo { - ( $( $($t:ident),* );* ) => { ${count(t,)} } + ( $( $($t:ident),* );* ) => { ${count($t,)} } //~^ ERROR `count` followed by a comma must have an associated //~| ERROR expected expression, found `$` } diff --git a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr index e9317a5c347..fd53c1686cf 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr @@ -1,13 +1,13 @@ error: `count` followed by a comma must have an associated index indicating its depth --> $DIR/issue-111904.rs:4:37 | -LL | ( $( $($t:ident),* );* ) => { ${count(t,)} } +LL | ( $( $($t:ident),* );* ) => { ${count($t,)} } | ^^^^^ error: expected expression, found `$` --> $DIR/issue-111904.rs:4:35 | -LL | ( $( $($t:ident),* );* ) => { ${count(t,)} } +LL | ( $( $($t:ident),* );* ) => { ${count($t,)} } | ^ expected expression ... LL | foo!(a, a; b, b); diff --git a/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs b/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs index b954967c4fe..04924f0efa6 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs @@ -13,17 +13,17 @@ macro_rules! example { ( $( [ $( ( $( $x:ident )* ) )* ] )* ) => { Example { _indexes: &[], - _counts: &[${count(x, 0)}, ${count(x, 1)}, ${count(x, 2)}], + _counts: &[${count($x, 0)}, ${count($x, 1)}, ${count($x, 2)}], _nested: vec![ $( Example { _indexes: &[(${index()}, ${length()})], - _counts: &[${count(x, 0)}, ${count(x, 1)}], + _counts: &[${count($x, 0)}, ${count($x, 1)}], _nested: vec![ $( Example { _indexes: &[(${index(1)}, ${length(1)}), (${index()}, ${length()})], - _counts: &[${count(x)}], + _counts: &[${count($x)}], _nested: vec![ $( Example { @@ -34,7 +34,7 @@ macro_rules! example { ], _counts: &[], _nested: vec![], - ${ignore(x)} + ${ignore($x)} } ),* ] @@ -49,9 +49,9 @@ macro_rules! example { } static EXPECTED: &str = concat!( - "Example { _indexes: [], _counts: [2, 4, 13], _nested: [", + "Example { _indexes: [], _counts: [13, 4, 2], _nested: [", concat!( - "Example { _indexes: [(0, 2)], _counts: [3, 10], _nested: [", + "Example { _indexes: [(0, 2)], _counts: [10, 3], _nested: [", concat!( "Example { _indexes: [(0, 2), (0, 3)], _counts: [4], _nested: [", concat!( @@ -77,7 +77,7 @@ static EXPECTED: &str = concat!( "] }", ), "] }, ", - "Example { _indexes: [(1, 2)], _counts: [1, 3], _nested: [", + "Example { _indexes: [(1, 2)], _counts: [3, 1], _nested: [", concat!( "Example { _indexes: [(1, 2), (0, 1)], _counts: [3], _nested: [", concat!( diff --git a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs index 6a0d68bd6b1..d195506af36 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs @@ -3,9 +3,9 @@ macro_rules! a { ( $( { $( [ $( ( $( $foo:ident )* ) )* ] )* } )* ) => { ( - ${count(foo, 0)}, - ${count(foo, 10)}, - //~^ ERROR depth parameter on meta-variable expression `count` must be less than 4 + ${count($foo, 0)}, + ${count($foo, 10)}, + //~^ ERROR depth parameter of meta-variable expression `count` must be less than 4 ) }; } @@ -14,10 +14,10 @@ macro_rules! b { ( $( { $( [ $( $foo:ident )* ] )* } )* ) => { ( $( $( $( - ${ignore(foo)} + ${ignore($foo)} ${index(0)}, ${index(10)}, - //~^ ERROR depth parameter on meta-variable expression `index` must be less than 3 + //~^ ERROR depth parameter of meta-variable expression `index` must be less than 3 )* )* )* ) }; @@ -27,10 +27,10 @@ macro_rules! c { ( $( { $( $foo:ident )* } )* ) => { ( $( $( - ${ignore(foo)} + ${ignore($foo)} ${length(0)} ${length(10)} - //~^ ERROR depth parameter on meta-variable expression `length` must be less than 2 + //~^ ERROR depth parameter of meta-variable expression `length` must be less than 2 )* )* ) }; diff --git a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr index 236122b6465..f757b8af219 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr @@ -1,16 +1,16 @@ -error: depth parameter on meta-variable expression `count` must be less than 4 +error: depth parameter of meta-variable expression `count` must be less than 4 --> $DIR/out-of-bounds-arguments.rs:7:14 | -LL | ${count(foo, 10)}, - | ^^^^^^^^^^^^^^^^ +LL | ${count($foo, 10)}, + | ^^^^^^^^^^^^^^^^^ -error: depth parameter on meta-variable expression `index` must be less than 3 +error: depth parameter of meta-variable expression `index` must be less than 3 --> $DIR/out-of-bounds-arguments.rs:19:18 | LL | ${index(10)}, | ^^^^^^^^^^^ -error: depth parameter on meta-variable expression `length` must be less than 2 +error: depth parameter of meta-variable expression `length` must be less than 2 --> $DIR/out-of-bounds-arguments.rs:32:18 | LL | ${length(10)} diff --git a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs index b4fef11f1e2..53d045700f9 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs @@ -1,6 +1,6 @@ macro_rules! count { ( $( $e:stmt ),* ) => { - ${ count(e) } + ${ count($e) } //~^ ERROR meta-variable expressions are unstable }; } @@ -19,7 +19,7 @@ macro_rules! dollar_dollar { macro_rules! index { ( $( $e:stmt ),* ) => { - $( ${ignore(e)} ${index()} )* + $( ${ignore($e)} ${index()} )* //~^ ERROR meta-variable expressions are unstable //~| ERROR meta-variable expressions are unstable }; @@ -27,14 +27,14 @@ macro_rules! index { macro_rules! ignore { ( $( $i:stmt ),* ) => {{ - 0 $( + 1 ${ignore(i)} )* + 0 $( + 1 ${ignore($i)} )* //~^ ERROR meta-variable expressions are unstable }}; } macro_rules! length { ( $( $e:stmt ),* ) => { - $( ${ignore(e)} ${length()} )* + $( ${ignore($e)} ${length()} )* //~^ ERROR meta-variable expressions are unstable //~| ERROR meta-variable expressions are unstable }; diff --git a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr index ecf598b104d..2c2cbb15b72 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr @@ -1,8 +1,8 @@ error[E0658]: meta-variable expressions are unstable --> $DIR/required-feature.rs:3:10 | -LL | ${ count(e) } - | ^^^^^^^^^^^^ +LL | ${ count($e) } + | ^^^^^^^^^^^^^ | = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable @@ -46,17 +46,17 @@ LL | ( $$( $$any:tt )* ) => { $$( $$any )* }; error[E0658]: meta-variable expressions are unstable --> $DIR/required-feature.rs:22:13 | -LL | $( ${ignore(e)} ${index()} )* - | ^^^^^^^^^^^ +LL | $( ${ignore($e)} ${index()} )* + | ^^^^^^^^^^^^ | = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable error[E0658]: meta-variable expressions are unstable - --> $DIR/required-feature.rs:22:26 + --> $DIR/required-feature.rs:22:27 | -LL | $( ${ignore(e)} ${index()} )* - | ^^^^^^^^^ +LL | $( ${ignore($e)} ${index()} )* + | ^^^^^^^^^ | = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable @@ -64,8 +64,8 @@ LL | $( ${ignore(e)} ${index()} )* error[E0658]: meta-variable expressions are unstable --> $DIR/required-feature.rs:30:19 | -LL | 0 $( + 1 ${ignore(i)} )* - | ^^^^^^^^^^^ +LL | 0 $( + 1 ${ignore($i)} )* + | ^^^^^^^^^^^^ | = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable @@ -73,17 +73,17 @@ LL | 0 $( + 1 ${ignore(i)} )* error[E0658]: meta-variable expressions are unstable --> $DIR/required-feature.rs:37:13 | -LL | $( ${ignore(e)} ${length()} )* - | ^^^^^^^^^^^ +LL | $( ${ignore($e)} ${length()} )* + | ^^^^^^^^^^^^ | = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable error[E0658]: meta-variable expressions are unstable - --> $DIR/required-feature.rs:37:26 + --> $DIR/required-feature.rs:37:27 | -LL | $( ${ignore(e)} ${length()} )* - | ^^^^^^^^^^ +LL | $( ${ignore($e)} ${length()} )* + | ^^^^^^^^^^ | = note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information = help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs index fdf16442d2a..05c65fe8690 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs @@ -5,24 +5,17 @@ // `round` = Left hand side round brackets macro_rules! curly__no_rhs_dollar__round { - ( $( $i:ident ),* ) => { ${ count(i) } }; + ( $( $i:ident ),* ) => { ${ count($i) } }; } macro_rules! curly__no_rhs_dollar__no_round { - ( $i:ident ) => { ${ count(i) } }; + ( $i:ident ) => { ${ count($i) } }; //~^ ERROR `count` can not be placed inside the inner-most repetition } -macro_rules! curly__rhs_dollar__round { - ( $( $i:ident ),* ) => { ${ count($i) } }; - //~^ ERROR expected identifier, found `$` - //~| ERROR expected expression, found `$` -} - macro_rules! curly__rhs_dollar__no_round { ( $i:ident ) => { ${ count($i) } }; - //~^ ERROR expected identifier, found `$` - //~| ERROR expected expression, found `$` + //~^ ERROR `count` can not be placed inside the inner-most repetition } macro_rules! no_curly__no_rhs_dollar__round { @@ -60,16 +53,16 @@ macro_rules! extra_garbage_after_metavar { ${count() a b c} //~^ ERROR unexpected token: a //~| ERROR expected expression, found `$` - ${count(i a b c)} + ${count($i a b c)} //~^ ERROR unexpected token: a - ${count(i, 1 a b c)} + ${count($i, 1 a b c)} //~^ ERROR unexpected token: a - ${count(i) a b c} + ${count($i) a b c} //~^ ERROR unexpected token: a - ${ignore(i) a b c} + ${ignore($i) a b c} //~^ ERROR unexpected token: a - ${ignore(i a b c)} + ${ignore($i a b c)} //~^ ERROR unexpected token: a ${index() a b c} @@ -100,8 +93,8 @@ macro_rules! metavar_in_the_lhs { macro_rules! metavar_token_without_ident { ( $( $i:ident ),* ) => { ${ ignore() } }; - //~^ ERROR expected identifier - //~| ERROR expected expression, found `$` + //~^ ERROR meta-variable expressions must be referenced using a dollar sign + //~| ERROR expected expression } macro_rules! metavar_with_literal_suffix { @@ -125,14 +118,16 @@ macro_rules! open_brackets_without_tokens { macro_rules! unknown_count_ident { ( $( $i:ident )* ) => { ${count(foo)} - //~^ ERROR variable `foo` is not recognized in meta-variable expression + //~^ ERROR meta-variable expressions must be referenced using a dollar sign + //~| ERROR expected expression }; } macro_rules! unknown_ignore_ident { ( $( $i:ident )* ) => { ${ignore(bar)} - //~^ ERROR variable `bar` is not recognized in meta-variable expression + //~^ ERROR meta-variable expressions must be referenced using a dollar sign + //~| ERROR expected expression }; } @@ -145,7 +140,6 @@ macro_rules! unknown_metavar { fn main() { curly__no_rhs_dollar__round!(a, b, c); curly__no_rhs_dollar__no_round!(a); - curly__rhs_dollar__round!(a, b, c); curly__rhs_dollar__no_round!(a); no_curly__no_rhs_dollar__round!(a, b, c); no_curly__no_rhs_dollar__no_round!(a); diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index a6cff95fd91..0dda38290ab 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -1,197 +1,197 @@ -error: expected identifier, found `$` - --> $DIR/syntax-errors.rs:17:33 - | -LL | ( $( $i:ident ),* ) => { ${ count($i) } }; - | ^^^^^ - help: try removing `$` - -error: expected identifier, found `$` - --> $DIR/syntax-errors.rs:23:26 - | -LL | ( $i:ident ) => { ${ count($i) } }; - | ^^^^^ - help: try removing `$` - error: unexpected token: $ - --> $DIR/syntax-errors.rs:53:8 + --> $DIR/syntax-errors.rs:46:8 | LL | ( $$ $a:ident ) => { | ^ note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions - --> $DIR/syntax-errors.rs:53:8 + --> $DIR/syntax-errors.rs:46:8 | LL | ( $$ $a:ident ) => { | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:60:19 + --> $DIR/syntax-errors.rs:53:19 | LL | ${count() a b c} | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:60:19 + --> $DIR/syntax-errors.rs:53:19 | LL | ${count() a b c} | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:63:19 + --> $DIR/syntax-errors.rs:56:20 | -LL | ${count(i a b c)} - | ^ +LL | ${count($i a b c)} + | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:63:19 + --> $DIR/syntax-errors.rs:56:20 | -LL | ${count(i a b c)} - | ^ +LL | ${count($i a b c)} + | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:65:22 + --> $DIR/syntax-errors.rs:58:23 | -LL | ${count(i, 1 a b c)} - | ^ +LL | ${count($i, 1 a b c)} + | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:65:22 + --> $DIR/syntax-errors.rs:58:23 | -LL | ${count(i, 1 a b c)} - | ^ +LL | ${count($i, 1 a b c)} + | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:67:20 + --> $DIR/syntax-errors.rs:60:21 | -LL | ${count(i) a b c} - | ^ +LL | ${count($i) a b c} + | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:67:20 + --> $DIR/syntax-errors.rs:60:21 | -LL | ${count(i) a b c} - | ^ +LL | ${count($i) a b c} + | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:70:21 + --> $DIR/syntax-errors.rs:63:22 | -LL | ${ignore(i) a b c} - | ^ +LL | ${ignore($i) a b c} + | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:70:21 + --> $DIR/syntax-errors.rs:63:22 | -LL | ${ignore(i) a b c} - | ^ +LL | ${ignore($i) a b c} + | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:72:20 + --> $DIR/syntax-errors.rs:65:21 | -LL | ${ignore(i a b c)} - | ^ +LL | ${ignore($i a b c)} + | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:72:20 + --> $DIR/syntax-errors.rs:65:21 | -LL | ${ignore(i a b c)} - | ^ +LL | ${ignore($i a b c)} + | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:75:19 + --> $DIR/syntax-errors.rs:68:19 | LL | ${index() a b c} | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:75:19 + --> $DIR/syntax-errors.rs:68:19 | LL | ${index() a b c} | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:77:19 + --> $DIR/syntax-errors.rs:70:19 | LL | ${index(1 a b c)} | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:77:19 + --> $DIR/syntax-errors.rs:70:19 | LL | ${index(1 a b c)} | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:80:19 + --> $DIR/syntax-errors.rs:73:19 | LL | ${index() a b c} | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:80:19 + --> $DIR/syntax-errors.rs:73:19 | LL | ${index() a b c} | ^ error: unexpected token: a - --> $DIR/syntax-errors.rs:82:19 + --> $DIR/syntax-errors.rs:75:19 | LL | ${index(1 a b c)} | ^ | note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:82:19 + --> $DIR/syntax-errors.rs:75:19 | LL | ${index(1 a b c)} | ^ error: meta-variable expression depth must be a literal - --> $DIR/syntax-errors.rs:89:33 + --> $DIR/syntax-errors.rs:82:33 | LL | ( $( $i:ident ),* ) => { ${ index(IDX) } }; | ^^^^^ error: unexpected token: { - --> $DIR/syntax-errors.rs:95:8 + --> $DIR/syntax-errors.rs:88:8 | LL | ( ${ length() } ) => { | ^^^^^^^^^^^^ note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions - --> $DIR/syntax-errors.rs:95:8 + --> $DIR/syntax-errors.rs:88:8 | LL | ( ${ length() } ) => { | ^^^^^^^^^^^^ error: expected one of: `*`, `+`, or `?` - --> $DIR/syntax-errors.rs:95:8 + --> $DIR/syntax-errors.rs:88:8 | LL | ( ${ length() } ) => { | ^^^^^^^^^^^^ -error: expected identifier - --> $DIR/syntax-errors.rs:102:33 +error: meta-variables within meta-variable expressions must be referenced using a dollar sign + --> $DIR/syntax-errors.rs:95:33 | LL | ( $( $i:ident ),* ) => { ${ ignore() } }; | ^^^^^^ error: only unsuffixes integer literals are supported in meta-variable expressions - --> $DIR/syntax-errors.rs:108:33 + --> $DIR/syntax-errors.rs:101:33 | LL | ( $( $i:ident ),* ) => { ${ index(1u32) } }; | ^^^^^ error: meta-variable expression parameter must be wrapped in parentheses - --> $DIR/syntax-errors.rs:114:33 + --> $DIR/syntax-errors.rs:107:33 | LL | ( $( $i:ident ),* ) => { ${ count{i} } }; | ^^^^^ error: expected identifier - --> $DIR/syntax-errors.rs:120:31 + --> $DIR/syntax-errors.rs:113:31 | LL | ( $( $i:ident ),* ) => { ${ {} } }; | ^^^^^^ +error: meta-variables within meta-variable expressions must be referenced using a dollar sign + --> $DIR/syntax-errors.rs:120:11 + | +LL | ${count(foo)} + | ^^^^^ + +error: meta-variables within meta-variable expressions must be referenced using a dollar sign + --> $DIR/syntax-errors.rs:128:11 + | +LL | ${ignore(bar)} + | ^^^^^^ + error: unrecognized meta-variable expression - --> $DIR/syntax-errors.rs:140:33 + --> $DIR/syntax-errors.rs:135:33 | LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } }; | ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and length @@ -199,39 +199,23 @@ LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } }; error: `count` can not be placed inside the inner-most repetition --> $DIR/syntax-errors.rs:12:24 | -LL | ( $i:ident ) => { ${ count(i) } }; - | ^^^^^^^^^^^^ - -error: expected expression, found `$` - --> $DIR/syntax-errors.rs:17:30 - | -LL | ( $( $i:ident ),* ) => { ${ count($i) } }; - | ^ expected expression -... -LL | curly__rhs_dollar__round!(a, b, c); - | ---------------------------------- in this macro invocation - | - = note: this error originates in the macro `curly__rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info) +LL | ( $i:ident ) => { ${ count($i) } }; + | ^^^^^^^^^^^^^ -error: expected expression, found `$` - --> $DIR/syntax-errors.rs:23:23 +error: `count` can not be placed inside the inner-most repetition + --> $DIR/syntax-errors.rs:17:24 | LL | ( $i:ident ) => { ${ count($i) } }; - | ^ expected expression -... -LL | curly__rhs_dollar__no_round!(a); - | ------------------------------- in this macro invocation - | - = note: this error originates in the macro `curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) + | ^^^^^^^^^^^^^ error: variable 'i' is still repeating at this depth - --> $DIR/syntax-errors.rs:41:36 + --> $DIR/syntax-errors.rs:34:36 | LL | ( $( $i:ident ),* ) => { count($i) }; | ^^ error: expected expression, found `$` - --> $DIR/syntax-errors.rs:60:9 + --> $DIR/syntax-errors.rs:53:9 | LL | ${count() a b c} | ^ expected expression @@ -242,7 +226,7 @@ LL | extra_garbage_after_metavar!(a); = note: this error originates in the macro `extra_garbage_after_metavar` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found `$` - --> $DIR/syntax-errors.rs:89:30 + --> $DIR/syntax-errors.rs:82:30 | LL | ( $( $i:ident ),* ) => { ${ index(IDX) } }; | ^ expected expression @@ -253,7 +237,7 @@ LL | metavar_depth_is_not_literal!(a); = note: this error originates in the macro `metavar_depth_is_not_literal` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found `$` - --> $DIR/syntax-errors.rs:102:30 + --> $DIR/syntax-errors.rs:95:30 | LL | ( $( $i:ident ),* ) => { ${ ignore() } }; | ^ expected expression @@ -264,7 +248,7 @@ LL | metavar_token_without_ident!(a); = note: this error originates in the macro `metavar_token_without_ident` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found `$` - --> $DIR/syntax-errors.rs:108:30 + --> $DIR/syntax-errors.rs:101:30 | LL | ( $( $i:ident ),* ) => { ${ index(1u32) } }; | ^ expected expression @@ -275,7 +259,7 @@ LL | metavar_with_literal_suffix!(a); = note: this error originates in the macro `metavar_with_literal_suffix` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found `$` - --> $DIR/syntax-errors.rs:114:30 + --> $DIR/syntax-errors.rs:107:30 | LL | ( $( $i:ident ),* ) => { ${ count{i} } }; | ^ expected expression @@ -286,7 +270,7 @@ LL | metavar_without_parens!(a); = note: this error originates in the macro `metavar_without_parens` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found `$` - --> $DIR/syntax-errors.rs:120:30 + --> $DIR/syntax-errors.rs:113:30 | LL | ( $( $i:ident ),* ) => { ${ {} } }; | ^ expected expression @@ -296,20 +280,30 @@ LL | open_brackets_without_tokens!(a); | = note: this error originates in the macro `open_brackets_without_tokens` (in Nightly builds, run with -Z macro-backtrace for more info) -error: variable `foo` is not recognized in meta-variable expression - --> $DIR/syntax-errors.rs:127:17 +error: expected expression, found `$` + --> $DIR/syntax-errors.rs:120:9 | LL | ${count(foo)} - | ^^^ + | ^ expected expression +... +LL | unknown_count_ident!(a); + | ----------------------- in this macro invocation + | + = note: this error originates in the macro `unknown_count_ident` (in Nightly builds, run with -Z macro-backtrace for more info) -error: variable `bar` is not recognized in meta-variable expression - --> $DIR/syntax-errors.rs:134:18 +error: expected expression, found `$` + --> $DIR/syntax-errors.rs:128:9 | LL | ${ignore(bar)} - | ^^^ + | ^ expected expression +... +LL | unknown_ignore_ident!(a); + | ------------------------ in this macro invocation + | + = note: this error originates in the macro `unknown_ignore_ident` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found `$` - --> $DIR/syntax-errors.rs:140:30 + --> $DIR/syntax-errors.rs:135:30 | LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } }; | ^ expected expression @@ -320,7 +314,7 @@ LL | unknown_metavar!(a); = note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `i` in this scope - --> $DIR/syntax-errors.rs:29:36 + --> $DIR/syntax-errors.rs:22:36 | LL | ( $( $i:ident ),* ) => { count(i) }; | ^ not found in this scope @@ -331,7 +325,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c); = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `i` in this scope - --> $DIR/syntax-errors.rs:35:29 + --> $DIR/syntax-errors.rs:28:29 | LL | ( $i:ident ) => { count(i) }; | ^ not found in this scope @@ -342,13 +336,13 @@ LL | no_curly__no_rhs_dollar__no_round!(a); = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `a` in this scope - --> $DIR/syntax-errors.rs:153:37 + --> $DIR/syntax-errors.rs:147:37 | LL | no_curly__rhs_dollar__no_round!(a); | ^ not found in this scope error[E0425]: cannot find function `count` in this scope - --> $DIR/syntax-errors.rs:29:30 + --> $DIR/syntax-errors.rs:22:30 | LL | ( $( $i:ident ),* ) => { count(i) }; | ^^^^^ not found in this scope @@ -359,7 +353,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c); = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find function `count` in this scope - --> $DIR/syntax-errors.rs:35:23 + --> $DIR/syntax-errors.rs:28:23 | LL | ( $i:ident ) => { count(i) }; | ^^^^^ not found in this scope @@ -370,7 +364,7 @@ LL | no_curly__no_rhs_dollar__no_round!(a); = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find function `count` in this scope - --> $DIR/syntax-errors.rs:46:23 + --> $DIR/syntax-errors.rs:39:23 | LL | ( $i:ident ) => { count($i) }; | ^^^^^ not found in this scope @@ -380,6 +374,6 @@ LL | no_curly__rhs_dollar__no_round!(a); | = note: this error originates in the macro `no_curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 40 previous errors +error: aborting due to 39 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/never_type/never-from-impl-is-reserved.rs b/tests/ui/never_type/never-from-impl-is-reserved.rs index f358e045cf0..97fac59149b 100644 --- a/tests/ui/never_type/never-from-impl-is-reserved.rs +++ b/tests/ui/never_type/never-from-impl-is-reserved.rs @@ -1,7 +1,7 @@ // check that the `for<T> T: From<!>` impl is reserved // revisions: current next -//[next] compile-flags: -Ztrait-solver=next-coherence +//[next] compile-flags: -Znext-solver=coherence #![feature(never_type)] diff --git a/tests/ui/nll/issue-53119.rs b/tests/ui/nll/issue-53119.rs index 015b72367f1..d19a9a0327c 100644 --- a/tests/ui/nll/issue-53119.rs +++ b/tests/ui/nll/issue-53119.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver use std::ops::Deref; diff --git a/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs index 0b30a88fdd4..21dda7b8c9b 100644 --- a/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs +++ b/tests/ui/object-safety/call-when-assoc-ty-is-sized.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver trait Foo { type Bar<'a> diff --git a/tests/ui/packed/dyn-trait.rs b/tests/ui/packed/dyn-trait.rs new file mode 100644 index 00000000000..bb73c26c18a --- /dev/null +++ b/tests/ui/packed/dyn-trait.rs @@ -0,0 +1,21 @@ +// run-pass +use std::ptr::addr_of; + +// When the unsized tail is a `dyn Trait`, its alignments is only dynamically known. This means the +// packed(2) needs to be applied at runtime: the actual alignment of the field is `min(2, +// usual_alignment)`. Here we check that we do this right by comparing size, alignment, and field +// offset before and after unsizing. +fn main() { + #[repr(C, packed(2))] + struct Packed<T: ?Sized>(u8, core::mem::ManuallyDrop<T>); + + let p = Packed(0, core::mem::ManuallyDrop::new(1)); + let p: &Packed<usize> = &p; + let sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) }; + let p: &Packed<dyn Send> = p; + let un_sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let un_sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) }; + assert_eq!(sized, un_sized); + assert_eq!(sized_offset, un_sized_offset); +} diff --git a/tests/ui/panic-handler/panic-handler-duplicate.stderr b/tests/ui/panic-handler/panic-handler-duplicate.stderr index 5c50b7016b2..299847474cd 100644 --- a/tests/ui/panic-handler/panic-handler-duplicate.stderr +++ b/tests/ui/panic-handler/panic-handler-duplicate.stderr @@ -1,14 +1,18 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-duplicate.rs:15:1 | -LL | fn panic2(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic2(info: &PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ | note: the lang item is first defined here --> $DIR/panic-handler-duplicate.rs:10:1 | -LL | fn panic(info: &PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic(info: &PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index ad9addec8eb..48c216ce27e 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -1,8 +1,10 @@ error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-std.rs:8:1 | -LL | fn panic(info: PanicInfo) -> ! { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / fn panic(info: PanicInfo) -> ! { +LL | | loop {} +LL | | } + | |_^ | = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib diff --git a/tests/ui/panics/abort-on-panic.rs b/tests/ui/panics/abort-on-panic.rs index 7fbee85ffd1..ff31fc24317 100644 --- a/tests/ui/panics/abort-on-panic.rs +++ b/tests/ui/panics/abort-on-panic.rs @@ -1,6 +1,6 @@ // run-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![allow(unused_must_use)] #![feature(c_unwind)] diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout index f34a8e9a706..71a7f3c6381 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout @@ -9,3 +9,9 @@ print-type-size padding: 3 bytes print-type-size local `.z`: 4 bytes, alignment: 4 bytes print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes +print-type-size type: `std::mem::ManuallyDrop<i32>`: 4 bytes, alignment: 4 bytes +print-type-size field `.value`: 4 bytes +print-type-size type: `std::mem::MaybeUninit<i32>`: 4 bytes, alignment: 4 bytes +print-type-size variant `MaybeUninit`: 4 bytes +print-type-size field `.uninit`: 0 bytes +print-type-size field `.value`: 4 bytes diff --git a/tests/ui/regions/resolve-re-error-ice.rs b/tests/ui/regions/resolve-re-error-ice.rs index f37b27a82b3..bf6defb9bae 100644 --- a/tests/ui/regions/resolve-re-error-ice.rs +++ b/tests/ui/regions/resolve-re-error-ice.rs @@ -1,8 +1,3 @@ -// check-pass - -// Allow this for now, can remove this UI test when this becomes a hard error. -#![allow(implied_bounds_entailment)] - use std::collections::hash_map::{Keys, HashMap}; use std::marker::PhantomData; @@ -15,6 +10,7 @@ struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>); impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R> { fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements todo!() } } diff --git a/tests/ui/regions/resolve-re-error-ice.stderr b/tests/ui/regions/resolve-re-error-ice.stderr index e7003e1c32f..41c5f0fa92e 100644 --- a/tests/ui/regions/resolve-re-error-ice.stderr +++ b/tests/ui/regions/resolve-re-error-ice.stderr @@ -1,15 +1,37 @@ -Future incompatibility report: Future breakage diagnostic: -warning: impl method assumes more implied bounds than the corresponding trait method - --> $DIR/resolve-re-error-ice.rs:17:16 +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements + --> $DIR/resolve-re-error-ice.rs:12:5 | LL | fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { - | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `Subject<'_, std::collections::hash_map::Keys<'_, K, V>, (), R>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> -note: the lint level is defined here - --> $DIR/resolve-re-error-ice.rs:4:10 +note: first, the lifetime cannot outlive the anonymous lifetime defined here... + --> $DIR/resolve-re-error-ice.rs:5:16 | -LL | #![allow(implied_bounds_entailment)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn key_set(&self) -> Subject<Keys<K, V>, (), R>; + | ^^^^^ +note: ...so that the method type is compatible with trait + --> $DIR/resolve-re-error-ice.rs:12:5 + | +LL | fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `fn(&Subject<'_, _, _, _>) -> Subject<'_, std::collections::hash_map::Keys<'_, _, _>, _, _>` + found `fn(&Subject<'_, _, _, _>) -> Subject<'a, std::collections::hash_map::Keys<'_, _, _>, _, _>` +note: but, the lifetime must be valid for the lifetime `'a` as defined here... + --> $DIR/resolve-re-error-ice.rs:10:6 + | +LL | impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R> + | ^^ +note: ...so that the type `std::collections::hash_map::Keys<'_, K, V>` will meet its required lifetime bounds... + --> $DIR/resolve-re-error-ice.rs:12:5 + | +LL | fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...that is required by this bound + --> $DIR/resolve-re-error-ice.rs:8:29 + | +LL | struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0495`. diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs index c27e8c4b019..c7665affb99 100644 --- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs +++ b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs @@ -1,7 +1,7 @@ // Check that we can manually implement an object-unsafe trait for its trait object. // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // run-pass #![feature(object_safe_for_dispatch)] diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs index 44c598f19cb..37903c21071 100644 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.rs +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs @@ -1,6 +1,6 @@ // revisions: classic coherence next -//[next] compile-flags: -Ztrait-solver=next -//[coherence] compile-flags: -Ztrait-solver=next-coherence +//[next] compile-flags: -Znext-solver +//[coherence] compile-flags: -Znext-solver=coherence //[classic] check-pass //[classic] known-bug: #105782 diff --git a/tests/ui/stable-mir-print/basic_function.rs b/tests/ui/stable-mir-print/basic_function.rs new file mode 100644 index 00000000000..6394edcbb78 --- /dev/null +++ b/tests/ui/stable-mir-print/basic_function.rs @@ -0,0 +1,15 @@ +// compile-flags: -Z unpretty=stable-mir -Z mir-opt-level=3 +// check-pass +// only-x86_64 + +fn foo(i:i32) -> i32 { + i + 1 +} + +fn bar(vec: &mut Vec<i32>) -> Vec<i32> { + let mut new_vec = vec.clone(); + new_vec.push(1); + new_vec +} + +fn main(){} diff --git a/tests/ui/stable-mir-print/basic_function.stdout b/tests/ui/stable-mir-print/basic_function.stdout new file mode 100644 index 00000000000..d9b33a4257c --- /dev/null +++ b/tests/ui/stable-mir-print/basic_function.stdout @@ -0,0 +1,234 @@ +// WARNING: This is highly experimental output it's intended for stable-mir developers only. +// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir. +fn foo(_0: i32) -> i32 { + let mut _0: (i32, bool); +} + bb0: { + _2 = 1 Add const 1_i32 + assert(!move _2 bool),"attempt to compute `{} + {}`, which would overflow", 1, const 1_i32) -> [success: bb1, unwind continue] + } + bb1: { + _0 = move _2 + return + } +fn bar(_0: &mut Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}) -> Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +} { + let mut _0: Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; + let mut _1: &Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; + let _2: (); + let mut _3: &mut Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; +} + bb0: { + _3 = refShared1 + _2 = const <Vec<i32> as Clone>::clone(move _3) -> [return: bb1, unwind continue] + } + bb1: { + _5 = refMut { + kind: TwoPhaseBorrow, +}2 + _4 = const Vec::<i32>::push(move _5, const 1_i32) -> [return: bb2, unwind: bb3] + } + bb2: { + _0 = move _2 + return + } + bb3: { + drop(_2) -> [return: bb4, unwind terminate] + } + bb4: { + resume + } +fn main() -> () { +} + bb0: { + return + } diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs index 406e5c8441e..490d6a2f918 100644 --- a/tests/ui/structs-enums/type-sizes.rs +++ b/tests/ui/structs-enums/type-sizes.rs @@ -4,7 +4,6 @@ #![allow(dead_code)] #![feature(never_type)] #![feature(pointer_is_aligned)] -#![feature(ptr_from_ref)] #![feature(strict_provenance)] use std::mem::size_of; diff --git a/tests/ui/traits/deny-builtin-object-impl.rs b/tests/ui/traits/deny-builtin-object-impl.rs index dce03a43b68..d0eb6382e41 100644 --- a/tests/ui/traits/deny-builtin-object-impl.rs +++ b/tests/ui/traits/deny-builtin-object-impl.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(rustc_attrs)] diff --git a/tests/ui/traits/issue-102989.rs b/tests/ui/traits/issue-102989.rs index 216cd78e56f..f1ecee0a552 100644 --- a/tests/ui/traits/issue-102989.rs +++ b/tests/ui/traits/issue-102989.rs @@ -7,6 +7,7 @@ trait Sized { } //~ ERROR found duplicate lang item `sized` fn ref_Struct(self: &Struct, f: &u32) -> &u32 { //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR cannot find type `Struct` in this scope + //~| ERROR mismatched types let x = x << 1; //~^ ERROR cannot find value `x` in this scope } diff --git a/tests/ui/traits/issue-102989.stderr b/tests/ui/traits/issue-102989.stderr index 7d0098fe885..40e49df2b2d 100644 --- a/tests/ui/traits/issue-102989.stderr +++ b/tests/ui/traits/issue-102989.stderr @@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | ^^^^^^ not found in this scope error[E0425]: cannot find value `x` in this scope - --> $DIR/issue-102989.rs:10:13 + --> $DIR/issue-102989.rs:11:13 | LL | let x = x << 1; | ^ help: a local variable with a similar name exists: `f` @@ -22,13 +22,27 @@ error[E0152]: found duplicate lang item `sized` --> $DIR/issue-102989.rs:5:1 | LL | trait Sized { } - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `core` (which `std` depends on) = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib = note: second definition in the local crate (`issue_102989`) -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/issue-102989.rs:7:42 + | +LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + | ---------- ^^^^ expected `&u32`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | +help: consider returning the local binding `f` + | +LL ~ let x = x << 1; +LL + f + | + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0152, E0412, E0425. +Some errors have detailed explanations: E0152, E0308, E0412, E0425. For more information about an error, try `rustc --explain E0152`. diff --git a/tests/ui/traits/issue-24010.rs b/tests/ui/traits/issue-24010.rs index fd7d6751d5c..1eaa5bf0c67 100644 --- a/tests/ui/traits/issue-24010.rs +++ b/tests/ui/traits/issue-24010.rs @@ -1,6 +1,6 @@ // run-pass // revisions: classic next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver trait Foo: Fn(i32) -> i32 + Send {} diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr index a53879657f5..8f5b937e586 100644 --- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -50,7 +50,7 @@ LL | is_send((8, TestType)); | required by a bound introduced by this call | = help: within `({integer}, dummy1c::TestType)`, the trait `Send` is not implemented for `dummy1c::TestType` - = note: required because it appears within the type `({integer}, TestType)` + = note: required because it appears within the type `({integer}, dummy1c::TestType)` note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 | @@ -67,7 +67,7 @@ LL | is_send(Box::new(TestType)); | = note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied = note: required for `Unique<dummy2::TestType>` to implement `Send` -note: required because it appears within the type `Box<TestType>` +note: required because it appears within the type `Box<dummy2::TestType>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 @@ -88,13 +88,13 @@ LL | is_send(Box::new(Outer2(TestType))); | required by a bound introduced by this call | = help: within `Outer2<dummy3::TestType>`, the trait `Send` is not implemented for `dummy3::TestType` -note: required because it appears within the type `Outer2<TestType>` +note: required because it appears within the type `Outer2<dummy3::TestType>` --> $DIR/negated-auto-traits-error.rs:12:8 | LL | struct Outer2<T>(T); | ^^^^^^ = note: required for `Unique<Outer2<dummy3::TestType>>` to implement `Send` -note: required because it appears within the type `Box<Outer2<TestType>>` +note: required because it appears within the type `Box<Outer2<dummy3::TestType>>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr deleted file mode 100644 index e4922b0c3e9..00000000000 --- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0284]: type annotations needed: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc` - --> $DIR/generalize-proj-new-universe-index-2.rs:74:5 - | -LL | bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/new-solver/alias-bound-preference.rs b/tests/ui/traits/next-solver/alias-bound-preference.rs index e4e0f634ef7..1c6e1209610 100644 --- a/tests/ui/traits/new-solver/alias-bound-preference.rs +++ b/tests/ui/traits/next-solver/alias-bound-preference.rs @@ -1,5 +1,5 @@ // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // run-pass // A test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/45. diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs index ab84e3875e2..565bfe1186e 100644 --- a/tests/ui/traits/new-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Makes sure that alias bounds are not unsound! diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr index b09c22f3f41..b09c22f3f41 100644 --- a/tests/ui/traits/new-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr diff --git a/tests/ui/traits/new-solver/alias-eq-in-canonical-response.rs b/tests/ui/traits/next-solver/alias-eq-in-canonical-response.rs index 4bfb6323a53..aa7c94791a7 100644 --- a/tests/ui/traits/new-solver/alias-eq-in-canonical-response.rs +++ b/tests/ui/traits/next-solver/alias-eq-in-canonical-response.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Foo { type Gat<'a> diff --git a/tests/ui/traits/new-solver/alias-relate/deeply-nested-no-hang.rs b/tests/ui/traits/next-solver/alias-relate/deeply-nested-no-hang.rs index 4abce7b57d5..91cfda37adf 100644 --- a/tests/ui/traits/new-solver/alias-relate/deeply-nested-no-hang.rs +++ b/tests/ui/traits/next-solver/alias-relate/deeply-nested-no-hang.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // regression test for trait-system-refactor-initiative#68 trait Identity { type Assoc: ?Sized; diff --git a/tests/ui/traits/new-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs b/tests/ui/traits/next-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs index 29a73e1a967..88bbd13f9a2 100644 --- a/tests/ui/traits/new-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs +++ b/tests/ui/traits/next-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver fn test<T: Iterator>(x: T::Item) -> impl Sized { x diff --git a/tests/ui/traits/new-solver/alias-sub.rs b/tests/ui/traits/next-solver/alias-sub.rs index 30c1981a92e..f7f23a024dd 100644 --- a/tests/ui/traits/new-solver/alias-sub.rs +++ b/tests/ui/traits/next-solver/alias-sub.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Trait { diff --git a/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs b/tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs index dc726ba51f9..04d1b949692 100644 --- a/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs +++ b/tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check that a goal such as `alias-eq(<T as TraitB>::Assoc<bool>, <T as TraitB>::Assoc<?0>)` // succeeds with a constraint that `?0 = bool` diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs b/tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs index 3c7fc7403b1..48157192a10 100644 --- a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs +++ b/tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // (should not pass, should be turned into a coherence-only test) diff --git a/tests/ui/traits/new-solver/alias_eq_simple.rs b/tests/ui/traits/next-solver/alias_eq_simple.rs index 6792cf3ce35..21ad1a4fa3c 100644 --- a/tests/ui/traits/new-solver/alias_eq_simple.rs +++ b/tests/ui/traits/next-solver/alias_eq_simple.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // test that the new solver can handle `alias-eq(<i32 as TraitB>::Assoc, u32)` diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs index 204f6e8b071..4717aa80499 100644 --- a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs +++ b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check that a `alias-eq(<?a as TraitB>::Assoc, <?b as TraitB>::Assoc)` goal fails // during coherence. We must not incorrectly constrain `?a` and `?b` to be diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr index 8c6840f72a7..8c6840f72a7 100644 --- a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr +++ b/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr diff --git a/tests/ui/traits/new-solver/array-default.rs b/tests/ui/traits/next-solver/array-default.rs index 5077137b09b..6bfbce7d433 100644 --- a/tests/ui/traits/new-solver/array-default.rs +++ b/tests/ui/traits/next-solver/array-default.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn has_default<const N: usize>() where [(); N]: Default {} diff --git a/tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs b/tests/ui/traits/next-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs index 826e8c1e0b1..4401abd0783 100644 --- a/tests/ui/traits/new-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs +++ b/tests/ui/traits/next-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // Checks that we do not get ambiguity by considering an impl diff --git a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.rs index 1dca86d3630..1edc1a8c58c 100644 --- a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs +++ b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // In the new solver, we are trying to select `<?0 as Iterator>::Item: Debug`, // which, naively can be unified with every impl of `Debug` if we're not careful. diff --git a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr index 4bd55ee80c6..4bd55ee80c6 100644 --- a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr +++ b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr diff --git a/tests/ui/traits/new-solver/async.fail.stderr b/tests/ui/traits/next-solver/async.fail.stderr index ebd0ada2604..ebd0ada2604 100644 --- a/tests/ui/traits/new-solver/async.fail.stderr +++ b/tests/ui/traits/next-solver/async.fail.stderr diff --git a/tests/ui/traits/new-solver/async.rs b/tests/ui/traits/next-solver/async.rs index 155b71eb749..5833c052234 100644 --- a/tests/ui/traits/new-solver/async.rs +++ b/tests/ui/traits/next-solver/async.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // edition: 2021 // revisions: pass fail //[pass] check-pass diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr index ac05dfb2d46..ac05dfb2d46 100644 --- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr +++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs index 6b54718e35c..d4010a55244 100644 --- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs +++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // edition: 2021 // revisions: pass fail //[pass] check-pass diff --git a/tests/ui/traits/new-solver/borrowck-error.rs b/tests/ui/traits/next-solver/borrowck-error.rs index 4787a2c7e11..25f1445941b 100644 --- a/tests/ui/traits/new-solver/borrowck-error.rs +++ b/tests/ui/traits/next-solver/borrowck-error.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver use std::collections::HashMap; diff --git a/tests/ui/traits/new-solver/borrowck-error.stderr b/tests/ui/traits/next-solver/borrowck-error.stderr index 4cb41e7d597..4cb41e7d597 100644 --- a/tests/ui/traits/new-solver/borrowck-error.stderr +++ b/tests/ui/traits/next-solver/borrowck-error.stderr diff --git a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs index ba473653ecf..eab25214d63 100644 --- a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.rs +++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(fn_traits)] #![feature(unboxed_closures)] diff --git a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr index 08047852f20..08047852f20 100644 --- a/tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr +++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr diff --git a/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs b/tests/ui/traits/next-solver/canonical-int-var-eq-in-response.rs index 4b013983a4a..ea2740523c9 100644 --- a/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs +++ b/tests/ui/traits/next-solver/canonical-int-var-eq-in-response.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Mirror { diff --git a/tests/ui/traits/new-solver/canonical-ty-var-eq-in-response.rs b/tests/ui/traits/next-solver/canonical-ty-var-eq-in-response.rs index d1c6b1077e8..b1e4a9e58cf 100644 --- a/tests/ui/traits/new-solver/canonical-ty-var-eq-in-response.rs +++ b/tests/ui/traits/next-solver/canonical-ty-var-eq-in-response.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Mirror { type Item; diff --git a/tests/ui/traits/new-solver/canonicalize-effect-var.rs b/tests/ui/traits/next-solver/canonicalize-effect-var.rs index 35b69ed1a6b..4a13ba37303 100644 --- a/tests/ui/traits/new-solver/canonicalize-effect-var.rs +++ b/tests/ui/traits/next-solver/canonicalize-effect-var.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(effects)] diff --git a/tests/ui/traits/new-solver/cast-checks-handling-projections.rs b/tests/ui/traits/next-solver/cast-checks-handling-projections.rs index 3b261062f78..406b4dc1211 100644 --- a/tests/ui/traits/new-solver/cast-checks-handling-projections.rs +++ b/tests/ui/traits/next-solver/cast-checks-handling-projections.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn main() { diff --git a/tests/ui/traits/new-solver/closure-inference-guidance.rs b/tests/ui/traits/next-solver/closure-inference-guidance.rs index d2ad0cc0316..8175b92f882 100644 --- a/tests/ui/traits/new-solver/closure-inference-guidance.rs +++ b/tests/ui/traits/next-solver/closure-inference-guidance.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn foo(i: isize) -> isize { i + 1 } diff --git a/tests/ui/traits/next-solver/closure-signature-inference-2.rs b/tests/ui/traits/next-solver/closure-signature-inference-2.rs new file mode 100644 index 00000000000..8fece7ba91f --- /dev/null +++ b/tests/ui/traits/next-solver/closure-signature-inference-2.rs @@ -0,0 +1,21 @@ +// compile-flags: -Znext-solver +// check-pass + +fn map<T: Default, U, F: FnOnce(T) -> U>(f: F) { + f(T::default()); +} + +fn main() { + map::<i32, _ /* ?U */, _ /* ?F */>(|x| x.to_string()); + // PREVIOUSLY when confirming the `map` call, we register: + // + // (1.) ?F: FnOnce<(i32,)> + // (2.) <?F as FnOnce<(i32,)>>::Output projects-to ?U + // + // While (1.) is ambiguous, (2.) immediately gets processed + // and we infer `?U := <?F as FnOnce<(i32,)>>::Output`. + // + // Thus, the only pending obligation that remains is (1.). + // Since it is a trait obligation, we don't use it to deduce + // the closure signature, and we fail! +} diff --git a/tests/ui/traits/next-solver/closure-signature-inference.rs b/tests/ui/traits/next-solver/closure-signature-inference.rs new file mode 100644 index 00000000000..355fc790229 --- /dev/null +++ b/tests/ui/traits/next-solver/closure-signature-inference.rs @@ -0,0 +1,15 @@ +// compile-flags: -Znext-solver +// check-pass + +struct A; +impl A { + fn hi(self) {} +} + +fn hello() -> Result<(A,), ()> { + Err(()) +} + +fn main() { + let x = hello().map(|(x,)| x.hi()); +} diff --git a/tests/ui/traits/new-solver/closure-substs-ambiguity.rs b/tests/ui/traits/next-solver/closure-substs-ambiguity.rs index 48432f4020f..cc9ee58f27f 100644 --- a/tests/ui/traits/new-solver/closure-substs-ambiguity.rs +++ b/tests/ui/traits/next-solver/closure-substs-ambiguity.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn main() { diff --git a/tests/ui/traits/new-solver/coherence/issue-102048.rs b/tests/ui/traits/next-solver/coherence/issue-102048.rs index 11636bfeb55..600e63d4d44 100644 --- a/tests/ui/traits/new-solver/coherence/issue-102048.rs +++ b/tests/ui/traits/next-solver/coherence/issue-102048.rs @@ -17,7 +17,7 @@ // that to `i32`. We then try to unify `i32` from `impl1` with `u32` from `impl2` which fails, // causing coherence to consider these two impls distinct. -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver pub trait Trait<T> {} pub trait WithAssoc1<'a> { diff --git a/tests/ui/traits/new-solver/coherence/issue-102048.stderr b/tests/ui/traits/next-solver/coherence/issue-102048.stderr index 4e93ae28496..4e93ae28496 100644 --- a/tests/ui/traits/new-solver/coherence/issue-102048.stderr +++ b/tests/ui/traits/next-solver/coherence/issue-102048.stderr diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs index b39ae0333ad..af471b5e193 100644 --- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Coherence should handle overflow while normalizing for // `trait_ref_is_knowable` correctly. diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr index e3c0dabf549..e3c0dabf549 100644 --- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-1.rs index c38e3baf5b4..e6ffb55b441 100644 --- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-1.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Id { diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-2.rs index 2d53266db09..d16f9d22ce0 100644 --- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-2.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass use std::future::{Future, IntoFuture}; diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs index 2f27de4e4f4..90de6b847d0 100644 --- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Id { diff --git a/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr b/tests/ui/traits/next-solver/const-param-placeholder.fail.stderr index 163710706b0..163710706b0 100644 --- a/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr +++ b/tests/ui/traits/next-solver/const-param-placeholder.fail.stderr diff --git a/tests/ui/traits/new-solver/const-param-placeholder.rs b/tests/ui/traits/next-solver/const-param-placeholder.rs index a83102a4cdd..c22bc54cfca 100644 --- a/tests/ui/traits/new-solver/const-param-placeholder.rs +++ b/tests/ui/traits/next-solver/const-param-placeholder.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // revisions: pass fail //[pass] check-pass diff --git a/tests/ui/traits/new-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr index 14e67727d0b..14e67727d0b 100644 --- a/tests/ui/traits/new-solver/coroutine.fail.stderr +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr diff --git a/tests/ui/traits/new-solver/coroutine.rs b/tests/ui/traits/next-solver/coroutine.rs index af16f70fb56..727e2356859 100644 --- a/tests/ui/traits/new-solver/coroutine.rs +++ b/tests/ui/traits/next-solver/coroutine.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // edition: 2021 // revisions: pass fail //[pass] check-pass diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.rs index 07c7d4fb29c..947b52da7c2 100644 --- a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Proving `W<?0>: Trait` instantiates `?0` with `(W<?1>, W<?2>)` and then // proves `W<?1>: Trait` and `W<?2>: Trait`, resulting in a coinductive cycle. diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr index 150100f2c53..150100f2c53 100644 --- a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs index 0cd14f05c8d..a3c07b98722 100644 --- a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(rustc_attrs)] // This test is incredibly subtle. At its core the goal is to get a coinductive cycle, diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr index d4932191791..d4932191791 100644 --- a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs index 5617e45adf6..0f19bc2c592 100644 --- a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs +++ b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(rustc_attrs)] // Test that having both an inductive and a coinductive cycle diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr index a3404da51f0..a3404da51f0 100644 --- a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr +++ b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs index 27906392340..c7e2e2d5e04 100644 --- a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs +++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(rustc_attrs)] // Check that we correctly rerun the trait solver for heads of cycles, diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr index 7b3075f4ff3..7b3075f4ff3 100644 --- a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr +++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs index cda98789886..fdc7afea378 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(trivial_bounds, marker_trait_attr)] #![allow(trivial_bounds)] // This previously triggered a bug in the provisional cache. diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr index acacaf6a331..acacaf6a331 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-ok.rs index d4851eb694b..d6d9762bb73 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-ok.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(trivial_bounds, marker_trait_attr)] #![allow(trivial_bounds)] diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs b/tests/ui/traits/next-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs index 530e6d0ecf3..a32f7a13a03 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(rustc_attrs, marker_trait_attr)] #[rustc_coinductive] trait Trait {} diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs index 062c6ae98d5..efeb8d0231e 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // This currently hangs if we do not erase constraints from // overflow. diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr index 42451920744..42451920744 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs index f06b98a79cf..f2f6e009d54 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(rustc_attrs, trivial_bounds)] // We have to be careful here: diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr index 859b3f3f1c7..859b3f3f1c7 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr diff --git a/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs b/tests/ui/traits/next-solver/cycles/leak-check-coinductive-cycle.rs index a6d31872673..9ff362ec882 100644 --- a/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs +++ b/tests/ui/traits/next-solver/cycles/leak-check-coinductive-cycle.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(rustc_attrs)] diff --git a/tests/ui/traits/new-solver/cycles/provisional-result-done.rs b/tests/ui/traits/next-solver/cycles/provisional-result-done.rs index 589d34dd7ab..0f3b84ce520 100644 --- a/tests/ui/traits/new-solver/cycles/provisional-result-done.rs +++ b/tests/ui/traits/next-solver/cycles/provisional-result-done.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // This tests checks that we update results in the provisional cache when diff --git a/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs index 51f62bc2312..08f26686b2f 100644 --- a/tests/ui/traits/new-solver/deduce-closure-signature-after-normalization.rs +++ b/tests/ui/traits/next-solver/deduce-closure-signature-after-normalization.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Foo { diff --git a/tests/ui/traits/new-solver/deduce-ty-from-object.rs b/tests/ui/traits/next-solver/deduce-ty-from-object.rs index 7398bce7b61..b627fd720e3 100644 --- a/tests/ui/traits/new-solver/deduce-ty-from-object.rs +++ b/tests/ui/traits/next-solver/deduce-ty-from-object.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver fn main() { let x: Box<dyn Iterator<Item = ()>> = Box::new(std::iter::empty()); diff --git a/tests/ui/traits/new-solver/dedup-regions.rs b/tests/ui/traits/next-solver/dedup-regions.rs index f376f39a5a6..dd406333f27 100644 --- a/tests/ui/traits/new-solver/dedup-regions.rs +++ b/tests/ui/traits/next-solver/dedup-regions.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass struct A(*mut ()); diff --git a/tests/ui/traits/new-solver/destruct.rs b/tests/ui/traits/next-solver/destruct.rs index 30d7777b78a..5093344e4b6 100644 --- a/tests/ui/traits/new-solver/destruct.rs +++ b/tests/ui/traits/next-solver/destruct.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(const_trait_impl)] diff --git a/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs b/tests/ui/traits/next-solver/dont-coerce-infer-to-dyn.rs index c2ac80459ca..da07869f3b6 100644 --- a/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs +++ b/tests/ui/traits/next-solver/dont-coerce-infer-to-dyn.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass use std::fmt::Display; diff --git a/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs b/tests/ui/traits/next-solver/dont-elaborate-for-projections.rs index e608250063c..9123871db97 100644 --- a/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs +++ b/tests/ui/traits/next-solver/dont-elaborate-for-projections.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Iter<'a, I: 'a>: Iterator<Item = &'a I> {} diff --git a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs index b9798c79d5e..1e1ef8c23a2 100644 --- a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next-coherence +// compile-flags: -Znext-solver=coherence // Makes sure we don't ICE on associated const projection when the feature gate // is not enabled, since we should avoid encountering ICEs on stable if possible. diff --git a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr index 368f5cd0c3b..368f5cd0c3b 100644 --- a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr diff --git a/tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs b/tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs index b241e3bf865..a85098a95ad 100644 --- a/tests/ui/traits/new-solver/dont-loop-fulfill-on-region-constraints.rs +++ b/tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Eq<'a, 'b, T> {} diff --git a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs index 19a6fa990ff..fd1682cd61a 100644 --- a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs +++ b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Test that we don't incorrectly leak unconstrained inference variables // if the projection contained an error. This caused an ICE in writeback. diff --git a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr index 576ede52aff..576ede52aff 100644 --- a/tests/ui/traits/new-solver/dont-normalize-proj-with-error.stderr +++ b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/next-solver/dont-remap-tait-substs.rs index 309bee8aa8c..b089f0df3c7 100644 --- a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs +++ b/tests/ui/traits/next-solver/dont-remap-tait-substs.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // Makes sure we don't prepopulate the MIR typeck of `define` diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr index 076dab29d89..076dab29d89 100644 --- a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr +++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr diff --git a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs index 08f14d7494d..a1f38e69e53 100644 --- a/tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs +++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs @@ -1,5 +1,5 @@ // revisions: is_send not_send -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver //[is_send] check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs b/tests/ui/traits/next-solver/dyn-any-dont-prefer-impl.rs index af35a6195e0..bb1c24a001f 100644 --- a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs +++ b/tests/ui/traits/next-solver/dyn-any-dont-prefer-impl.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // Test that selection prefers the builtin trait object impl for `Any` diff --git a/tests/ui/traits/new-solver/elaborate-item-bounds.rs b/tests/ui/traits/next-solver/elaborate-item-bounds.rs index 076aefcf8fc..0f1f6c0445c 100644 --- a/tests/ui/traits/new-solver/elaborate-item-bounds.rs +++ b/tests/ui/traits/next-solver/elaborate-item-bounds.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Foo { diff --git a/tests/ui/traits/new-solver/equating-projection-cyclically.rs b/tests/ui/traits/next-solver/equating-projection-cyclically.rs index 845597e9ce1..e7c80cfd797 100644 --- a/tests/ui/traits/new-solver/equating-projection-cyclically.rs +++ b/tests/ui/traits/next-solver/equating-projection-cyclically.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Test { type Assoc; diff --git a/tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs b/tests/ui/traits/next-solver/escaping-bound-vars-in-writeback-normalization.rs index 29784c32a1b..77bedc351e7 100644 --- a/tests/ui/traits/new-solver/escaping-bound-vars-in-writeback-normalization.rs +++ b/tests/ui/traits/next-solver/escaping-bound-vars-in-writeback-normalization.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Trivial { diff --git a/tests/ui/traits/new-solver/float-canonical.rs b/tests/ui/traits/next-solver/float-canonical.rs index b8748cd433b..90d75bacbf4 100644 --- a/tests/ui/traits/new-solver/float-canonical.rs +++ b/tests/ui/traits/next-solver/float-canonical.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn foo(x: f64) { diff --git a/tests/ui/traits/new-solver/fn-trait-closure.rs b/tests/ui/traits/next-solver/fn-trait-closure.rs index bd65737ee39..cd2ae1f6fb2 100644 --- a/tests/ui/traits/new-solver/fn-trait-closure.rs +++ b/tests/ui/traits/next-solver/fn-trait-closure.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn require_fn(_: impl Fn() -> i32) {} diff --git a/tests/ui/traits/new-solver/fn-trait.rs b/tests/ui/traits/next-solver/fn-trait.rs index 0a19e626553..1e3d8a21c7c 100644 --- a/tests/ui/traits/new-solver/fn-trait.rs +++ b/tests/ui/traits/next-solver/fn-trait.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver fn require_fn(_: impl Fn() -> i32) {} diff --git a/tests/ui/traits/new-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr index e33487235e6..e33487235e6 100644 --- a/tests/ui/traits/new-solver/fn-trait.stderr +++ b/tests/ui/traits/next-solver/fn-trait.stderr diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs index b0b9b6bbd20..4a70bd5f815 100644 --- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs +++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-1.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // A minimization of an ambiguity when using typenum. See diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs index 94d645a9859..70758e7deaa 100644 --- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs +++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // known-bug: trait-system-refactor-initiative#60 // Generalizing a projection containing an inference variable diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr new file mode 100644 index 00000000000..4548ab1e297 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr @@ -0,0 +1,19 @@ +error[E0284]: type annotations needed + --> $DIR/generalize-proj-new-universe-index-2.rs:74:5 + | +LL | bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound` + | + = note: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc == _` +note: required by a bound in `bound` + --> $DIR/generalize-proj-new-universe-index-2.rs:69:21 + | +LL | fn bound<T: ?Sized, U: ?Sized, V: ?Sized>() + | ----- required by a bound in this function +LL | where +LL | T: WithAssoc<U, Assoc = V>, + | ^^^^^^^^^ required by this bound in `bound` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.next.stderr b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr index ad8b24a39c7..ad8b24a39c7 100644 --- a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.next.stderr +++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr diff --git a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.rs b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs index 02ac091c0a8..e51508d684f 100644 --- a/tests/ui/traits/new-solver/generalize/occurs-check-nested-alias.rs +++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs @@ -3,7 +3,7 @@ // Currently always fails to generalize the outer alias, even if it // is treated as rigid by `alias-relate`. -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[next] known-bug: trait-system-refactor-initiative#8 #![crate_type = "lib"] #![allow(unused)] diff --git a/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs b/tests/ui/traits/next-solver/higher-ranked-dyn-bounds.rs index c886aeeda3e..b87210d7fb3 100644 --- a/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs +++ b/tests/ui/traits/next-solver/higher-ranked-dyn-bounds.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Trait<'a> { diff --git a/tests/ui/traits/new-solver/int-var-alias-eq.rs b/tests/ui/traits/next-solver/int-var-alias-eq.rs index 790197e2d97..26ba7f8e511 100644 --- a/tests/ui/traits/new-solver/int-var-alias-eq.rs +++ b/tests/ui/traits/next-solver/int-var-alias-eq.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // HIR typeck ends up equating `<?0i as Add>::Output == ?0i`. // Want to make sure that we emit an alias-eq goal for this, diff --git a/tests/ui/traits/new-solver/int-var-is-send.rs b/tests/ui/traits/next-solver/int-var-is-send.rs index 083aa90e1f6..d8b963f2008 100644 --- a/tests/ui/traits/new-solver/int-var-is-send.rs +++ b/tests/ui/traits/next-solver/int-var-is-send.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn needs_send(_: impl Send) {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs new file mode 100644 index 00000000000..10fb7d525b7 --- /dev/null +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -0,0 +1,22 @@ +// compile-flags: -Znext-solver +// +// This is a gnarly test but I don't know how to minimize it, frankly. + +#![feature(lazy_type_alias)] +//~^ WARN the feature `lazy_type_alias` is incomplete + +trait ToUnit<'a> { + type Unit; +} + +trait Overlap<T> {} + +type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; + +impl<T> Overlap<T> for T {} + +impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} +//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)` +//~| ERROR cannot find type `Missing` in this scope + +fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr new file mode 100644 index 00000000000..c16a48d5f15 --- /dev/null +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -0,0 +1,36 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/issue-118950-root-region.rs:18:55 + | +LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} + | ^^^^^^^ not found in this scope + +warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-118950-root-region.rs:5:12 + | +LL | #![feature(lazy_type_alias)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information + = note: `#[warn(incomplete_features)]` on by default + +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }) +error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)` + --> $DIR/issue-118950-root-region.rs:18:1 + | +LL | impl<T> Overlap<T> for T {} + | ------------------------ first implementation here +LL | +LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)` + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0119, E0412. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/new-solver/iter-filter-projection.rs b/tests/ui/traits/next-solver/iter-filter-projection.rs index 8fb62323aa5..f948831ad52 100644 --- a/tests/ui/traits/new-solver/iter-filter-projection.rs +++ b/tests/ui/traits/next-solver/iter-filter-projection.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass use std::{iter, slice}; diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-1.rs b/tests/ui/traits/next-solver/lazy-nested-obligations-1.rs index af00cbb3ba8..f9e73a93c27 100644 --- a/tests/ui/traits/new-solver/lazy-nested-obligations-1.rs +++ b/tests/ui/traits/next-solver/lazy-nested-obligations-1.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Issue 94358 fn foo<C>(_: C) diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs b/tests/ui/traits/next-solver/lazy-nested-obligations-2.rs index 20f504928c7..b85f9d9736c 100644 --- a/tests/ui/traits/new-solver/lazy-nested-obligations-2.rs +++ b/tests/ui/traits/next-solver/lazy-nested-obligations-2.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass pub trait With { diff --git a/tests/ui/traits/new-solver/lazy-nested-obligations-3.rs b/tests/ui/traits/next-solver/lazy-nested-obligations-3.rs index baf39957240..5fb4832dd08 100644 --- a/tests/ui/traits/new-solver/lazy-nested-obligations-3.rs +++ b/tests/ui/traits/next-solver/lazy-nested-obligations-3.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Issue 96750 use std::marker::PhantomData; diff --git a/tests/ui/traits/new-solver/member-constraints-in-root-universe.rs b/tests/ui/traits/next-solver/member-constraints-in-root-universe.rs index 97c44305864..16e95e94ce5 100644 --- a/tests/ui/traits/new-solver/member-constraints-in-root-universe.rs +++ b/tests/ui/traits/next-solver/member-constraints-in-root-universe.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Trait { diff --git a/tests/ui/traits/new-solver/more-object-bound.rs b/tests/ui/traits/next-solver/more-object-bound.rs index bb730b18ef7..8522f034d87 100644 --- a/tests/ui/traits/new-solver/more-object-bound.rs +++ b/tests/ui/traits/next-solver/more-object-bound.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // From #80800 trait SuperTrait { diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr index e3be2931e12..e3be2931e12 100644 --- a/tests/ui/traits/new-solver/more-object-bound.stderr +++ b/tests/ui/traits/next-solver/more-object-bound.stderr diff --git a/tests/ui/traits/new-solver/negative-coherence-bounds.rs b/tests/ui/traits/next-solver/negative-coherence-bounds.rs index 5436b02c3de..5436b02c3de 100644 --- a/tests/ui/traits/new-solver/negative-coherence-bounds.rs +++ b/tests/ui/traits/next-solver/negative-coherence-bounds.rs diff --git a/tests/ui/traits/new-solver/negative-coherence-bounds.stderr b/tests/ui/traits/next-solver/negative-coherence-bounds.stderr index 4127f51f56d..4127f51f56d 100644 --- a/tests/ui/traits/new-solver/negative-coherence-bounds.stderr +++ b/tests/ui/traits/next-solver/negative-coherence-bounds.stderr diff --git a/tests/ui/traits/new-solver/nested-alias-bound.rs b/tests/ui/traits/next-solver/nested-alias-bound.rs index c365902dbe5..2e3de0ac66d 100644 --- a/tests/ui/traits/new-solver/nested-alias-bound.rs +++ b/tests/ui/traits/next-solver/nested-alias-bound.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait A { diff --git a/tests/ui/traits/new-solver/nested-obligations-with-bound-vars-gat.rs b/tests/ui/traits/next-solver/nested-obligations-with-bound-vars-gat.rs index 92bad959095..94c6c285680 100644 --- a/tests/ui/traits/new-solver/nested-obligations-with-bound-vars-gat.rs +++ b/tests/ui/traits/next-solver/nested-obligations-with-bound-vars-gat.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Issue 96230 use std::fmt::Debug; diff --git a/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs b/tests/ui/traits/next-solver/normalize-async-closure-in-trait.rs index cc16cc87169..b58db2be841 100644 --- a/tests/ui/traits/new-solver/normalize-async-closure-in-trait.rs +++ b/tests/ui/traits/next-solver/normalize-async-closure-in-trait.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // edition:2021 diff --git a/tests/ui/traits/new-solver/normalize-param-env-1.rs b/tests/ui/traits/next-solver/normalize-param-env-1.rs index b02a5d62330..92d4051378b 100644 --- a/tests/ui/traits/new-solver/normalize-param-env-1.rs +++ b/tests/ui/traits/next-solver/normalize-param-env-1.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Issue 108933 trait Add<Rhs> { diff --git a/tests/ui/traits/new-solver/normalize-param-env-2.rs b/tests/ui/traits/next-solver/normalize-param-env-2.rs index 7c2cebdd200..ce084651bfb 100644 --- a/tests/ui/traits/new-solver/normalize-param-env-2.rs +++ b/tests/ui/traits/next-solver/normalize-param-env-2.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Issue 92505 trait A<T> { diff --git a/tests/ui/traits/new-solver/normalize-param-env-3.rs b/tests/ui/traits/next-solver/normalize-param-env-3.rs index ce2974b2a16..e15e1155a1a 100644 --- a/tests/ui/traits/new-solver/normalize-param-env-3.rs +++ b/tests/ui/traits/next-solver/normalize-param-env-3.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Issue 100177 trait GenericTrait<T> {} diff --git a/tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs b/tests/ui/traits/next-solver/normalize-rcvr-for-inherent.rs index d70534feb07..d308b1695f5 100644 --- a/tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs +++ b/tests/ui/traits/next-solver/normalize-rcvr-for-inherent.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // Verify that we can assemble inherent impl candidates on a possibly diff --git a/tests/ui/traits/new-solver/normalize-unsize-rhs.rs b/tests/ui/traits/next-solver/normalize-unsize-rhs.rs index 1bb5c9b4111..6ca82d1b872 100644 --- a/tests/ui/traits/new-solver/normalize-unsize-rhs.rs +++ b/tests/ui/traits/next-solver/normalize-unsize-rhs.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait A {} diff --git a/tests/ui/traits/new-solver/normalized-const-built-in-op.rs b/tests/ui/traits/next-solver/normalized-const-built-in-op.rs index 2443e517813..0fffe7b4369 100644 --- a/tests/ui/traits/new-solver/normalized-const-built-in-op.rs +++ b/tests/ui/traits/next-solver/normalized-const-built-in-op.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass const fn foo() { diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs index 46343241b45..7dc87daccd9 100644 --- a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs +++ b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs @@ -1,5 +1,5 @@ // [no_self_infer] check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // revisions: self_infer no_self_infer // checks that the new solver is smart enough to infer `?0 = U` when solving: @@ -7,7 +7,7 @@ // with `normalizes-to(<Vec<U> as Trait>::Assoc, u8)` in the paramenv even when // there is a separate `Vec<T>: Trait` bound in the paramenv. // -// FIXME(-Ztrait-solver=next) +// FIXME(-Znext-solver) // This could also compile for `normalizes-to(<?0 as Trait>::Assoc, u8)` but // we currently immediately consider a goal ambiguous if the self type is an // inference variable. diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr index c1a8b74df08..c1a8b74df08 100644 --- a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr +++ b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr diff --git a/tests/ui/traits/new-solver/object-soundness-requires-generalization.rs b/tests/ui/traits/next-solver/object-soundness-requires-generalization.rs index d02dada72c9..6e709d9ae8e 100644 --- a/tests/ui/traits/new-solver/object-soundness-requires-generalization.rs +++ b/tests/ui/traits/next-solver/object-soundness-requires-generalization.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // ignore-test trait Trait { diff --git a/tests/ui/traits/new-solver/object-unsafety.rs b/tests/ui/traits/next-solver/object-unsafety.rs index da843c91478..8aae7217398 100644 --- a/tests/ui/traits/new-solver/object-unsafety.rs +++ b/tests/ui/traits/next-solver/object-unsafety.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Setup { type From: Copy; @@ -17,7 +17,7 @@ pub fn copy_any<T>(t: &T) -> T { //~| ERROR the type `<dyn Setup<From = T> as Setup>::From` is not well-formed //~| ERROR the size for values of type `<dyn Setup<From = T> as Setup>::From` cannot be known at compilation time - // FIXME(-Ztrait-solver=next): These error messages are horrible and some of them + // FIXME(-Znext-solver): These error messages are horrible and some of them // are even simple fallout from previous error. } diff --git a/tests/ui/traits/new-solver/object-unsafety.stderr b/tests/ui/traits/next-solver/object-unsafety.stderr index 914a8f9d4c5..914a8f9d4c5 100644 --- a/tests/ui/traits/new-solver/object-unsafety.stderr +++ b/tests/ui/traits/next-solver/object-unsafety.stderr diff --git a/tests/ui/traits/new-solver/opportunistic-region-resolve.rs b/tests/ui/traits/next-solver/opportunistic-region-resolve.rs index 2610789cd48..d852332d0e5 100644 --- a/tests/ui/traits/new-solver/opportunistic-region-resolve.rs +++ b/tests/ui/traits/next-solver/opportunistic-region-resolve.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(rustc_attrs)] diff --git a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs index 3d2e70a639f..a465bcecfe0 100644 --- a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs +++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Trait {} diff --git a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr index 90b54b1e789..90b54b1e789 100644 --- a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr +++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr diff --git a/tests/ui/traits/new-solver/overflow/global-cache.rs b/tests/ui/traits/next-solver/overflow/global-cache.rs index adc03da04a8..fe4032ca62e 100644 --- a/tests/ui/traits/new-solver/overflow/global-cache.rs +++ b/tests/ui/traits/next-solver/overflow/global-cache.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Check that we consider the reached depth of global cache // entries when detecting overflow. We would otherwise be unstable diff --git a/tests/ui/traits/new-solver/overflow/global-cache.stderr b/tests/ui/traits/next-solver/overflow/global-cache.stderr index 67616619384..67616619384 100644 --- a/tests/ui/traits/new-solver/overflow/global-cache.stderr +++ b/tests/ui/traits/next-solver/overflow/global-cache.stderr diff --git a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs index 539c9614e82..52a17a14281 100644 --- a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.rs +++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs @@ -2,7 +2,7 @@ //~| ERROR overflow evaluating the requirement `Self: Trait` // This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE. -// compile-flags: -Ztrait-solver=next --crate-type=lib +// compile-flags: -Znext-solver --crate-type=lib // check-fail #![recursion_limit = "0"] diff --git a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.stderr b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr index 16b25d90ace..16b25d90ace 100644 --- a/tests/ui/traits/new-solver/overflow/recursion-limit-zero-issue-115351.stderr +++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs index 3e10b2b595e..327ef865de9 100644 --- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Foo1 { type Assoc1; diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr index eda62b99c44..eda62b99c44 100644 --- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs index 36ef856a466..f45d208e666 100644 --- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Foo { type Assoc; diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr index b0a0a69761a..b0a0a69761a 100644 --- a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr diff --git a/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs b/tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs index bdf999ec5dd..f67b073c53c 100644 --- a/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs +++ b/tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Foo { diff --git a/tests/ui/traits/new-solver/param-discr-kind.rs b/tests/ui/traits/next-solver/param-discr-kind.rs index e319ddea106..c66b0b9f45f 100644 --- a/tests/ui/traits/new-solver/param-discr-kind.rs +++ b/tests/ui/traits/next-solver/param-discr-kind.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn foo<T>(x: T) { diff --git a/tests/ui/traits/new-solver/pointee.rs b/tests/ui/traits/next-solver/pointee.rs index 93c0542ace4..a56df549a8d 100644 --- a/tests/ui/traits/new-solver/pointee.rs +++ b/tests/ui/traits/next-solver/pointee.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(ptr_metadata)] diff --git a/tests/ui/traits/new-solver/pointer-like.rs b/tests/ui/traits/next-solver/pointer-like.rs index 98630176976..f6cc718c6e2 100644 --- a/tests/ui/traits/new-solver/pointer-like.rs +++ b/tests/ui/traits/next-solver/pointer-like.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(pointer_like_trait)] diff --git a/tests/ui/traits/new-solver/pointer-like.stderr b/tests/ui/traits/next-solver/pointer-like.stderr index 4b624fd0d35..4b624fd0d35 100644 --- a/tests/ui/traits/new-solver/pointer-like.stderr +++ b/tests/ui/traits/next-solver/pointer-like.stderr diff --git a/tests/ui/traits/new-solver/prefer-candidate-no-constraints.rs b/tests/ui/traits/next-solver/prefer-candidate-no-constraints.rs index 6f8164f3a40..a47f819f192 100644 --- a/tests/ui/traits/new-solver/prefer-candidate-no-constraints.rs +++ b/tests/ui/traits/next-solver/prefer-candidate-no-constraints.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Foo {} diff --git a/tests/ui/traits/new-solver/prefer-param-env-on-ambiguity.rs b/tests/ui/traits/next-solver/prefer-param-env-on-ambiguity.rs index 909b33ec3d5..f8c0223e187 100644 --- a/tests/ui/traits/new-solver/prefer-param-env-on-ambiguity.rs +++ b/tests/ui/traits/next-solver/prefer-param-env-on-ambiguity.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Foo<'a> {} diff --git a/tests/ui/traits/new-solver/projection-discr-kind.rs b/tests/ui/traits/next-solver/projection-discr-kind.rs index 20296b287b1..bf557f8633a 100644 --- a/tests/ui/traits/new-solver/projection-discr-kind.rs +++ b/tests/ui/traits/next-solver/projection-discr-kind.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Check that `<T::Assoc as DiscriminantKind>::Discriminant` doesn't normalize // to itself and cause overflow/ambiguity. diff --git a/tests/ui/traits/new-solver/projection-discr-kind.stderr b/tests/ui/traits/next-solver/projection-discr-kind.stderr index 69999c75522..69999c75522 100644 --- a/tests/ui/traits/new-solver/projection-discr-kind.stderr +++ b/tests/ui/traits/next-solver/projection-discr-kind.stderr diff --git a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs index e36d574efe2..b337c067374 100644 --- a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs +++ b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // See https://github.com/rust-lang/trait-system-refactor-initiative/issues/1 // a minimization of a pattern in core. diff --git a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs index c8050997a1d..db8dc1eb9be 100644 --- a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs +++ b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // See https://github.com/rust-lang/trait-system-refactor-initiative/issues/1, // a minimization of a pattern in core. diff --git a/tests/ui/traits/new-solver/slice-match-byte-lit.rs b/tests/ui/traits/next-solver/slice-match-byte-lit.rs index 4f848062595..1edc9f1e8e9 100644 --- a/tests/ui/traits/new-solver/slice-match-byte-lit.rs +++ b/tests/ui/traits/next-solver/slice-match-byte-lit.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass fn test(s: &[u8]) { diff --git a/tests/ui/traits/new-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs index fac7d76f8cf..58b62f52dfd 100644 --- a/tests/ui/traits/new-solver/specialization-transmute.rs +++ b/tests/ui/traits/next-solver/specialization-transmute.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(specialization)] //~^ WARN the feature `specialization` is incomplete diff --git a/tests/ui/traits/new-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr index eaf32a475ac..eaf32a475ac 100644 --- a/tests/ui/traits/new-solver/specialization-transmute.stderr +++ b/tests/ui/traits/next-solver/specialization-transmute.stderr diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.rs b/tests/ui/traits/next-solver/specialization-unconstrained.rs index 7fd753109be..950fb1512bc 100644 --- a/tests/ui/traits/new-solver/specialization-unconstrained.rs +++ b/tests/ui/traits/next-solver/specialization-unconstrained.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver #![feature(specialization)] //~^ WARN the feature `specialization` is incomplete diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/next-solver/specialization-unconstrained.stderr index ed4dafa1484..ed4dafa1484 100644 --- a/tests/ui/traits/new-solver/specialization-unconstrained.stderr +++ b/tests/ui/traits/next-solver/specialization-unconstrained.stderr diff --git a/tests/ui/traits/new-solver/stall-num-var-auto-trait.fallback.stderr b/tests/ui/traits/next-solver/stall-num-var-auto-trait.fallback.stderr index 2e3c22c8d38..2e3c22c8d38 100644 --- a/tests/ui/traits/new-solver/stall-num-var-auto-trait.fallback.stderr +++ b/tests/ui/traits/next-solver/stall-num-var-auto-trait.fallback.stderr diff --git a/tests/ui/traits/new-solver/stall-num-var-auto-trait.rs b/tests/ui/traits/next-solver/stall-num-var-auto-trait.rs index 0539c3a4292..f5bf985cdb2 100644 --- a/tests/ui/traits/new-solver/stall-num-var-auto-trait.rs +++ b/tests/ui/traits/next-solver/stall-num-var-auto-trait.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // revisions: fallback constrain //[constrain] check-pass diff --git a/tests/ui/traits/new-solver/structural-resolve-field.rs b/tests/ui/traits/next-solver/structural-resolve-field.rs index 01899c9ad64..b247e237534 100644 --- a/tests/ui/traits/new-solver/structural-resolve-field.rs +++ b/tests/ui/traits/next-solver/structural-resolve-field.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #[derive(Default)] diff --git a/tests/ui/traits/new-solver/tait-eq-proj-2.rs b/tests/ui/traits/next-solver/tait-eq-proj-2.rs index 77ea8bc246e..a3df053dd83 100644 --- a/tests/ui/traits/new-solver/tait-eq-proj-2.rs +++ b/tests/ui/traits/next-solver/tait-eq-proj-2.rs @@ -1,9 +1,9 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(type_alias_impl_trait)] -// Similar to tests/ui/traits/new-solver/tait-eq-proj.rs +// Similar to tests/ui/traits/next-solver/tait-eq-proj.rs // but check the alias-sub relation in the other direction. type Tait = impl Iterator<Item = impl Sized>; diff --git a/tests/ui/traits/new-solver/tait-eq-proj.rs b/tests/ui/traits/next-solver/tait-eq-proj.rs index 01ef2ec953a..871e8e1e9fc 100644 --- a/tests/ui/traits/new-solver/tait-eq-proj.rs +++ b/tests/ui/traits/next-solver/tait-eq-proj.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/traits/new-solver/tait-eq-tait.rs b/tests/ui/traits/next-solver/tait-eq-tait.rs index 70d9dc0eaa8..2629a124c3a 100644 --- a/tests/ui/traits/new-solver/tait-eq-tait.rs +++ b/tests/ui/traits/next-solver/tait-eq-tait.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // Not exactly sure if this is the inference behavior we *want*, diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/next-solver/temporary-ambiguity.rs index c6c11a1a1de..6102de7e446 100644 --- a/tests/ui/traits/new-solver/temporary-ambiguity.rs +++ b/tests/ui/traits/next-solver/temporary-ambiguity.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass // Checks that we don't explode when we assemble >1 candidate for a goal. diff --git a/tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs b/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs index 79114b93b78..2a482f74668 100644 --- a/tests/ui/traits/new-solver/trait-upcast-lhs-needs-normalization.rs +++ b/tests/ui/traits/next-solver/trait-upcast-lhs-needs-normalization.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver pub trait A {} pub trait B: A {} diff --git a/tests/ui/traits/new-solver/try-example.rs b/tests/ui/traits/next-solver/try-example.rs index e826f3a0059..92b0b597881 100644 --- a/tests/ui/traits/new-solver/try-example.rs +++ b/tests/ui/traits/next-solver/try-example.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver use std::error::Error; diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.rs index 3c7fc0d813d..d25e372b5d8 100644 --- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs +++ b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // When we're solving `<T as Foo>::Assoc = i32`, we actually first solve // `<T as Foo>::Assoc = ?1t`, then unify `?1t` with `i32`. That goal diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.stderr index dfff9f11b87..dfff9f11b87 100644 --- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr +++ b/tests/ui/traits/next-solver/two-projection-param-candidates-are-ambiguous.stderr diff --git a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.fails.stderr b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr index 4be90c702a0..4be90c702a0 100644 --- a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.fails.stderr +++ b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.fails.stderr diff --git a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.rs b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs index 26c595bc974..77a169d48de 100644 --- a/tests/ui/traits/new-solver/unevaluated-const-impl-trait-ref.rs +++ b/tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // revisions: works fails //[works] check-pass diff --git a/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs b/tests/ui/traits/next-solver/unsafe-auto-trait-impl.rs index bcfc747ebb1..f66bf0b87ec 100644 --- a/tests/ui/traits/new-solver/unsafe-auto-trait-impl.rs +++ b/tests/ui/traits/next-solver/unsafe-auto-trait-impl.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass struct Foo(*mut ()); diff --git a/tests/ui/traits/new-solver/unsize-although-ambiguous.rs b/tests/ui/traits/next-solver/unsize-although-ambiguous.rs index 431988a5fff..8217701b9f8 100644 --- a/tests/ui/traits/new-solver/unsize-although-ambiguous.rs +++ b/tests/ui/traits/next-solver/unsize-although-ambiguous.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver use std::fmt::Display; diff --git a/tests/ui/traits/new-solver/unsize-good.rs b/tests/ui/traits/next-solver/unsize-good.rs index 87ed9cfd10a..04ebe66f21c 100644 --- a/tests/ui/traits/new-solver/unsize-good.rs +++ b/tests/ui/traits/next-solver/unsize-good.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass #![feature(unsized_tuple_coercion)] diff --git a/tests/ui/traits/new-solver/upcast-right-substs.rs b/tests/ui/traits/next-solver/upcast-right-substs.rs index 97eb189d5c7..5e4d958c895 100644 --- a/tests/ui/traits/new-solver/upcast-right-substs.rs +++ b/tests/ui/traits/next-solver/upcast-right-substs.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // check-pass trait Foo: Bar<i32> + Bar<u32> {} diff --git a/tests/ui/traits/new-solver/upcast-wrong-substs.rs b/tests/ui/traits/next-solver/upcast-wrong-substs.rs index 3376f9787d3..0cd253007fc 100644 --- a/tests/ui/traits/new-solver/upcast-wrong-substs.rs +++ b/tests/ui/traits/next-solver/upcast-wrong-substs.rs @@ -1,4 +1,4 @@ -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver trait Foo: Bar<i32> + Bar<u32> {} diff --git a/tests/ui/traits/new-solver/upcast-wrong-substs.stderr b/tests/ui/traits/next-solver/upcast-wrong-substs.stderr index 00ba1ef678f..00ba1ef678f 100644 --- a/tests/ui/traits/new-solver/upcast-wrong-substs.stderr +++ b/tests/ui/traits/next-solver/upcast-wrong-substs.stderr diff --git a/tests/ui/traits/new-solver/winnow-specializing-impls.rs b/tests/ui/traits/next-solver/winnow-specializing-impls.rs index 06f64de7403..d70a9159611 100644 --- a/tests/ui/traits/new-solver/winnow-specializing-impls.rs +++ b/tests/ui/traits/next-solver/winnow-specializing-impls.rs @@ -1,5 +1,5 @@ // build-pass -// compile-flags: -Ztrait-solver=next +// compile-flags: -Znext-solver // Tests that the specializing impl `<() as Foo>` holds during codegen. diff --git a/tests/ui/traits/non-lifetime-via-dyn-builtin.rs b/tests/ui/traits/non-lifetime-via-dyn-builtin.rs index 9a8a5ced2e2..996cd295dc4 100644 --- a/tests/ui/traits/non-lifetime-via-dyn-builtin.rs +++ b/tests/ui/traits/non-lifetime-via-dyn-builtin.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass #![feature(non_lifetime_binders)] diff --git a/tests/ui/traits/reservation-impl/coherence-conflict.rs b/tests/ui/traits/reservation-impl/coherence-conflict.rs index 6bbd90f94dc..cdea162d64a 100644 --- a/tests/ui/traits/reservation-impl/coherence-conflict.rs +++ b/tests/ui/traits/reservation-impl/coherence-conflict.rs @@ -1,6 +1,6 @@ // check that reservation impls are accounted for in negative reasoning. // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(rustc_attrs)] trait MyTrait {} diff --git a/tests/ui/traits/reservation-impl/no-use.rs b/tests/ui/traits/reservation-impl/no-use.rs index 864f1791fd0..10aad3605ea 100644 --- a/tests/ui/traits/reservation-impl/no-use.rs +++ b/tests/ui/traits/reservation-impl/no-use.rs @@ -1,6 +1,6 @@ // check that reservation impls can't be used as normal impls in positive reasoning. // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(rustc_attrs)] trait MyTrait { fn foo(&self); } diff --git a/tests/ui/traits/reservation-impl/non-lattice-ok.rs b/tests/ui/traits/reservation-impl/non-lattice-ok.rs index 7787904d9b2..9a3c2b4f991 100644 --- a/tests/ui/traits/reservation-impl/non-lattice-ok.rs +++ b/tests/ui/traits/reservation-impl/non-lattice-ok.rs @@ -34,7 +34,7 @@ // check that reservation impls can't be used as normal impls in positive reasoning. // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(rustc_attrs, never_type)] diff --git a/tests/ui/traits/reservation-impl/ok.rs b/tests/ui/traits/reservation-impl/ok.rs index 8ff6645a2b3..2d945f6adeb 100644 --- a/tests/ui/traits/reservation-impl/ok.rs +++ b/tests/ui/traits/reservation-impl/ok.rs @@ -4,7 +4,7 @@ // but still. // revisions: old next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(rustc_attrs)] diff --git a/tests/ui/traits/trait-upcasting/fewer-associated.rs b/tests/ui/traits/trait-upcasting/fewer-associated.rs index 937818aac58..e7ca6fa5208 100644 --- a/tests/ui/traits/trait-upcasting/fewer-associated.rs +++ b/tests/ui/traits/trait-upcasting/fewer-associated.rs @@ -1,7 +1,7 @@ // check-pass // issue: 114035 // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver trait A: B { type Assoc; diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs index 4b730dab7cc..5a493fd48b3 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver trait Super { type Assoc; diff --git a/tests/ui/traits/trait-upcasting/issue-11515.rs b/tests/ui/traits/trait-upcasting/issue-11515.rs index 66ab1ce260a..a1edb53ec37 100644 --- a/tests/ui/traits/trait-upcasting/issue-11515.rs +++ b/tests/ui/traits/trait-upcasting/issue-11515.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver struct Test { func: Box<dyn FnMut() + 'static>, diff --git a/tests/ui/traits/trait-upcasting/normalization.rs b/tests/ui/traits/trait-upcasting/normalization.rs index c57640e7e34..b594969483a 100644 --- a/tests/ui/traits/trait-upcasting/normalization.rs +++ b/tests/ui/traits/trait-upcasting/normalization.rs @@ -1,7 +1,7 @@ // check-pass // issue: 114113 // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver trait Mirror { type Assoc; diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs index 3b6ec3b65e7..7d3deeeaa61 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver trait Foo: Bar<i32> + Bar<u32> {} trait Bar<T> { diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs index 9981d436062..f8cf793e4a4 100644 --- a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs +++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver struct Wrapper<T: ?Sized>(T); diff --git a/tests/ui/transmutability/primitives/bool-mut.rs b/tests/ui/transmutability/primitives/bool-mut.rs index 49dbe90e4b8..6ee168d1a71 100644 --- a/tests/ui/transmutability/primitives/bool-mut.rs +++ b/tests/ui/transmutability/primitives/bool-mut.rs @@ -1,5 +1,5 @@ // check-fail -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(transmutability)] mod assert { diff --git a/tests/ui/transmutability/primitives/bool.rs b/tests/ui/transmutability/primitives/bool.rs index 654e7b47ede..ac4024b7f33 100644 --- a/tests/ui/transmutability/primitives/bool.rs +++ b/tests/ui/transmutability/primitives/bool.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(transmutability)] mod assert { diff --git a/tests/ui/transmutability/primitives/numbers.rs b/tests/ui/transmutability/primitives/numbers.rs index e980e91ed06..1afc7d677ee 100644 --- a/tests/ui/transmutability/primitives/numbers.rs +++ b/tests/ui/transmutability/primitives/numbers.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![crate_type = "lib"] #![feature(transmutability)] diff --git a/tests/ui/transmutability/primitives/unit.rs b/tests/ui/transmutability/primitives/unit.rs index 12eac175106..5ea96cf8ba7 100644 --- a/tests/ui/transmutability/primitives/unit.rs +++ b/tests/ui/transmutability/primitives/unit.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //! The unit type, `()`, should be one byte. diff --git a/tests/ui/type-alias-impl-trait/assoc-type-const.rs b/tests/ui/type-alias-impl-trait/assoc-type-const.rs index 6632a3450e5..e385fe045fc 100644 --- a/tests/ui/type-alias-impl-trait/assoc-type-const.rs +++ b/tests/ui/type-alias-impl-trait/assoc-type-const.rs @@ -3,7 +3,7 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(impl_trait_in_assoc_type)] trait UnwrapItemsExt<'a, const C: usize> { diff --git a/tests/ui/type-alias-impl-trait/cross_inference.rs b/tests/ui/type-alias-impl-trait/cross_inference.rs index 5eaf0ddda99..c5ef75fee61 100644 --- a/tests/ui/type-alias-impl-trait/cross_inference.rs +++ b/tests/ui/type-alias-impl-trait/cross_inference.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs index 386b77d4d16..af1c18bbb59 100644 --- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs +++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs @@ -2,7 +2,7 @@ // Tests that we don't ICE when we have a trait impl on a TAIT. // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/type-alias-impl-trait/issue-78450.rs b/tests/ui/type-alias-impl-trait/issue-78450.rs index 236e9f4e88c..c51dfb6782b 100644 --- a/tests/ui/type-alias-impl-trait/issue-78450.rs +++ b/tests/ui/type-alias-impl-trait/issue-78450.rs @@ -1,6 +1,6 @@ // check-pass // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(impl_trait_in_assoc_type)] diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs index 8d80546444a..371cac6da7c 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.rs @@ -1,7 +1,7 @@ // Regression test for #112691 // // revisions: current next -// [next] compile-flags: -Ztrait-solver=next +// [next] compile-flags: -Znext-solver // [next] check-pass // [current]: known-bug: #112691 diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs index 0f0002f7797..222841f3467 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs @@ -6,7 +6,7 @@ //! have a situation where the RPIT gets constrained outside its anchor. // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver //[next] check-pass //[current] known-bug: #108498 diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs index b966ca4bff0..22e2b0efd1f 100644 --- a/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs +++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs @@ -2,7 +2,7 @@ // // revisions: pass pass_next fail // [pass] check-pass -// [pass_next] compile-flags: -Ztrait-solver=next +// [pass_next] compile-flags: -Znext-solver // [pass_next] check-pass // [fail] check-fail diff --git a/tests/ui/unsized/issue-71659.rs b/tests/ui/unsized/issue-71659.rs index db5c2e205aa..65a867caf8f 100644 --- a/tests/ui/unsized/issue-71659.rs +++ b/tests/ui/unsized/issue-71659.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver #![feature(unsize)] diff --git a/tests/ui/unsized/issue-75899.rs b/tests/ui/unsized/issue-75899.rs index 71943103291..56c8a72bfcc 100644 --- a/tests/ui/unsized/issue-75899.rs +++ b/tests/ui/unsized/issue-75899.rs @@ -1,5 +1,5 @@ // revisions: current next -//[next] compile-flags: -Ztrait-solver=next +//[next] compile-flags: -Znext-solver // check-pass trait Trait {} diff --git a/triagebot.toml b/triagebot.toml index 30f049c79d6..2867bbc8171 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -441,6 +441,14 @@ cc = ["@rust-lang/miri"] message = "Some changes occurred in need_type_info.rs" cc = ["@lcnr"] +[mentions."compiler/rustc_middle/src/ty/relate.rs"] +message = "Type relation code was changed" +cc = ["@compiler-errors", "@lcnr"] + +[mentions."compiler/rustc_infer/src/infer/relate"] +message = "Type relation code was changed" +cc = ["@compiler-errors", "@lcnr"] + [mentions."compiler/rustc_middle/src/mir/interpret"] message = "Some changes occurred to the CTFE / Miri engine" cc = ["@rust-lang/miri"] @@ -555,15 +563,15 @@ cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@davidtwco", "@celinval", "@vakar [mentions."compiler/rustc_error_messages"] message = "`rustc_error_messages` was changed" -cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"] +cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] [mentions."compiler/rustc_errors/src/translation.rs"] message = "`rustc_errors::translation` was changed" -cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"] +cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] [mentions."compiler/rustc_macros/src/diagnostics"] message = "`rustc_macros::diagnostics` was changed" -cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"] +cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] [mentions."compiler/stable_mir"] message = "This PR changes Stable MIR" |
