diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 96c230ec243a2..cfd32fc066f41 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -1,13 +1,12 @@ use std::collections::hash_map::Entry; use std::fmt::Write; -use rustc_ast::ptr::P; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_session::parse::feature_err; -use rustc_span::{Span, kw, sym}; +use rustc_span::{Span, sym}; use rustc_target::asm; use super::LoweringContext; @@ -230,20 +229,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { tokens: None, }; - // Wrap the expression in an AnonConst. - let parent_def_id = self.current_hir_id_owner.def_id; - let node_id = self.next_node_id(); - self.create_def( - parent_def_id, - node_id, - kw::Empty, - DefKind::AnonConst, - *op_sp, - ); - let anon_const = AnonConst { id: node_id, value: P(expr) }; - hir::InlineAsmOperand::SymFn { - anon_const: self.lower_anon_const_to_anon_const(&anon_const), - } + hir::InlineAsmOperand::SymFn { expr: self.lower_expr(&expr) } } } InlineAsmOperand::Label { block } => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index bc2db41546989..1d3db64b47ed9 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -251,7 +251,12 @@ impl<'hir> LoweringContext<'_, 'hir> { .arena .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), }, - ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)), + ItemKind::GlobalAsm(asm) => { + let asm = self.lower_inline_asm(span, asm); + let fake_body = + self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); + hir::ItemKind::GlobalAsm { asm, fake_body } + } ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { // We lower // diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 9a68eeb3326eb..a71ca37bf1306 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -126,6 +126,11 @@ pub(crate) enum DefiningTy<'tcx> { /// The MIR represents an inline const. The signature has no inputs and a /// single return value found via `InlineConstArgs::ty`. InlineConst(DefId, GenericArgsRef<'tcx>), + + // Fake body for a global asm. Not particularly useful or interesting, + // but we need it so we can properly store the typeck results of the asm + // operands, which aren't associated with a body otherwise. + GlobalAsm(DefId), } impl<'tcx> DefiningTy<'tcx> { @@ -138,9 +143,10 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(), DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(), DefiningTy::Coroutine(_, args) => args.as_coroutine().upvar_tys(), - DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => { - ty::List::empty() - } + DefiningTy::FnDef(..) + | DefiningTy::Const(..) + | DefiningTy::InlineConst(..) + | DefiningTy::GlobalAsm(_) => ty::List::empty(), } } @@ -152,7 +158,10 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::Closure(..) | DefiningTy::CoroutineClosure(..) | DefiningTy::Coroutine(..) => 1, - DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0, + DefiningTy::FnDef(..) + | DefiningTy::Const(..) + | DefiningTy::InlineConst(..) + | DefiningTy::GlobalAsm(_) => 0, } } @@ -171,7 +180,8 @@ impl<'tcx> DefiningTy<'tcx> { | DefiningTy::Coroutine(def_id, ..) | DefiningTy::FnDef(def_id, ..) | DefiningTy::Const(def_id, ..) - | DefiningTy::InlineConst(def_id, ..) => def_id, + | DefiningTy::InlineConst(def_id, ..) + | DefiningTy::GlobalAsm(def_id) => def_id, } } } @@ -411,6 +421,7 @@ impl<'tcx> UniversalRegions<'tcx> { tcx.def_path_str_with_args(def_id, args), )); } + DefiningTy::GlobalAsm(_) => unreachable!(), } } @@ -633,6 +644,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::InlineConst(self.mir_def.to_def_id(), args) } } + + BodyOwnerKind::GlobalAsm => DefiningTy::GlobalAsm(self.mir_def.to_def_id()), } } @@ -666,6 +679,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args, + + DefiningTy::GlobalAsm(_) => ty::List::empty(), }; let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); @@ -802,6 +817,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let ty = args.as_inline_const().ty(); ty::Binder::dummy(tcx.mk_type_list(&[ty])) } + + DefiningTy::GlobalAsm(def_id) => { + ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()])) + } }; // FIXME(#129952): We probably want a more principled approach here. diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 54745b0d8c104..9ea92c300f898 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -16,7 +16,7 @@ use crate::prelude::*; pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) { let item = tcx.hir_item(item_id); - if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind { + if let rustc_hir::ItemKind::GlobalAsm { asm, .. } = item.kind { let is_x86 = matches!(tcx.sess.asm_arch.unwrap(), InlineAsmArch::X86 | InlineAsmArch::X86_64); @@ -55,7 +55,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, } } } - InlineAsmOperand::SymFn { anon_const } => { + InlineAsmOperand::SymFn { expr } => { if cfg!(not(feature = "inline_asm_sym")) { tcx.dcx().span_err( item.span, @@ -63,7 +63,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, ); } - let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + let ty = tcx.typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { &ty::FnDef(def_id, args) => Instance::new(def_id, args), _ => span_bug!(op_sp, "asm sym is not a function"), diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 5f95b6615bd30..f6af889fd6ecb 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { } MonoItem::GlobalAsm(item_id) => { let item = cx.tcx().hir_item(item_id); - if let hir::ItemKind::GlobalAsm(asm) = item.kind { + if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind { let operands: Vec<_> = asm .operands .iter() @@ -71,11 +71,8 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { } } } - hir::InlineAsmOperand::SymFn { ref anon_const } => { - let ty = cx - .tcx() - .typeck_body(anon_const.body) - .node_type(anon_const.hir_id); + hir::InlineAsmOperand::SymFn { expr } => { + let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { &ty::FnDef(def_id, args) => Instance::new(def_id, args), _ => span_bug!(*op_sp, "asm sym is not a function"), diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 634afacf53900..f7f842393084b 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2216,12 +2216,7 @@ impl HumanEmitter { if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add = show_code_change { - for mut part in parts { - // If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the - // suggestion and snippet to look as if we just suggested to add - // `"b"`, which is typically much easier for the user to understand. - part.trim_trivial_replacements(sm); - + for part in parts { let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) { snippet } else { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6fce1fade2664..ceed0cd94fc91 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -71,7 +71,7 @@ use rustc_macros::{Decodable, Encodable}; pub use rustc_span::ErrorGuaranteed; pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; use rustc_span::source_map::SourceMap; -use rustc_span::{DUMMY_SP, Loc, Span}; +use rustc_span::{BytePos, DUMMY_SP, Loc, Span}; pub use snippet::Style; // Used by external projects such as `rust-gpu`. // See https://github.com/rust-lang/rust/pull/115393. @@ -237,10 +237,9 @@ impl SubstitutionPart { /// it with "abx" is, since the "c" character is lost. pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool { self.is_replacement(sm) - && !sm.span_to_snippet(self.span).is_ok_and(|snippet| { - self.snippet.trim_start().starts_with(snippet.trim_start()) - || self.snippet.trim_end().ends_with(snippet.trim_end()) - }) + && !sm + .span_to_snippet(self.span) + .is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some()) } fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool { @@ -257,16 +256,40 @@ impl SubstitutionPart { let Ok(snippet) = sm.span_to_snippet(self.span) else { return; }; - if self.snippet.starts_with(&snippet) { - self.span = self.span.shrink_to_hi(); - self.snippet = self.snippet[snippet.len()..].to_string(); - } else if self.snippet.ends_with(&snippet) { - self.span = self.span.shrink_to_lo(); - self.snippet = self.snippet[..self.snippet.len() - snippet.len()].to_string(); + + if let Some((prefix, substr, suffix)) = as_substr(&snippet, &self.snippet) { + self.span = Span::new( + self.span.lo() + BytePos(prefix as u32), + self.span.hi() - BytePos(suffix as u32), + self.span.ctxt(), + self.span.parent(), + ); + self.snippet = substr.to_string(); } } } +/// Given an original string like `AACC`, and a suggestion like `AABBCC`, try to detect +/// the case where a substring of the suggestion is "sandwiched" in the original, like +/// `BB` is. Return the length of the prefix, the "trimmed" suggestion, and the length +/// of the suffix. +fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> { + let common_prefix = original + .chars() + .zip(suggestion.chars()) + .take_while(|(c1, c2)| c1 == c2) + .map(|(c, _)| c.len_utf8()) + .sum(); + let original = &original[common_prefix..]; + let suggestion = &suggestion[common_prefix..]; + if suggestion.ends_with(original) { + let common_suffix = original.len(); + Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix)) + } else { + None + } +} + impl CodeSuggestion { /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. @@ -380,7 +403,12 @@ impl CodeSuggestion { // or deleted code in order to point at the correct column *after* substitution. let mut acc = 0; let mut only_capitalization = false; - for part in &substitution.parts { + for part in &mut substitution.parts { + // If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the + // suggestion and snippet to look as if we just suggested to add + // `"b"`, which is typically much easier for the user to understand. + part.trim_trivial_replacements(sm); + only_capitalization |= is_case_difference(sm, &part.snippet, part.span); let cur_lo = sm.lookup_char_pos(part.span.lo()); if prev_hi.line == cur_lo.line { diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 2fb0c8e43448a..60e7788f2c05d 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -135,6 +135,8 @@ declare_features! ( Some("removed as it caused some confusion and discussion was inactive for years")), /// Lazily evaluate constants. This allows constants to depend on type parameters. (removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")), + /// Changes `impl Trait` to capture all lifetimes in scope. + (removed, lifetime_capture_rules_2024, "1.76.0", None, Some("unnecessary -- use edition 2024 instead")), /// Allows using the `#[link_args]` attribute. (removed, link_args, "1.53.0", Some(29596), Some("removed in favor of using `-C link-arg=ARG` on command line, \ diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e852f239aa27c..c7b44cecb9e00 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -214,8 +214,6 @@ declare_features! ( (internal, intrinsics, "1.0.0", None), /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. (internal, lang_items, "1.0.0", None), - /// Changes `impl Trait` to capture all lifetimes in scope. - (unstable, lifetime_capture_rules_2024, "1.76.0", None), /// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406 (internal, link_cfg, "1.14.0", None), /// Allows using `?Trait` trait bounds in more contexts. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index eafc60f9d72f7..61f64e62058fc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1913,13 +1913,18 @@ pub enum BodyOwnerKind { /// Initializer of a `static` item. Static(Mutability), + + /// Fake body for a global asm to store its const-like value types. + GlobalAsm, } impl BodyOwnerKind { pub fn is_fn_or_closure(self) -> bool { match self { BodyOwnerKind::Fn | BodyOwnerKind::Closure => true, - BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) => false, + BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => { + false + } } } } @@ -3420,7 +3425,7 @@ pub enum InlineAsmOperand<'hir> { anon_const: &'hir AnonConst, }, SymFn { - anon_const: &'hir AnonConst, + expr: &'hir Expr<'hir>, }, SymStatic { path: QPath<'hir>, @@ -3848,7 +3853,7 @@ impl<'hir> Item<'hir> { expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]), ItemKind::ForeignMod { abi, items }, (*abi, items); - expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm(asm), asm; + expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm; expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>), ItemKind::TyAlias(ty, generics), (ty, generics); @@ -4015,7 +4020,15 @@ pub enum ItemKind<'hir> { /// An external module, e.g. `extern { .. }`. ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] }, /// Module-level inline assembly (from `global_asm!`). - GlobalAsm(&'hir InlineAsm<'hir>), + GlobalAsm { + asm: &'hir InlineAsm<'hir>, + /// A fake body which stores typeck results for the global asm's sym_fn + /// operands, which are represented as path expressions. This body contains + /// a single [`ExprKind::InlineAsm`] which points to the asm in the field + /// above, and which is typechecked like a inline asm expr just for the + /// typeck results. + fake_body: BodyId, + }, /// A type alias, e.g., `type Foo = Bar`. TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>), /// An enum definition, e.g., `enum Foo {C, D}`. @@ -4081,7 +4094,7 @@ impl ItemKind<'_> { ItemKind::Macro(..) => "macro", ItemKind::Mod(..) => "module", ItemKind::ForeignMod { .. } => "extern block", - ItemKind::GlobalAsm(..) => "global asm item", + ItemKind::GlobalAsm { .. } => "global asm item", ItemKind::TyAlias(..) => "type alias", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", @@ -4540,6 +4553,10 @@ impl<'hir> Node<'hir> { .. }) => Some((owner_id.def_id, *body)), + Node::Item(Item { + owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, .. + }) => Some((owner_id.def_id, *fake_body)), + Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => { Some((*def_id, *body)) } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index bd96fe9ee32c7..89a58e947cb56 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -573,9 +573,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_id(item.hir_id())); walk_list!(visitor, visit_foreign_item_ref, items); } - ItemKind::GlobalAsm(asm) => { + ItemKind::GlobalAsm { asm: _, fake_body } => { try_visit!(visitor.visit_id(item.hir_id())); - try_visit!(visitor.visit_inline_asm(asm, item.hir_id())); + // Visit the fake body, which contains the asm statement. + // Therefore we should not visit the asm statement again + // outside of the body, or some visitors won't have their + // typeck results set correctly. + try_visit!(visitor.visit_nested_body(fake_body)); } ItemKind::TyAlias(ref ty, ref generics) => { try_visit!(visitor.visit_id(item.hir_id())); @@ -1442,10 +1446,12 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>( try_visit!(visitor.visit_expr(in_expr)); visit_opt!(visitor, visit_expr, out_expr); } - InlineAsmOperand::Const { anon_const, .. } - | InlineAsmOperand::SymFn { anon_const, .. } => { + InlineAsmOperand::Const { anon_const, .. } => { try_visit!(visitor.visit_anon_const(anon_const)); } + InlineAsmOperand::SymFn { expr, .. } => { + try_visit!(visitor.visit_expr(expr)); + } InlineAsmOperand::SymStatic { path, .. } => { try_visit!(visitor.visit_qpath(path, id, *op_sp)); } diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index f3e8f059c9e3c..70e95a84e68cc 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -110,7 +110,7 @@ impl Target { ItemKind::Macro(..) => Target::MacroDef, ItemKind::Mod(..) => Target::Mod, ItemKind::ForeignMod { .. } => Target::ForeignMod, - ItemKind::GlobalAsm(..) => Target::GlobalAsm, + ItemKind::GlobalAsm { .. } => Target::GlobalAsm, ItemKind::TyAlias(..) => Target::TyAlias, ItemKind::Enum(..) => Target::Enum, ItemKind::Struct(..) => Target::Struct, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 516ecbcfe0ef9..179962005004f 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -15,7 +15,6 @@ use rustc_lint_defs::builtin::{ use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; -use rustc_middle::span_bug; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::fold::{BottomUpFolder, fold_regions}; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; @@ -35,7 +34,6 @@ use {rustc_attr_parsing as attr, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; -use crate::check::intrinsicck::InlineAsmCtxt; pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) { if !tcx.sess.target.is_abi_supported(abi) { @@ -895,13 +893,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } } - DefKind::GlobalAsm => { - let it = tcx.hir().expect_item(def_id); - let hir::ItemKind::GlobalAsm(asm) = it.kind else { - span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) - }; - InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, def_id); - } _ => {} } } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 90e93bdbb5075..e1727fc48a833 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_middle::bug; -use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; +use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::{Symbol, sym}; @@ -16,10 +16,11 @@ use rustc_target::asm::{ use crate::errors::RegisterTypeUnstable; -pub struct InlineAsmCtxt<'a, 'tcx> { +pub struct InlineAsmCtxt<'a, 'tcx: 'a> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, - get_operand_ty: Box) -> Ty<'tcx> + 'a>, + target_features: &'tcx FxIndexSet, + expr_ty: Box) -> Ty<'tcx> + 'a>, } enum NonAsmTypeReason<'tcx> { @@ -29,25 +30,24 @@ enum NonAsmTypeReason<'tcx> { } impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { - pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self { + pub fn new( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, + ) -> Self { InlineAsmCtxt { tcx, typing_env: ty::TypingEnv { typing_mode: ty::TypingMode::non_body_analysis(), param_env: ty::ParamEnv::empty(), }, - get_operand_ty: Box::new(|e| bug!("asm operand in global asm: {e:?}")), + target_features: tcx.asm_target_features(def_id), + expr_ty: Box::new(get_operand_ty), } } - // FIXME(#132279): This likely causes us to incorrectly handle opaque types in their - // defining scope. - pub fn new_in_fn( - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - get_operand_ty: impl Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a, - ) -> Self { - InlineAsmCtxt { tcx, typing_env, get_operand_ty: Box::new(get_operand_ty) } + fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { + (self.expr_ty)(expr) } // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` @@ -139,9 +139,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { template: &[InlineAsmTemplatePiece], is_input: bool, tied_input: Option<(&'tcx hir::Expr<'tcx>, Option)>, - target_features: &FxIndexSet, ) -> Option { - let ty = (self.get_operand_ty)(expr); + let ty = self.expr_ty(expr); if ty.has_non_region_infer() { bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); } @@ -229,7 +228,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some((in_expr, Some(in_asm_ty))) = tied_input { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; - let in_expr_ty = (self.get_operand_ty)(in_expr); + let in_expr_ty = self.expr_ty(in_expr); self.tcx .dcx() .struct_span_err(vec![in_expr.span, expr.span], msg) @@ -291,7 +290,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // (!). In that case we still need the earlier check to verify that the // register class is usable at all. if let Some(feature) = feature { - if !target_features.contains(feature) { + if !self.target_features.contains(feature) { let msg = format!("`{feature}` target feature is not enabled"); self.tcx .dcx() @@ -351,14 +350,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { Some(asm_ty) } - pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) { - let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id()); + pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { let Some(asm_arch) = self.tcx.sess.asm_arch else { self.tcx.dcx().delayed_bug("target architecture does not support asm"); return; }; let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); - for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { + for (idx, &(op, op_sp)) in asm.operands.iter().enumerate() { // Validate register classes against currently enabled target // features. We check that at least one type is available for // the enabled features. @@ -381,12 +379,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Err(msg) = reg.validate( asm_arch, self.tcx.sess.relocation_model(), - target_features, + self.target_features, &self.tcx.sess.target, op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); continue; } } @@ -401,7 +399,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { { match feature { Some(feature) => { - if target_features.contains(&feature) { + if self.target_features.contains(&feature) { missing_required_features.clear(); break; } else { @@ -426,7 +424,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -440,7 +438,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::(), ); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -448,52 +446,21 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } } - match *op { + match op { hir::InlineAsmOperand::In { reg, expr } => { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - true, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, true, None); } hir::InlineAsmOperand::Out { reg, late: _, expr } => { if let Some(expr) = expr { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - false, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } } hir::InlineAsmOperand::InOut { reg, late: _, expr } => { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - false, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } hir::InlineAsmOperand::SplitInOut { reg, late: _, in_expr, out_expr } => { - let in_ty = self.check_asm_operand_type( - idx, - reg, - in_expr, - asm.template, - true, - None, - target_features, - ); + let in_ty = + self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None); if let Some(out_expr) = out_expr { self.check_asm_operand_type( idx, @@ -502,7 +469,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { asm.template, false, Some((in_expr, in_ty)), - target_features, ); } } @@ -514,11 +480,25 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ); } // Typeck has checked that SymFn refers to a function. - hir::InlineAsmOperand::SymFn { anon_const } => { - debug_assert_matches!( - self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), - ty::Error(_) | ty::FnDef(..) - ); + hir::InlineAsmOperand::SymFn { expr } => { + let ty = self.expr_ty(expr); + match ty.kind() { + ty::FnDef(..) => {} + ty::Error(_) => {} + _ => { + self.tcx + .dcx() + .struct_span_err(op_sp, "invalid `sym` operand") + .with_span_label( + expr.span, + format!("is {} `{}`", ty.kind().article(), ty), + ) + .with_help( + "`sym` operands must refer to either a function or a static", + ) + .emit(); + } + } } // AST lowering guarantees that SymStatic points to a static. hir::InlineAsmOperand::SymStatic { .. } => {} diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 75ea207a06bb1..da0d12816f883 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -680,7 +680,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { | hir::ItemKind::Use(..) | hir::ItemKind::Macro(..) | hir::ItemKind::Mod(_) - | hir::ItemKind::GlobalAsm(_) => {} + | hir::ItemKind::GlobalAsm { .. } => {} hir::ItemKind::ForeignMod { items, .. } => { for item in *items { let item = tcx.hir_foreign_item(item.id); diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index c0902398a54ae..f2d1132d6dcf3 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -189,8 +189,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // Exclude `GlobalAsm` here which cannot have generics. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => { + hir::InlineAsmOperand::Const { anon_const } => { anon_const.hir_id == hir_id } _ => false, 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 759c981a8f768..e309654d7503b 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -305,21 +305,15 @@ fn generic_param_def_as_bound_arg(param: &ty::GenericParamDef) -> ty::BoundVaria } /// Whether this opaque always captures lifetimes in scope. -/// Right now, this is all RPITIT and TAITs, and when `lifetime_capture_rules_2024` -/// is enabled. We don't check the span of the edition, since this is done -/// on a per-opaque basis to account for nested opaques. -fn opaque_captures_all_in_scope_lifetimes<'tcx>( - tcx: TyCtxt<'tcx>, - opaque: &'tcx hir::OpaqueTy<'tcx>, -) -> bool { +/// Right now, this is all RPITIT and TAITs, and when the opaque +/// is coming from a span corresponding to edition 2024. +fn opaque_captures_all_in_scope_lifetimes<'tcx>(opaque: &'tcx hir::OpaqueTy<'tcx>) -> bool { match opaque.origin { // if the opaque has the `use<...>` syntax, the user is telling us that they only want // to account for those lifetimes, so do not try to be clever. _ if opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..))) => false, hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => true, - _ if tcx.features().lifetime_capture_rules_2024() || opaque.span.at_least_rust_2024() => { - true - } + _ if opaque.span.at_least_rust_2024() => true, hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => in_trait_or_impl.is_some(), } } @@ -519,8 +513,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { fn visit_opaque_ty(&mut self, opaque: &'tcx rustc_hir::OpaqueTy<'tcx>) { let captures = RefCell::new(FxIndexMap::default()); - let capture_all_in_scope_lifetimes = - opaque_captures_all_in_scope_lifetimes(self.tcx, opaque); + let capture_all_in_scope_lifetimes = opaque_captures_all_in_scope_lifetimes(opaque); if capture_all_in_scope_lifetimes { let lifetime_ident = |def_id: LocalDefId| { let name = self.tcx.item_name(def_id.to_def_id()); @@ -630,7 +623,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } | hir::ItemKind::Static(..) - | hir::ItemKind::GlobalAsm(..) => { + | hir::ItemKind::GlobalAsm { .. } => { // These sorts of items have no lifetime parameters at all. intravisit::walk_item(self, item); } @@ -2276,7 +2269,7 @@ fn is_late_bound_map( } let mut appears_in_output = - AllCollector { tcx, has_fully_capturing_opaque: false, regions: Default::default() }; + AllCollector { has_fully_capturing_opaque: false, regions: Default::default() }; intravisit::walk_fn_ret_ty(&mut appears_in_output, &sig.decl.output); if appears_in_output.has_fully_capturing_opaque { appears_in_output.regions.extend(generics.params.iter().map(|param| param.def_id)); @@ -2289,7 +2282,7 @@ fn is_late_bound_map( // Subtle point: because we disallow nested bindings, we can just // ignore binders here and scrape up all names we see. let mut appears_in_where_clause = - AllCollector { tcx, has_fully_capturing_opaque: true, regions: Default::default() }; + AllCollector { has_fully_capturing_opaque: true, regions: Default::default() }; appears_in_where_clause.visit_generics(generics); debug!(?appears_in_where_clause.regions); @@ -2455,23 +2448,21 @@ fn is_late_bound_map( } } - struct AllCollector<'tcx> { - tcx: TyCtxt<'tcx>, + struct AllCollector { has_fully_capturing_opaque: bool, regions: FxHashSet, } - impl<'v> Visitor<'v> for AllCollector<'v> { - fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { + impl<'tcx> Visitor<'tcx> for AllCollector { + fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { if let hir::LifetimeName::Param(def_id) = lifetime_ref.res { self.regions.insert(def_id); } } - fn visit_opaque_ty(&mut self, opaque: &'v hir::OpaqueTy<'v>) { + fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) { if !self.has_fully_capturing_opaque { - self.has_fully_capturing_opaque = - opaque_captures_all_in_scope_lifetimes(self.tcx, opaque); + self.has_fully_capturing_opaque = opaque_captures_all_in_scope_lifetimes(opaque); } intravisit::walk_opaque_ty(self, opaque); } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 293a095b41d0c..c3a75ac89e14a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -35,13 +35,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx let parent_node_id = tcx.parent_hir_id(hir_id); let parent_node = tcx.hir_node(parent_node_id); - let find_sym_fn = |&(op, op_sp)| match op { - hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == hir_id => { - Some((anon_const, op_sp)) - } - _ => None, - }; - let find_const = |&(op, op_sp)| match op { hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => { Some((anon_const, op_sp)) @@ -59,31 +52,7 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx // Anon consts outside the type system. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) - if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_sym_fn) => - { - let ty = tcx.typeck(def_id).node_type(hir_id); - - match ty.kind() { - ty::Error(_) => ty, - ty::FnDef(..) => ty, - _ => { - let guar = tcx - .dcx() - .struct_span_err(op_sp, "invalid `sym` operand") - .with_span_label( - tcx.def_span(anon_const.def_id), - format!("is {} `{}`", ty.kind().article(), ty), - ) - .with_help("`sym` operands must refer to either a function or a static") - .emit(); - - Ty::new_error(tcx, guar) - } - } - } - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) + | Node::Item(&Item { kind: ItemKind::GlobalAsm { asm, .. }, .. }) if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) => { let ty = tcx.typeck(def_id).node_type(hir_id); @@ -313,12 +282,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_adt(tcx, def, args) } + ItemKind::GlobalAsm { .. } => tcx.typeck(def_id).node_type(hir_id), ItemKind::Trait(..) | ItemKind::TraitAlias(..) | ItemKind::Macro(..) | ItemKind::Mod(..) | ItemKind::ForeignMod { .. } - | ItemKind::GlobalAsm(..) | ItemKind::ExternCrate(..) | ItemKind::Use(..) => { span_bug!(item.span, "compute_type_of_item: unexpected item type: {:?}", item.kind); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 830dca0d3cd53..3eb4945ebf80e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; @@ -58,9 +58,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - let (trait_bounds, mut projection_bounds) = + let (elaborated_trait_bounds, elaborated_projection_bounds) = traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied()); - let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = trait_bounds + let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = elaborated_trait_bounds .into_iter() .partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id())); @@ -103,29 +103,81 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + // Map the projection bounds onto a key that makes it easy to remove redundant + // bounds that are constrained by supertraits of the principal def id. + // + // Also make sure we detect conflicting bounds from expanding a trait alias and + // also specifying it manually, like: + // ``` + // type Alias = Trait; + // let _: &dyn Alias = /* ... */; + // ``` + let mut projection_bounds = FxIndexMap::default(); + for (proj, proj_span) in elaborated_projection_bounds { + let key = ( + proj.skip_binder().projection_term.def_id, + tcx.anonymize_bound_vars( + proj.map_bound(|proj| proj.projection_term.trait_ref(tcx)), + ), + ); + if let Some((old_proj, old_proj_span)) = + projection_bounds.insert(key, (proj, proj_span)) + && tcx.anonymize_bound_vars(proj) != tcx.anonymize_bound_vars(old_proj) + { + let item = tcx.item_name(proj.item_def_id()); + self.dcx() + .struct_span_err( + span, + format!( + "conflicting associated type bounds for `{item}` when \ + expanding trait alias" + ), + ) + .with_span_label( + old_proj_span, + format!("`{item}` is specified to be `{}` here", old_proj.term()), + ) + .with_span_label( + proj_span, + format!("`{item}` is specified to be `{}` here", proj.term()), + ) + .emit(); + } + } + let principal_trait = regular_traits.into_iter().next(); - let mut needed_associated_types = FxIndexSet::default(); - if let Some((principal_trait, spans)) = &principal_trait { - let pred: ty::Predicate<'tcx> = (*principal_trait).upcast(tcx); - for ClauseWithSupertraitSpan { pred, supertrait_span } in traits::elaborate( + let mut needed_associated_types = vec![]; + if let Some((principal_trait, ref spans)) = principal_trait { + let principal_trait = principal_trait.map_bound(|trait_pred| { + assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive); + trait_pred.trait_ref + }); + + for ClauseWithSupertraitSpan { clause, supertrait_span } in traits::elaborate( tcx, - [ClauseWithSupertraitSpan::new(pred, *spans.last().unwrap())], + [ClauseWithSupertraitSpan::new( + ty::TraitRef::identity(tcx, principal_trait.def_id()).upcast(tcx), + *spans.last().unwrap(), + )], ) .filter_only_self() { - debug!("observing object predicate `{pred:?}`"); + let clause = clause.instantiate_supertrait(tcx, principal_trait); + debug!("observing object predicate `{clause:?}`"); - let bound_predicate = pred.kind(); + let bound_predicate = clause.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { + ty::ClauseKind::Trait(pred) => { // FIXME(negative_bounds): Handle this correctly... let trait_ref = tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref)); needed_associated_types.extend( - tcx.associated_items(trait_ref.def_id()) + tcx.associated_items(pred.trait_ref.def_id) .in_definition_order() + // We only care about associated types. .filter(|item| item.kind == ty::AssocKind::Type) + // No RPITITs -- even with `async_fn_in_dyn_trait`, they are implicit. .filter(|item| !item.is_impl_trait_in_trait()) // If the associated type has a `where Self: Sized` bound, // we do not need to constrain the associated type. @@ -133,7 +185,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|item| (item.def_id, trait_ref)), ); } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { + ty::ClauseKind::Projection(pred) => { let pred = bound_predicate.rebind(pred); // A `Self` within the original bound will be instantiated with a // `trait_object_dummy_self`, so check for that. @@ -161,8 +213,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `dyn MyTrait`, which is uglier but works. See // the discussion in #56288 for alternatives. if !references_self { - // Include projections defined on supertraits. - projection_bounds.push((pred, supertrait_span)); + let key = ( + pred.skip_binder().projection_term.def_id, + tcx.anonymize_bound_vars( + pred.map_bound(|proj| proj.projection_term.trait_ref(tcx)), + ), + ); + if !projection_bounds.contains_key(&key) { + projection_bounds.insert(key, (pred, supertrait_span)); + } } self.check_elaborated_projection_mentions_input_lifetimes( @@ -182,12 +241,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // types that we expect to be provided by the user, so the following loop // removes all the associated types that have a corresponding `Projection` // clause, either from expanding trait aliases or written by the user. - for &(projection_bound, span) in &projection_bounds { + for &(projection_bound, span) in projection_bounds.values() { let def_id = projection_bound.item_def_id(); - let trait_ref = tcx.anonymize_bound_vars( - projection_bound.map_bound(|p| p.projection_term.trait_ref(tcx)), - ); - needed_associated_types.swap_remove(&(def_id, trait_ref)); if tcx.generics_require_sized_self(def_id) { tcx.emit_node_span_lint( UNUSED_ASSOCIATED_TYPE_BOUNDS, @@ -198,9 +253,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + let mut missing_assoc_types = FxIndexSet::default(); + let projection_bounds: Vec<_> = needed_associated_types + .into_iter() + .filter_map(|key| { + if let Some(assoc) = projection_bounds.get(&key) { + Some(*assoc) + } else { + missing_assoc_types.insert(key); + None + } + }) + .collect(); + if let Err(guar) = self.check_for_required_assoc_tys( principal_trait.as_ref().map_or(smallvec![], |(_, spans)| spans.clone()), - needed_associated_types, + missing_assoc_types, potential_assoc_types, hir_bounds, ) { @@ -266,7 +334,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) }); - let existential_projections = projection_bounds.iter().map(|(bound, _)| { + let existential_projections = projection_bounds.into_iter().map(|(bound, _)| { bound.map_bound(|mut b| { assert_eq!(b.projection_term.self_ty(), dummy_self); @@ -291,12 +359,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) }); - let auto_trait_predicates = auto_traits.into_iter().map(|(trait_pred, _)| { - assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive); - assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self); + let mut auto_trait_predicates: Vec<_> = auto_traits + .into_iter() + .map(|(trait_pred, _)| { + assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive); + assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self); - ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id())) - }); + ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id())) + }) + .collect(); + auto_trait_predicates.dedup(); // N.b. principal, projections, auto traits // FIXME: This is actually wrong with multiple principals in regards to symbol mangling @@ -306,7 +378,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .chain(auto_trait_predicates) .collect::>(); v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); - v.dedup(); let existential_predicates = tcx.mk_poly_existential_predicates(&v); // Use explicitly-specified region bound, unless the bound is missing. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 34124a6aa11a3..b9cdf3ddc346a 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -692,7 +692,7 @@ impl<'a> State<'a> { } self.bclose(item.span); } - hir::ItemKind::GlobalAsm(asm) => { + hir::ItemKind::GlobalAsm { asm, .. } => { self.head("global_asm!"); self.print_inline_asm(asm); self.end() @@ -1431,10 +1431,10 @@ impl<'a> State<'a> { s.space(); s.print_anon_const(anon_const); } - hir::InlineAsmOperand::SymFn { ref anon_const } => { + hir::InlineAsmOperand::SymFn { ref expr } => { s.word("sym_fn"); s.space(); - s.print_anon_const(anon_const); + s.print_expr(expr); } hir::InlineAsmOperand::SymStatic { ref path, def_id: _ } => { s.word("sym_static"); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1c63b8b365594..d32e280059488 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3763,7 +3763,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut diverge = asm.asm_macro.diverges(asm.options); for (op, _op_sp) in asm.operands { - match op { + match *op { hir::InlineAsmOperand::In { expr, .. } => { self.check_expr_asm_operand(expr, true); } @@ -3778,10 +3778,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr_asm_operand(out_expr, false); } } + hir::InlineAsmOperand::SymFn { expr } => { + self.check_expr(expr); + } // `AnonConst`s have their own body and is type-checked separately. // As they don't flow into the type system we don't need them to // be well-formed. - hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymFn { .. } => {} + hir::InlineAsmOperand::Const { .. } => {} hir::InlineAsmOperand::SymStatic { .. } => {} hir::InlineAsmOperand::Label { block } => { let previous_diverges = self.diverges.get(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 7ca44d23e3ed6..c619e0f223221 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -101,7 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len()); for (asm, hir_id) in deferred_asm_checks.drain(..) { let enclosing_id = self.tcx.hir_enclosing_body_owner(hir_id); - let get_operand_ty = |expr| { + let expr_ty = |expr: &hir::Expr<'tcx>| { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); if ty.has_non_region_infer() { @@ -110,12 +110,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.erase_regions(ty) } }; - InlineAsmCtxt::new_in_fn( - self.tcx, - self.infcx.typing_env(self.param_env), - get_operand_ty, - ) - .check_asm(asm, enclosing_id); + InlineAsmCtxt::new(self.tcx, enclosing_id, expr_ty).check_asm(asm); } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 9d5184acb3ca7..0130ad775d9e7 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -133,7 +133,12 @@ fn typeck_with_inspect<'tcx>( } let mut fcx = FnCtxt::new(&root_ctxt, param_env, def_id); - if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() { + if let hir::Node::Item(hir::Item { kind: hir::ItemKind::GlobalAsm { .. }, .. }) = node { + // Check the fake body of a global ASM. There's not much to do here except + // for visit the asm expr of the body. + let ty = fcx.check_expr(body.value); + fcx.write_ty(id, ty); + } else if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() { let fn_sig = if decl.output.is_suggestable_infer_ty().is_some() { // In the case that we're recovering `fn() -> W<_>` or some other return // type that has an infer in it, lower the type directly so that it'll @@ -277,12 +282,9 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti Some(fcx.next_ty_var(span)) } Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. }) - | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => { + | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm { asm, .. }, span, .. }) => { asm.operands.iter().find_map(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } - if anon_const.hir_id == id => - { + hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => { Some(fcx.next_ty_var(span)) } _ => None, diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 8c50cc59c1d5e..3e9ce0e11e402 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -48,13 +48,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for param in body.params { wbcx.visit_node_id(param.pat.span, param.hir_id); } - // Type only exists for constants and statics, not functions. match self.tcx.hir_body_owner_kind(item_def_id) { - hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) => { + // Visit the type of a const or static, which is used during THIR building. + hir::BodyOwnerKind::Const { .. } + | hir::BodyOwnerKind::Static(_) + | hir::BodyOwnerKind::GlobalAsm => { let item_hir_id = self.tcx.local_def_id_to_hir_id(item_def_id); wbcx.visit_node_id(body.value.span, item_hir_id); } - hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => (), + // For closures and consts, we already plan to visit liberated signatures. + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => {} } wbcx.visit_body(body); wbcx.visit_min_capture_map(); diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 118a6fed036ed..56858679af663 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -261,7 +261,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { HirItem::ForeignMod { .. } => ("ItemForeignMod", LABELS_HIR_ONLY), // Module-level inline assembly (from global_asm!) - HirItem::GlobalAsm(..) => ("ItemGlobalAsm", LABELS_HIR_ONLY), + HirItem::GlobalAsm { .. } => ("ItemGlobalAsm", LABELS_HIR_ONLY), // A type alias, e.g., `type Foo = Bar` HirItem::TyAlias(..) => ("ItemTy", LABELS_HIR_ONLY), diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index e449f1106131d..e8c2c43786827 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2909,7 +2909,13 @@ enum AsmLabelKind { impl<'tcx> LateLintPass<'tcx> for AsmLabels { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { if let hir::Expr { - kind: hir::ExprKind::InlineAsm(hir::InlineAsm { template_strs, options, .. }), + kind: + hir::ExprKind::InlineAsm(hir::InlineAsm { + asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm, + template_strs, + options, + .. + }), .. } = expr { diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index d2956d94685f1..0b3af7d6aba98 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -86,8 +86,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail - /// # #![feature(lifetime_capture_rules_2024)] + /// ```rust,edition2024,compile_fail /// # #![deny(impl_trait_redundant_captures)] /// fn test<'a>(x: &'a i32) -> impl Sized + use<'a> { x } /// ``` @@ -268,8 +267,7 @@ where && parent == self.parent_def_id { let opaque_span = self.tcx.def_span(opaque_def_id); - let new_capture_rules = opaque_span.at_least_rust_2024() - || self.tcx.features().lifetime_capture_rules_2024(); + let new_capture_rules = opaque_span.at_least_rust_2024(); if !new_capture_rules && !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..))) { diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 68b1f435a4cf7..4930cc35c9c3d 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1740,7 +1740,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { hir::ItemKind::Impl(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Trait(..) - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::ForeignMod { .. } | hir::ItemKind::Mod(..) | hir::ItemKind::Macro(..) diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 3436c2f372f49..e611dbb5bdf42 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -305,6 +305,7 @@ impl<'tcx> TyCtxt<'tcx> { DefKind::Static { safety: _, mutability, nested: false } => { BodyOwnerKind::Static(mutability) } + DefKind::GlobalAsm => BodyOwnerKind::GlobalAsm, dk => bug!("{:?} is not a body node: {:?}", def_id, dk), } } @@ -327,7 +328,7 @@ impl<'tcx> TyCtxt<'tcx> { ConstContext::ConstFn } BodyOwnerKind::Fn if self.is_const_default_method(def_id) => ConstContext::ConstFn, - BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None, + BodyOwnerKind::Fn | BodyOwnerKind::Closure | BodyOwnerKind::GlobalAsm => return None, }; Some(ccx) @@ -1164,7 +1165,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { ItemKind::Macro(..) => "macro", ItemKind::Mod(..) => "mod", ItemKind::ForeignMod { .. } => "foreign mod", - ItemKind::GlobalAsm(..) => "global asm", + ItemKind::GlobalAsm { .. } => "global asm", ItemKind::TyAlias(..) => "ty", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 98e8f269c57b7..af09a6d570bab 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1364,13 +1364,13 @@ impl PlaceContext { matches!(self, PlaceContext::MutatingUse(MutatingUseContext::Drop)) } - /// Returns `true` if this place context represents a borrow. + /// Returns `true` if this place context represents a borrow, excluding fake borrows + /// (which are an artifact of borrowck and not actually borrows in runtime MIR). pub fn is_borrow(self) -> bool { matches!( self, - PlaceContext::NonMutatingUse( - NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::FakeBorrow - ) | PlaceContext::MutatingUse(MutatingUseContext::Borrow) + PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) + | PlaceContext::MutatingUse(MutatingUseContext::Borrow) ) } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 98cc00c367cfe..6a2672ac02b75 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -94,6 +94,7 @@ thir_with_elements! { pub enum BodyTy<'tcx> { Const(Ty<'tcx>), Fn(FnSig<'tcx>), + GlobalAsm(Ty<'tcx>), } /// Description of a type-checked function parameter. @@ -605,8 +606,7 @@ pub enum InlineAsmOperand<'tcx> { span: Span, }, SymFn { - value: mir::Const<'tcx>, - span: Span, + value: ExprId, }, SymStatic { def_id: DefId, diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 13b8af55e518e..e347a64e45d0f 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -172,7 +172,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( } Out { expr: None, reg: _, late: _ } | Const { value: _, span: _ } - | SymFn { value: _, span: _ } + | SymFn { value: _ } | SymStatic { def_id: _ } => {} Label { block } => visitor.visit_block(&visitor.thir()[*block]), } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 53bc9eb7e466c..54cd8cc3efe75 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -12,7 +12,7 @@ use std::borrow::Cow; use std::hash::{Hash, Hasher}; use std::sync::Arc; -use rustc_errors::{Applicability, Diag, EmissionGuarantee}; +use rustc_errors::{Applicability, Diag, EmissionGuarantee, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def_id::DefId; @@ -996,4 +996,7 @@ pub enum CodegenObligationError { /// but was included during typeck due to the trivial_bounds feature. Unimplemented, FulfillmentError, + /// The selected impl has unconstrained generic parameters. This will emit an error + /// during impl WF checking. + UnconstrainedParam(ErrorGuaranteed), } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 35893ad953d1a..b2562f7d0307a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1473,7 +1473,11 @@ impl<'tcx> TyCtxt<'tcx> { self.codegen_fn_attrs(def_id) } else if matches!( def_kind, - DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::InlineConst + DefKind::AnonConst + | DefKind::AssocConst + | DefKind::Const + | DefKind::InlineConst + | DefKind::GlobalAsm ) { CodegenFnAttrs::EMPTY } else { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index afdec7a86d445..839c1c346a47b 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -79,20 +79,14 @@ impl<'tcx> Relate> for &'tcx ty::List RelateResult<'tcx, Self> { let tcx = relation.cx(); - - // FIXME: this is wasteful, but want to do a perf run to see how slow it is. - // We need to perform this deduplication as we sometimes generate duplicate projections - // in `a`. - let mut a_v: Vec<_> = a.into_iter().collect(); - let mut b_v: Vec<_> = b.into_iter().collect(); - a_v.dedup(); - b_v.dedup(); - if a_v.len() != b_v.len() { + // Fast path for when the auto traits do not match, or if the principals + // are from different traits and therefore the projections definitely don't + // match up. + if a.len() != b.len() { return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))); } - - let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { - match (ep_a.skip_binder(), ep_b.skip_binder()) { + let v = + iter::zip(a, b).map(|(ep_a, ep_b)| match (ep_a.skip_binder(), ep_b.skip_binder()) { (ty::ExistentialPredicate::Trait(a), ty::ExistentialPredicate::Trait(b)) => { Ok(ep_a.rebind(ty::ExistentialPredicate::Trait( relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), @@ -109,8 +103,7 @@ impl<'tcx> Relate> for &'tcx ty::List Ok(ep_a.rebind(ty::ExistentialPredicate::AutoTrait(a))), _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))), - } - }); + }); tcx.mk_poly_existential_predicates_from_iter(v) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8a31b2960188e..9eda760870716 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -18,7 +18,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use rustc_type_ir::TyKind::*; use rustc_type_ir::visit::TypeVisitableExt; -use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind}; +use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, elaborate}; use tracing::instrument; use ty::util::{AsyncDropGlueMorphology, IntTypeExt}; @@ -720,6 +720,34 @@ impl<'tcx> Ty<'tcx> { reg: ty::Region<'tcx>, repr: DynKind, ) -> Ty<'tcx> { + if cfg!(debug_assertions) { + let projection_count = obj.projection_bounds().count(); + let expected_count: usize = obj + .principal_def_id() + .into_iter() + .flat_map(|principal_def_id| { + // NOTE: This should agree with `needed_associated_types` in + // dyn trait lowering, or else we'll have ICEs. + elaborate::supertraits( + tcx, + ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)), + ) + .map(|principal| { + tcx.associated_items(principal.def_id()) + .in_definition_order() + .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| !item.is_impl_trait_in_trait()) + .filter(|item| !tcx.generics_require_sized_self(item.def_id)) + .count() + }) + }) + .sum(); + assert_eq!( + projection_count, expected_count, + "expected {obj:?} to have {expected_count} projections, \ + but it has {projection_count}" + ); + } Ty::new(tcx, Dynamic(obj, reg, repr)) } diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 65dd061003d8d..72443e2f60ddc 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -482,15 +482,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }), } } - thir::InlineAsmOperand::SymFn { value, span } => { - mir::InlineAsmOperand::SymFn { - value: Box::new(ConstOperand { - span, - user_ty: None, - const_: value, - }), - } - } + thir::InlineAsmOperand::SymFn { value } => mir::InlineAsmOperand::SymFn { + value: Box::new(this.as_constant(&this.thir[value])), + }, thir::InlineAsmOperand::SymStatic { def_id } => { mir::InlineAsmOperand::SymStatic { def_id } } @@ -518,10 +512,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let asm_macro = match asm_macro { - AsmMacro::Asm => InlineAsmMacro::Asm, - AsmMacro::GlobalAsm => { - span_bug!(expr_span, "unexpected global_asm! in inline asm") - } + AsmMacro::Asm | AsmMacro::GlobalAsm => InlineAsmMacro::Asm, AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm, }; diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 4348b7a4b4cc9..949559549345f 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -61,7 +61,9 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { Ok((thir, expr)) => { let build_mir = |thir: &Thir<'tcx>| match thir.body_type { thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, thir, expr, fn_sig), - thir::BodyTy::Const(ty) => construct_const(tcx, def, thir, expr, ty), + thir::BodyTy::Const(ty) | thir::BodyTy::GlobalAsm(ty) => { + construct_const(tcx, def, thir, expr, ty) + } }; // this must run before MIR dump, because @@ -576,6 +578,7 @@ fn construct_const<'a, 'tcx>( let span = tcx.def_span(def); (span, span) } + Node::Item(hir::Item { kind: hir::ItemKind::GlobalAsm { .. }, span, .. }) => (*span, *span), _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def), }; diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 84f58f1968db2..ed663a9c76058 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::mem; use std::ops::Bound; +use rustc_ast::AsmMacro; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::DiagArgValue; use rustc_hir::def::DefKind; @@ -559,7 +560,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } } ExprKind::InlineAsm(box InlineAsmExpr { - asm_macro: _, + asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm, ref operands, template: _, options: _, @@ -583,7 +584,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } Out { expr: None, reg: _, late: _ } | Const { value: _, span: _ } - | SymFn { value: _, span: _ } + | SymFn { value: _ } | SymStatic { def_id: _ } => {} Label { block } => { // Label blocks are safe context. diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index d0fca76fcf05d..29bc1d6572dfa 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -739,13 +739,8 @@ impl<'tcx> ThirBuildCx<'tcx> { InlineAsmOperand::Const { value, span } } - hir::InlineAsmOperand::SymFn { ref anon_const } => { - let value = - mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id()) - .instantiate_identity(); - let span = tcx.def_span(anon_const.def_id); - - InlineAsmOperand::SymFn { value, span } + hir::InlineAsmOperand::SymFn { expr } => { + InlineAsmOperand::SymFn { value: self.mirror_expr(expr) } } hir::InlineAsmOperand::SymStatic { path: _, def_id } => { InlineAsmOperand::SymStatic { def_id } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 7a9f6e4630456..c32082c609ec4 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -76,23 +76,29 @@ impl<'tcx> ThirBuildCx<'tcx> { let hir = tcx.hir(); let hir_id = tcx.local_def_id_to_hir_id(def); - let body_type = if tcx.hir_body_owner_kind(def).is_fn_or_closure() { - // fetch the fully liberated fn signature (that is, all bound - // types/lifetimes replaced) - BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id]) - } else { - // Get the revealed type of this const. This is *not* the adjusted - // type of its body, which may be a subtype of this type. For - // example: - // - // fn foo(_: &()) {} - // static X: fn(&'static ()) = foo; - // - // The adjusted type of the body of X is `for<'a> fn(&'a ())` which - // is not the same as the type of X. We need the type of the return - // place to be the type of the constant because NLL typeck will - // equate them. - BodyTy::Const(typeck_results.node_type(hir_id)) + let body_type = match tcx.hir_body_owner_kind(def) { + rustc_hir::BodyOwnerKind::Fn | rustc_hir::BodyOwnerKind::Closure => { + // fetch the fully liberated fn signature (that is, all bound + // types/lifetimes replaced) + BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id]) + } + rustc_hir::BodyOwnerKind::Const { .. } | rustc_hir::BodyOwnerKind::Static(_) => { + // Get the revealed type of this const. This is *not* the adjusted + // type of its body, which may be a subtype of this type. For + // example: + // + // fn foo(_: &()) {} + // static X: fn(&'static ()) = foo; + // + // The adjusted type of the body of X is `for<'a> fn(&'a ())` which + // is not the same as the type of X. We need the type of the return + // place to be the type of the constant because NLL typeck will + // equate them. + BodyTy::Const(typeck_results.node_type(hir_id)) + } + rustc_hir::BodyOwnerKind::GlobalAsm => { + BodyTy::GlobalAsm(typeck_results.node_type(hir_id)) + } }; Self { diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 9ab87dd99ffc0..cd56d93afcf75 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -921,10 +921,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); print_indented!(self, "}", depth_lvl + 1); } - InlineAsmOperand::SymFn { value, span } => { + InlineAsmOperand::SymFn { value } => { print_indented!(self, "InlineAsmOperand::SymFn {", depth_lvl); - print_indented!(self, format!("value: {:?}", *value), depth_lvl + 1); - print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); + print_indented!(self, "value: ", depth_lvl + 1); + self.print_expr(*value, depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } InlineAsmOperand::SymStatic { def_id } => { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1195c25e13087..694a4dd5b4c4c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -479,24 +479,23 @@ fn collect_items_rec<'tcx>( recursion_depth_reset = None; let item = tcx.hir_item(item_id); - if let hir::ItemKind::GlobalAsm(asm) = item.kind { + if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind { for (op, op_sp) in asm.operands { - match op { + match *op { hir::InlineAsmOperand::Const { .. } => { // Only constants which resolve to a plain integer // are supported. Therefore the value should not // depend on any other items. } - hir::InlineAsmOperand::SymFn { anon_const } => { - let fn_ty = - tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + hir::InlineAsmOperand::SymFn { expr } => { + let fn_ty = tcx.typeck(item_id.owner_id).expr_ty(expr); visit_fn_use(tcx, fn_ty, false, *op_sp, &mut used_items); } hir::InlineAsmOperand::SymStatic { path: _, def_id } => { - let instance = Instance::mono(tcx, *def_id); + let instance = Instance::mono(tcx, def_id); if tcx.should_codegen_locally(instance) { trace!("collecting static {:?}", def_id); - used_items.push(dummy_spanned(MonoItem::Static(*def_id))); + used_items.push(dummy_spanned(MonoItem::Static(def_id))); } } hir::InlineAsmOperand::In { .. } diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 7eeed721d5a0f..9cae7f27947b4 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; -use rustc_type_ir::data_structures::HashMap; +use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack}; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::solve::{Goal, QueryInput}; @@ -389,7 +389,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { | ty::Alias(_, _) | ty::Bound(_, _) | ty::Error(_) => { - return t.super_fold_with(self); + return ensure_sufficient_stack(|| t.super_fold_with(self)); } }; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 1fe44bd3d21a9..fd465717bf766 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -246,7 +246,7 @@ impl<'tcx> ReachableContext<'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) - | hir::ItemKind::GlobalAsm(..) => {} + | hir::ItemKind::GlobalAsm { .. } => {} } } Node::TraitItem(trait_method) => { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 6faa2c1a00d23..41725d0c6a4f9 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -645,7 +645,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // The interface is empty, and no nested items. hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(..) - | hir::ItemKind::GlobalAsm(..) => {} + | hir::ItemKind::GlobalAsm { .. } => {} // The interface is empty, and all nested items are processed by `visit_item`. hir::ItemKind::Mod(..) => {} hir::ItemKind::Macro(macro_def, _) => { diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index e5276e6d51585..cc329ca33288c 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -80,16 +80,14 @@ pub(crate) fn codegen_select_candidate<'tcx>( // but never resolved, causing the return value of a query to contain inference // vars. We do not have a concept for this and will in fact ICE in stable hashing // of the return value. So bail out instead. - match impl_source { - ImplSource::UserDefined(impl_) => { - tcx.dcx().span_delayed_bug( - tcx.def_span(impl_.impl_def_id), - "this impl has unconstrained generic parameters", - ); - } + let guar = match impl_source { + ImplSource::UserDefined(impl_) => tcx.dcx().span_delayed_bug( + tcx.def_span(impl_.impl_def_id), + "this impl has unconstrained generic parameters", + ), _ => unreachable!(), - } - return Err(CodegenObligationError::FulfillmentError); + }; + return Err(CodegenObligationError::UnconstrainedParam(guar)); } Ok(&*tcx.arena.alloc(impl_source)) diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 8c6e3c86bf5c8..d059d6dcd139c 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -112,6 +112,7 @@ fn resolve_associated_item<'tcx>( | CodegenObligationError::Unimplemented | CodegenObligationError::FulfillmentError, ) => return Ok(None), + Err(CodegenObligationError::UnconstrainedParam(guar)) => return Err(guar), }; // Now that we know which impl is being used, we can dispatch to diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index b6a14d147cad4..c8b3c8a796f3a 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -147,12 +147,25 @@ fn extract_const_value<'tcx>( ) -> Result, &'tcx LayoutError<'tcx>> { match ct.kind() { ty::ConstKind::Value(cv) => Ok(cv), - ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) => { + ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) => { if !ct.has_param() { bug!("failed to normalize const, but it is not generic: {ct:?}"); } Err(error(cx, LayoutError::TooGeneric(ty))) } + ty::ConstKind::Unevaluated(_) => { + let err = if ct.has_param() { + LayoutError::TooGeneric(ty) + } else { + // This case is reachable with unsatisfiable predicates and GCE (which will + // cause anon consts to inherit the unsatisfiable predicates). For example + // if we have an unsatisfiable `u8: Trait` bound, then it's not a compile + // error to mention `[u8; ::CONST]`, but we can't compute its + // layout. + LayoutError::Unknown(ty) + }; + Err(error(cx, err)) + } ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 923b74abdfd2f..b11bcff1d8bbb 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -44,25 +44,22 @@ pub trait Elaboratable { } pub struct ClauseWithSupertraitSpan { - pub pred: I::Predicate, + pub clause: I::Clause, // Span of the supertrait predicatae that lead to this clause. pub supertrait_span: I::Span, } impl ClauseWithSupertraitSpan { - pub fn new(pred: I::Predicate, span: I::Span) -> Self { - ClauseWithSupertraitSpan { pred, supertrait_span: span } + pub fn new(clause: I::Clause, span: I::Span) -> Self { + ClauseWithSupertraitSpan { clause, supertrait_span: span } } } impl Elaboratable for ClauseWithSupertraitSpan { fn predicate(&self) -> ::Predicate { - self.pred + self.clause.as_predicate() } fn child(&self, clause: ::Clause) -> Self { - ClauseWithSupertraitSpan { - pred: clause.as_predicate(), - supertrait_span: self.supertrait_span, - } + ClauseWithSupertraitSpan { clause, supertrait_span: self.supertrait_span } } fn child_with_derived_cause( @@ -72,7 +69,7 @@ impl Elaboratable for ClauseWithSupertraitSpan { _parent_trait_pred: crate::Binder>, _index: usize, ) -> Self { - ClauseWithSupertraitSpan { pred: clause.as_predicate(), supertrait_span } + ClauseWithSupertraitSpan { clause, supertrait_span } } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index b3f4a7bad99c2..5fc3e8469bb75 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1762,7 +1762,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--coverage-dump-path").arg(coverage_dump); } - cmd.arg("--src-base").arg(builder.src.join("tests").join(suite)); + cmd.arg("--src-root").arg(&builder.src); + cmd.arg("--src-test-suite-root").arg(builder.src.join("tests").join(suite)); + cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite)); // When top stage is 0, that means that we're testing an externally provided compiler. diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 658d5965b3d2a..ce9c42c01cc73 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -288,7 +288,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { | ItemKind::Use(_, _) | ItemKind::ExternCrate(_) | ItemKind::ForeignMod { .. } - | ItemKind::GlobalAsm(_) + | ItemKind::GlobalAsm { .. } // We already have "visit_mod" above so no need to check it here. | ItemKind::Mod(_) => {} } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f606a3d8a9270..7b6921afa0808 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -439,7 +439,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } // If we're inlining, skip private items. _ if self.inlining && !is_pub => {} - hir::ItemKind::GlobalAsm(..) => {} + hir::ItemKind::GlobalAsm { .. } => {} hir::ItemKind::Use(_, hir::UseKind::ListStem) => {} hir::ItemKind::Use(path, kind) => { for &res in &path.res { diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index aff40fa846be2..c0ae4960e10d9 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -362,7 +362,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { } } else if let ItemKind::ForeignMod { .. } = item.kind { continue; - } else if let ItemKind::GlobalAsm(_) = item.kind { + } else if let ItemKind::GlobalAsm { .. } = item.kind { continue; } else if let ItemKind::Use(path, use_kind) = item.kind { if path.segments.is_empty() { @@ -467,7 +467,7 @@ fn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleIte ItemKind::Macro(..) => Macro, ItemKind::Mod(..) => Mod, ItemKind::ForeignMod { .. } => ForeignMod, - ItemKind::GlobalAsm(..) => GlobalAsm, + ItemKind::GlobalAsm { .. } => GlobalAsm, ItemKind::TyAlias(..) => TyAlias, ItemKind::Enum(..) => Enum, ItemKind::Struct(..) => Struct, diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 06e92985e6648..47a9e17b3cfe1 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -217,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { | hir::ItemKind::Union(..) => {}, hir::ItemKind::ExternCrate(..) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::Impl { .. } | hir::ItemKind::Use(..) => note_prev_span_then_ret!(self.prev_span, it.span), } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index fdc0930e957a0..3cf1a80607e8b 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::TraitAlias(..) - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::TyAlias(..) | hir::ItemKind::Union(..) | hir::ItemKind::ExternCrate(..) diff --git a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs index cda99a362dcae..c261fd9bd9cb0 100644 --- a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs @@ -82,7 +82,7 @@ impl Context { } self.const_span = Some(body_span); }, - hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => (), + hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::GlobalAsm => (), } } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 9ee30094d608c..0ac675345ae0c 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -968,7 +968,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(out_expr); } }, - InlineAsmOperand::Const { anon_const } | InlineAsmOperand::SymFn { anon_const } => { + InlineAsmOperand::SymFn { expr } => { + self.hash_expr(expr); + } + InlineAsmOperand::Const { anon_const } => { self.hash_body(anon_const.body); }, InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path), diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr index 474914299d069..8c023d0d61f4a 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.stderr +++ b/src/tools/clippy/tests/ui/async_yields_async.stderr @@ -14,9 +14,9 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::async_yields_async)]` help: consider awaiting this value | -LL ~ async { -LL + 3 -LL + }.await +LL | async { +LL | 3 +LL ~ }.await | error: an async construct yields a type which is itself awaitable @@ -46,9 +46,9 @@ LL | | }; | help: consider awaiting this value | -LL ~ async { -LL + 3 -LL + }.await +LL | async { +LL | 3 +LL ~ }.await | error: an async construct yields a type which is itself awaitable diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr index 71f43af46c241..b8a0eedeb9ee8 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr +++ b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr @@ -13,9 +13,8 @@ LL + let x: &str = s; | help: if you would like to deref, try using `&**` | -LL - let x: &str = &*s; -LL + let x: &str = &**s; - | +LL | let x: &str = &**s; + | + error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr index c069c9d1672de..0238e3a91369b 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr @@ -8,9 +8,8 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]` help: did you mean to invoke the function? | -LL - let _ = foo as i8; -LL + let _ = foo() as i8; - | +LL | let _ = foo() as i8; + | ++ error: casting function pointer `foo` to `i16` --> tests/ui/fn_to_numeric_cast_any.rs:26:13 @@ -20,9 +19,8 @@ LL | let _ = foo as i16; | help: did you mean to invoke the function? | -LL - let _ = foo as i16; -LL + let _ = foo() as i16; - | +LL | let _ = foo() as i16; + | ++ error: casting function pointer `foo` to `i32` --> tests/ui/fn_to_numeric_cast_any.rs:28:13 @@ -32,9 +30,8 @@ LL | let _ = foo as i32; | help: did you mean to invoke the function? | -LL - let _ = foo as i32; -LL + let _ = foo() as i32; - | +LL | let _ = foo() as i32; + | ++ error: casting function pointer `foo` to `i64` --> tests/ui/fn_to_numeric_cast_any.rs:30:13 @@ -44,9 +41,8 @@ LL | let _ = foo as i64; | help: did you mean to invoke the function? | -LL - let _ = foo as i64; -LL + let _ = foo() as i64; - | +LL | let _ = foo() as i64; + | ++ error: casting function pointer `foo` to `i128` --> tests/ui/fn_to_numeric_cast_any.rs:32:13 @@ -56,9 +52,8 @@ LL | let _ = foo as i128; | help: did you mean to invoke the function? | -LL - let _ = foo as i128; -LL + let _ = foo() as i128; - | +LL | let _ = foo() as i128; + | ++ error: casting function pointer `foo` to `isize` --> tests/ui/fn_to_numeric_cast_any.rs:34:13 @@ -68,9 +63,8 @@ LL | let _ = foo as isize; | help: did you mean to invoke the function? | -LL - let _ = foo as isize; -LL + let _ = foo() as isize; - | +LL | let _ = foo() as isize; + | ++ error: casting function pointer `foo` to `u8` --> tests/ui/fn_to_numeric_cast_any.rs:37:13 @@ -80,9 +74,8 @@ LL | let _ = foo as u8; | help: did you mean to invoke the function? | -LL - let _ = foo as u8; -LL + let _ = foo() as u8; - | +LL | let _ = foo() as u8; + | ++ error: casting function pointer `foo` to `u16` --> tests/ui/fn_to_numeric_cast_any.rs:39:13 @@ -92,9 +85,8 @@ LL | let _ = foo as u16; | help: did you mean to invoke the function? | -LL - let _ = foo as u16; -LL + let _ = foo() as u16; - | +LL | let _ = foo() as u16; + | ++ error: casting function pointer `foo` to `u32` --> tests/ui/fn_to_numeric_cast_any.rs:41:13 @@ -104,9 +96,8 @@ LL | let _ = foo as u32; | help: did you mean to invoke the function? | -LL - let _ = foo as u32; -LL + let _ = foo() as u32; - | +LL | let _ = foo() as u32; + | ++ error: casting function pointer `foo` to `u64` --> tests/ui/fn_to_numeric_cast_any.rs:43:13 @@ -116,9 +107,8 @@ LL | let _ = foo as u64; | help: did you mean to invoke the function? | -LL - let _ = foo as u64; -LL + let _ = foo() as u64; - | +LL | let _ = foo() as u64; + | ++ error: casting function pointer `foo` to `u128` --> tests/ui/fn_to_numeric_cast_any.rs:45:13 @@ -128,9 +118,8 @@ LL | let _ = foo as u128; | help: did you mean to invoke the function? | -LL - let _ = foo as u128; -LL + let _ = foo() as u128; - | +LL | let _ = foo() as u128; + | ++ error: casting function pointer `foo` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:47:13 @@ -140,9 +129,8 @@ LL | let _ = foo as usize; | help: did you mean to invoke the function? | -LL - let _ = foo as usize; -LL + let _ = foo() as usize; - | +LL | let _ = foo() as usize; + | ++ error: casting function pointer `Struct::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:52:13 @@ -152,9 +140,8 @@ LL | let _ = Struct::static_method as usize; | help: did you mean to invoke the function? | -LL - let _ = Struct::static_method as usize; -LL + let _ = Struct::static_method() as usize; - | +LL | let _ = Struct::static_method() as usize; + | ++ error: casting function pointer `f` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:57:5 @@ -164,9 +151,8 @@ LL | f as usize | help: did you mean to invoke the function? | -LL - f as usize -LL + f() as usize - | +LL | f() as usize + | ++ error: casting function pointer `T::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:62:5 @@ -176,9 +162,8 @@ LL | T::static_method as usize | help: did you mean to invoke the function? | -LL - T::static_method as usize -LL + T::static_method() as usize - | +LL | T::static_method() as usize + | ++ error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:69:13 @@ -188,9 +173,8 @@ LL | let _ = (clos as fn(u32) -> u32) as usize; | help: did you mean to invoke the function? | -LL - let _ = (clos as fn(u32) -> u32) as usize; -LL + let _ = (clos as fn(u32) -> u32)() as usize; - | +LL | let _ = (clos as fn(u32) -> u32)() as usize; + | ++ error: casting function pointer `foo` to `*const ()` --> tests/ui/fn_to_numeric_cast_any.rs:74:13 @@ -200,9 +184,8 @@ LL | let _ = foo as *const (); | help: did you mean to invoke the function? | -LL - let _ = foo as *const (); -LL + let _ = foo() as *const (); - | +LL | let _ = foo() as *const (); + | ++ error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/implicit_hasher.stderr b/src/tools/clippy/tests/ui/implicit_hasher.stderr index 6e964c65a2e42..01d08a1bd9b2a 100644 --- a/src/tools/clippy/tests/ui/implicit_hasher.stderr +++ b/src/tools/clippy/tests/ui/implicit_hasher.stderr @@ -78,9 +78,8 @@ LL | pub fn map(map: &mut HashMap) {} | help: add a type parameter for `BuildHasher` | -LL - pub fn map(map: &mut HashMap) {} -LL + pub fn map(map: &mut HashMap) {} - | +LL | pub fn map(map: &mut HashMap) {} + | +++++++++++++++++++++++++++++ +++ error: parameter of type `HashSet` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:70:22 @@ -90,9 +89,8 @@ LL | pub fn set(set: &mut HashSet) {} | help: add a type parameter for `BuildHasher` | -LL - pub fn set(set: &mut HashSet) {} -LL + pub fn set(set: &mut HashSet) {} - | +LL | pub fn set(set: &mut HashSet) {} + | +++++++++++++++++++++++++++++ +++ error: impl for `HashMap` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:76:43 @@ -116,9 +114,8 @@ LL | pub async fn election_vote(_data: HashMap) {} | help: add a type parameter for `BuildHasher` | -LL - pub async fn election_vote(_data: HashMap) {} -LL + pub async fn election_vote(_data: HashMap) {} - | +LL | pub async fn election_vote(_data: HashMap) {} + | +++++++++++++++++++++++++++++ +++ error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/implicit_return.stderr b/src/tools/clippy/tests/ui/implicit_return.stderr index 7ea72307450c7..936a779fa747d 100644 --- a/src/tools/clippy/tests/ui/implicit_return.stderr +++ b/src/tools/clippy/tests/ui/implicit_return.stderr @@ -9,7 +9,7 @@ LL | true help: add `return` as shown | LL | return true - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:19:15 @@ -122,7 +122,7 @@ LL | format!("test {}", "test") help: add `return` as shown | LL | return format!("test {}", "test") - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:90:5 @@ -133,7 +133,7 @@ LL | m!(true, false) help: add `return` as shown | LL | return m!(true, false) - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:96:13 @@ -169,10 +169,8 @@ LL | | } | help: add `return` as shown | -LL ~ return loop { -LL + m!(true); -LL + } - | +LL | return loop { + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:130:5 @@ -183,7 +181,7 @@ LL | true help: add `return` as shown | LL | return true - | + | ++++++ error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr index a9192825b3543..576b38a47d2de 100644 --- a/src/tools/clippy/tests/ui/literals.stderr +++ b/src/tools/clippy/tests/ui/literals.stderr @@ -99,9 +99,8 @@ LL + let fail8 = 123; | help: if you mean to use an octal constant, use `0o` | -LL - let fail8 = 0123; -LL + let fail8 = 0o123; - | +LL | let fail8 = 0o123; + | + error: integer type suffix should not be separated by an underscore --> tests/ui/literals.rs:48:16 diff --git a/src/tools/clippy/tests/ui/manual_flatten.stderr b/src/tools/clippy/tests/ui/manual_flatten.stderr index cf1b0a1c8bbf6..93f7f11b5e64c 100644 --- a/src/tools/clippy/tests/ui/manual_flatten.stderr +++ b/src/tools/clippy/tests/ui/manual_flatten.stderr @@ -196,11 +196,9 @@ LL | | } | |_________^ help: try | -LL ~ for n in vec![ -LL + -LL + Some(1), -LL + Some(2), -LL + Some(3) +LL | for n in vec![ +... +LL | Some(3) LL ~ ].iter().flatten() { | diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr index c8a89ac8bea42..61c781e316ef3 100644 --- a/src/tools/clippy/tests/ui/octal_escapes.stderr +++ b/src/tools/clippy/tests/ui/octal_escapes.stderr @@ -14,9 +14,8 @@ LL + let _bad1 = "\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad1 = "\033[0m"; -LL + let _bad1 = "\x0033[0m"; - | +LL | let _bad1 = "\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:6:19 @@ -31,9 +30,8 @@ LL + let _bad2 = b"\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad2 = b"\033[0m"; -LL + let _bad2 = b"\x0033[0m"; - | +LL | let _bad2 = b"\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:7:20 @@ -48,9 +46,8 @@ LL + let _bad3 = "\\\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad3 = "\\\033[0m"; -LL + let _bad3 = "\\\x0033[0m"; - | +LL | let _bad3 = "\\\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:9:18 @@ -65,9 +62,8 @@ LL + let _bad4 = "\x0a34567"; | help: if a null escape is intended, disambiguate using | -LL - let _bad4 = "\01234567"; -LL + let _bad4 = "\x001234567"; - | +LL | let _bad4 = "\x001234567"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:10:20 @@ -77,14 +73,12 @@ LL | let _bad5 = "\0\03"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad5 = "\0\03"; -LL + let _bad5 = "\0\x03"; - | +LL | let _bad5 = "\0\x03"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad5 = "\0\03"; -LL + let _bad5 = "\0\x0003"; - | +LL | let _bad5 = "\0\x0003"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:23 @@ -99,9 +93,8 @@ LL + let _bad6 = "Text-\x2d\077-MoreText"; | help: if a null escape is intended, disambiguate using | -LL - let _bad6 = "Text-\055\077-MoreText"; -LL + let _bad6 = "Text-\x0055\077-MoreText"; - | +LL | let _bad6 = "Text-\x0055\077-MoreText"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:27 @@ -116,9 +109,8 @@ LL + let _bad6 = "Text-\055\x3f-MoreText"; | help: if a null escape is intended, disambiguate using | -LL - let _bad6 = "Text-\055\077-MoreText"; -LL + let _bad6 = "Text-\055\x0077-MoreText"; - | +LL | let _bad6 = "Text-\055\x0077-MoreText"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:31 @@ -128,14 +120,12 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:34 @@ -145,14 +135,12 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:17:19 @@ -162,14 +150,12 @@ LL | let _bad8 = "锈\01锈"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad8 = "锈\01锈"; -LL + let _bad8 = "锈\x01锈"; - | +LL | let _bad8 = "锈\x01锈"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad8 = "锈\01锈"; -LL + let _bad8 = "锈\x0001锈"; - | +LL | let _bad8 = "锈\x0001锈"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:18:19 @@ -184,9 +170,8 @@ LL + let _bad9 = "锈\x09锈"; | help: if a null escape is intended, disambiguate using | -LL - let _bad9 = "锈\011锈"; -LL + let _bad9 = "锈\x0011锈"; - | +LL | let _bad9 = "锈\x0011锈"; + | ++ error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr index 74bbcfcca51e1..2c26565d5ef14 100644 --- a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr +++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr @@ -8,9 +8,8 @@ LL | let _ = cow.to_owned(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]` help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -25,9 +24,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -42,9 +40,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -59,9 +56,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr index 6ef333f0cfd29..84a574017a9b7 100644 --- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr @@ -12,7 +12,7 @@ LL | | /// 200 characters so I needed to write something longeeeeeeer. = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` help: add an empty line | -LL ~ /// A very short summary. +LL | /// A very short summary. LL + /// | diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr index 95f42349b9b35..8bc853132ec0b 100644 --- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr @@ -12,8 +12,8 @@ LL | | //! 200 characters so I needed to write something longeeeeeeer. = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` help: add an empty line | -LL ~ //! A very short summary. -LL + //! +LL | //! A very short summary. +LL ~ //! LL ~ //! A much longer explanation that goes into a lot more detail about | diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 1614c35cb1ce4..98ab7adf5a726 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -215,8 +215,10 @@ pub struct Config { /// `None` then these tests will be ignored. pub run_clang_based_tests_with: Option, - /// The directory containing the tests to run - pub src_base: PathBuf, + /// The directory containing the sources. + pub src_root: PathBuf, + /// The directory containing the test suite sources. Must be a subdirectory of `src_root`. + pub src_test_suite_root: PathBuf, /// The directory where programs should be built pub build_base: PathBuf, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 452a2e9a9d518..3bdf37a1f294a 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1026,19 +1026,6 @@ impl Config { } } - pub fn find_rust_src_root(&self) -> Option { - let mut path = self.src_base.clone(); - let path_postfix = Path::new("src/etc/lldb_batchmode.py"); - - while path.pop() { - if path.join(&path_postfix).is_file() { - return Some(path); - } - } - - None - } - fn parse_edition(&self, line: &str) -> Option { self.parse_name_value_directive(line, "edition") } @@ -1098,7 +1085,7 @@ fn expand_variables(mut value: String, config: &Config) -> String { } if value.contains(SRC_BASE) { - value = value.replace(SRC_BASE, &config.src_base.to_string_lossy()); + value = value.replace(SRC_BASE, &config.src_test_suite_root.to_str().unwrap()); } if value.contains(BUILD_BASE) { diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index c65f10a52bd5b..c9536b7a19b79 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -153,7 +153,8 @@ impl ConfigBuilder { "--run-lib-path=", "--python=", "--jsondocck-path=", - "--src-base=", + "--src-root=", + "--src-test-suite-root=", "--build-base=", "--sysroot-base=", "--cc=c", diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index d0a83cab9cd99..979821701385e 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -61,7 +61,8 @@ pub fn parse_config(args: Vec) -> Config { .optopt("", "jsondoclint-path", "path to jsondoclint to use for doc tests", "PATH") .optopt("", "run-clang-based-tests-with", "path to Clang executable", "PATH") .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR") - .reqopt("", "src-base", "directory to scan for test files", "PATH") + .reqopt("", "src-root", "directory containing sources", "PATH") + .reqopt("", "src-test-suite-root", "directory containing test suite sources", "PATH") .reqopt("", "build-base", "directory to deposit test outputs", "PATH") .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH") .reqopt("", "stage", "stage number under test", "N") @@ -243,7 +244,6 @@ pub fn parse_config(args: Vec) -> Config { || header::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?), ); - let src_base = opt_path(matches, "src-base"); let run_ignored = matches.opt_present("ignored"); let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions"); let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions"); @@ -300,6 +300,15 @@ pub fn parse_config(args: Vec) -> Config { None => panic!("`--stage` is required"), }; + let src_root = opt_path(matches, "src-root"); + let src_test_suite_root = opt_path(matches, "src-test-suite-root"); + assert!( + src_test_suite_root.starts_with(&src_root), + "`src-root` must be a parent of `src-test-suite-root`: `src-root`=`{}`, `src-test-suite-root` = `{}`", + src_root.display(), + src_test_suite_root.display() + ); + Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -314,7 +323,10 @@ pub fn parse_config(args: Vec) -> Config { run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"), llvm_filecheck: matches.opt_str("llvm-filecheck").map(PathBuf::from), llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from), - src_base, + + src_root, + src_test_suite_root, + build_base: opt_path(matches, "build-base"), sysroot_base: opt_path(matches, "sysroot-base"), @@ -422,7 +434,10 @@ pub fn log_config(config: &Config) { logv(c, format!("rustc_path: {:?}", config.rustc_path.display())); logv(c, format!("cargo_path: {:?}", config.cargo_path)); logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path)); - logv(c, format!("src_base: {:?}", config.src_base.display())); + + logv(c, format!("src_root: {}", config.src_root.display())); + logv(c, format!("src_test_suite_root: {}", config.src_test_suite_root.display())); + logv(c, format!("build_base: {:?}", config.build_base.display())); logv(c, format!("stage: {}", config.stage)); logv(c, format!("stage_id: {}", config.stage_id)); @@ -620,20 +635,29 @@ struct TestCollector { /// regardless of whether any filters/tests were specified on the command-line, /// because filtering is handled later by libtest. pub fn collect_and_make_tests(config: Arc) -> Vec { - debug!("making tests from {:?}", config.src_base.display()); + debug!("making tests from {}", config.src_test_suite_root.display()); let common_inputs_stamp = common_inputs_stamp(&config); - let modified_tests = modified_tests(&config, &config.src_base).unwrap_or_else(|err| { - panic!("modified_tests got error from dir: {}, error: {}", config.src_base.display(), err) - }); + let modified_tests = + modified_tests(&config, &config.src_test_suite_root).unwrap_or_else(|err| { + panic!( + "modified_tests got error from dir: {}, error: {}", + config.src_test_suite_root.display(), + err + ) + }); let cache = HeadersCache::load(&config); let cx = TestCollectorCx { config, cache, common_inputs_stamp, modified_tests }; let mut collector = TestCollector { tests: vec![], found_path_stems: HashSet::new(), poisoned: false }; - collect_tests_from_dir(&cx, &mut collector, &cx.config.src_base, Path::new("")).unwrap_or_else( - |reason| panic!("Could not read tests from {}: {reason}", cx.config.src_base.display()), - ); + collect_tests_from_dir(&cx, &mut collector, &cx.config.src_test_suite_root, Path::new("")) + .unwrap_or_else(|reason| { + panic!( + "Could not read tests from {}: {reason}", + cx.config.src_test_suite_root.display() + ) + }); let TestCollector { tests, found_path_stems, poisoned } = collector; @@ -655,7 +679,7 @@ pub fn collect_and_make_tests(config: Arc) -> Vec { /// common to some subset of tests, and are hopefully unlikely to be modified /// while working on other tests.) fn common_inputs_stamp(config: &Config) -> Stamp { - let rust_src_dir = config.find_rust_src_root().expect("Could not find Rust source root"); + let src_root = &config.src_root; let mut stamp = Stamp::from_path(&config.rustc_path); @@ -670,17 +694,17 @@ fn common_inputs_stamp(config: &Config) -> Stamp { "src/etc/lldb_providers.py", ]; for file in &pretty_printer_files { - let path = rust_src_dir.join(file); + let path = src_root.join(file); stamp.add_path(&path); } - stamp.add_dir(&rust_src_dir.join("src/etc/natvis")); + stamp.add_dir(&src_root.join("src/etc/natvis")); stamp.add_dir(&config.run_lib_path); if let Some(ref rustdoc_path) = config.rustdoc_path { stamp.add_path(&rustdoc_path); - stamp.add_path(&rust_src_dir.join("src/etc/htmldocck.py")); + stamp.add_path(&src_root.join("src/etc/htmldocck.py")); } // Re-run coverage tests if the `coverage-dump` tool was modified, @@ -689,10 +713,10 @@ fn common_inputs_stamp(config: &Config) -> Stamp { stamp.add_path(coverage_dump_path) } - stamp.add_dir(&rust_src_dir.join("src/tools/run-make-support")); + stamp.add_dir(&src_root.join("src/tools/run-make-support")); // Compiletest itself. - stamp.add_dir(&rust_src_dir.join("src/tools/compiletest/")); + stamp.add_dir(&src_root.join("src/tools/compiletest")); stamp } @@ -933,10 +957,7 @@ fn files_related_to_test( } // `minicore.rs` test auxiliary: we need to make sure tests get rerun if this changes. - // - // FIXME(jieyouxu): untangle these paths, we should provide both a path to root `tests/` or - // `tests/auxiliary/` and the test suite in question. `src_base` is also a terrible name. - related.push(config.src_base.parent().unwrap().join("auxiliary").join("minicore.rs")); + related.push(config.src_root.join("tests").join("auxiliary").join("minicore.rs")); related } @@ -1026,10 +1047,8 @@ fn make_test_name( testpaths: &TestPaths, revision: Option<&str>, ) -> test::TestName { - // Print the name of the file, relative to the repository root. - // `src_base` looks like `/path/to/rust/tests/ui` - let root_directory = config.src_base.parent().unwrap().parent().unwrap(); - let path = testpaths.file.strip_prefix(root_directory).unwrap(); + // Print the name of the file, relative to the sources root. + let path = testpaths.file.strip_prefix(&config.src_root).unwrap(); let debugger = match config.debugger { Some(d) => format!("-{}", d), None => String::new(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 0e2da2b02ca0f..536e19bc4933e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1365,7 +1365,7 @@ impl<'test> TestCx<'test> { // // Note: avoid adding a subdirectory of an already filtered directory here, otherwise the // same slice of text will be double counted and the truncation might not happen. - add_path(&self.config.src_base); + add_path(&self.config.src_test_suite_root); add_path(&self.config.build_base); read2_abbreviated(child, &filter_paths_from_len).expect("failed to read output") @@ -1471,7 +1471,7 @@ impl<'test> TestCx<'test> { // Similarly, vendored sources shouldn't be shown when running from a dist tarball. rustc.arg("-Z").arg(format!( "ignore-directory-in-diagnostics-source-blocks={}", - self.config.find_rust_src_root().unwrap().join("vendor").display(), + self.config.src_root.join("vendor").to_str().unwrap(), )); // Optionally prevent default --sysroot if specified in test compile-flags. @@ -1632,7 +1632,7 @@ impl<'test> TestCx<'test> { if self.props.remap_src_base { rustc.arg(format!( "--remap-path-prefix={}={}", - self.config.src_base.display(), + self.config.src_test_suite_root.to_str().unwrap(), FAKE_SRC_BASE, )); } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index b236b06756903..170b8a8099687 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -257,11 +257,8 @@ impl TestCx<'_> { println!("Adb process is already finished."); } } else { - let rust_src_root = - self.config.find_rust_src_root().expect("Could not find Rust source root"); - let rust_pp_module_rel_path = Path::new("./src/etc"); - let rust_pp_module_abs_path = - rust_src_root.join(rust_pp_module_rel_path).to_str().unwrap().to_owned(); + let rust_pp_module_abs_path = self.config.src_root.join("src").join("etc"); + let rust_pp_module_abs_path = rust_pp_module_abs_path.to_str().unwrap(); // write debugger script let mut script_str = String::with_capacity(2048); script_str.push_str(&format!("set charset {}\n", Self::charset())); @@ -338,7 +335,7 @@ impl TestCx<'_> { let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") { format!("{pp}:{rust_pp_module_abs_path}") } else { - rust_pp_module_abs_path + rust_pp_module_abs_path.to_string() }; gdb.args(debugger_opts).env("PYTHONPATH", pythonpath); @@ -407,11 +404,8 @@ impl TestCx<'_> { // Make LLDB emit its version, so we have it documented in the test output script_str.push_str("version\n"); - // Switch LLDB into "Rust mode" - let rust_src_root = - self.config.find_rust_src_root().expect("Could not find Rust source root"); - let rust_pp_module_rel_path = Path::new("./src/etc"); - let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path); + // Switch LLDB into "Rust mode". + let rust_pp_module_abs_path = self.config.src_root.join("src/etc"); script_str.push_str(&format!( "command script import {}/lldb_lookup.py\n", @@ -445,7 +439,7 @@ impl TestCx<'_> { let debugger_script = self.make_out_name("debugger.script"); // Let LLDB execute the script via lldb_batchmode.py - let debugger_run_result = self.run_lldb(&exe_file, &debugger_script, &rust_src_root); + let debugger_run_result = self.run_lldb(&exe_file, &debugger_script); if !debugger_run_result.status.success() { self.fatal_proc_rec("Error while running LLDB", &debugger_run_result); @@ -456,18 +450,13 @@ impl TestCx<'_> { } } - fn run_lldb( - &self, - test_executable: &Path, - debugger_script: &Path, - rust_src_root: &Path, - ) -> ProcRes { + fn run_lldb(&self, test_executable: &Path, debugger_script: &Path) -> ProcRes { // Prepare the lldb_batchmode which executes the debugger script - let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py"); + let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py"); let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") { format!("{pp}:{}", self.config.lldb_python_dir.as_ref().unwrap()) } else { - self.config.lldb_python_dir.as_ref().unwrap().to_string() + self.config.lldb_python_dir.clone().unwrap() }; self.run_command_to_procres( Command::new(&self.config.python) diff --git a/src/tools/compiletest/src/runtest/js_doc.rs b/src/tools/compiletest/src/runtest/js_doc.rs index a83bcd70c8718..d630affbec104 100644 --- a/src/tools/compiletest/src/runtest/js_doc.rs +++ b/src/tools/compiletest/src/runtest/js_doc.rs @@ -9,12 +9,11 @@ impl TestCx<'_> { self.document(&out_dir, &self.testpaths); - let root = self.config.find_rust_src_root().unwrap(); let file_stem = self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem"); let res = self.run_command_to_procres( Command::new(&nodejs) - .arg(root.join("src/tools/rustdoc-js/tester.js")) + .arg(self.config.src_root.join("src/tools/rustdoc-js/tester.js")) .arg("--doc-folder") .arg(out_dir) .arg("--crate-name") diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 16c46fc13390f..74e6af36ea1dd 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -21,8 +21,6 @@ impl TestCx<'_> { fn run_rmake_legacy_test(&self) { let cwd = env::current_dir().unwrap(); - let src_root = self.config.src_base.parent().unwrap().parent().unwrap(); - let src_root = cwd.join(&src_root); // FIXME(Zalathar): This should probably be `output_base_dir` to avoid // an unnecessary extra subdirectory, but since legacy Makefile tests @@ -51,7 +49,7 @@ impl TestCx<'_> { .stderr(Stdio::piped()) .env("TARGET", &self.config.target) .env("PYTHON", &self.config.python) - .env("S", src_root) + .env("S", &self.config.src_root) .env("RUST_BUILD_STAGE", &self.config.stage_id) .env("RUSTC", cwd.join(&self.config.rustc_path)) .env("TMPDIR", &tmpdir) @@ -181,28 +179,10 @@ impl TestCx<'_> { // library. // 2. We need to run the recipe binary. - // So we assume the rust-lang/rust project setup looks like the following (our `.` is the - // top-level directory, irrelevant entries to our purposes omitted): - // - // ``` - // . // <- `source_root` - // ├── build/ // <- `build_root` - // ├── compiler/ - // ├── library/ - // ├── src/ - // │ └── tools/ - // │ └── run_make_support/ - // └── tests - // └── run-make/ - // ``` - - // `source_root` is the top-level directory containing the rust-lang/rust checkout. - let source_root = - self.config.find_rust_src_root().expect("could not determine rust source root"); // `self.config.build_base` is actually the build base folder + "test" + test suite name, it // looks like `build//test/run-make`. But we want `build//`. Note // that the `build` directory does not need to be called `build`, nor does it need to be - // under `source_root`, so we must compute it based off of `self.config.build_base`. + // under `src_root`, so we must compute it based off of `self.config.build_base`. let build_root = self.config.build_base.parent().and_then(Path::parent).unwrap().to_path_buf(); @@ -389,10 +369,9 @@ impl TestCx<'_> { .env("TARGET", &self.config.target) // Some tests unfortunately still need Python, so provide path to a Python interpreter. .env("PYTHON", &self.config.python) - // Provide path to checkout root. This is the top-level directory containing - // rust-lang/rust checkout. - .env("SOURCE_ROOT", &source_root) - // Path to the build directory. This is usually the same as `source_root.join("build").join("host")`. + // Provide path to sources root. + .env("SOURCE_ROOT", &self.config.src_root) + // Path to the host build directory. .env("BUILD_ROOT", &build_root) // Provide path to stage-corresponding rustc. .env("RUSTC", &self.config.rustc_path) @@ -408,11 +387,11 @@ impl TestCx<'_> { .env("LLVM_COMPONENTS", &self.config.llvm_components); if let Some(ref cargo) = self.config.cargo_path { - cmd.env("CARGO", source_root.join(cargo)); + cmd.env("CARGO", cargo); } if let Some(ref rustdoc) = self.config.rustdoc_path { - cmd.env("RUSTDOC", source_root.join(rustdoc)); + cmd.env("RUSTDOC", rustdoc); } if let Some(ref node) = self.config.nodejs { diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 3f33862d2cfe2..2583ae96a6788 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -17,9 +17,10 @@ impl TestCx<'_> { if self.props.check_test_line_numbers_match { self.check_rustdoc_test_option(proc_res); } else { - let root = self.config.find_rust_src_root().unwrap(); let mut cmd = Command::new(&self.config.python); - cmd.arg(root.join("src/etc/htmldocck.py")).arg(&out_dir).arg(&self.testpaths.file); + cmd.arg(self.config.src_root.join("src/etc/htmldocck.py")) + .arg(&out_dir) + .arg(&self.testpaths.file); if self.config.bless { cmd.arg("--bless"); } diff --git a/tests/crashes/111709-2.rs b/tests/crashes/111709-2.rs deleted file mode 100644 index 6c4fb9f28c7de..0000000000000 --- a/tests/crashes/111709-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #111709 -//@ edition: 2021 - -use core::arch::asm; - -extern "C" fn test() {} - -fn uwu() { - unsafe { - asm!( - "/* {0} */", - sym test::<&mut ()> - ); - } -} diff --git a/tests/crashes/111709.rs b/tests/crashes/111709.rs deleted file mode 100644 index eef375b8924b7..0000000000000 --- a/tests/crashes/111709.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ known-bug: #111709 -//@ edition:2021 - -use core::arch::asm; - -struct TrapFrame; - -unsafe extern "C" fn _rust_abi_shim1(arg: A, f: fn(A) -> R) -> R { - f(arg) -} - -unsafe extern "C" fn _start_trap() { - extern "Rust" { - fn interrupt(tf: &mut TrapFrame); - } - asm!( - " - la a1, {irq} - call {shim} - ", - shim = sym crate::_rust_abi_shim1::<&mut TrapFrame, ()>, - irq = sym interrupt, - options(noreturn) - ) -} diff --git a/tests/crashes/125957.rs b/tests/crashes/125957.rs deleted file mode 100644 index e3abe5262eb90..0000000000000 --- a/tests/crashes/125957.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: rust-lang/rust#125957 -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] -#![feature(associated_const_equality)] - -pub struct Equal(); - -pub enum ParseMode { - Raw, -} -pub trait Parse { - const PARSE_MODE: ParseMode; -} -pub trait RenderRaw: Parse {} - -trait GenericVec { - fn unwrap() -> dyn RenderRaw; -} - -fn main() {} diff --git a/tests/crashes/132330.rs b/tests/crashes/132330.rs deleted file mode 100644 index 3432685749d9d..0000000000000 --- a/tests/crashes/132330.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ known-bug: #132330 -//@compile-flags: -Znext-solver=globally - -trait Service { - type S; -} - -trait Framing { - type F; -} - -impl Framing for () { - type F = (); -} - -trait HttpService: Service {} - -type BoxService = Box>; - -fn build_server BoxService>(_: F) {} - -fn make_server() -> Box> { - unimplemented!() -} - -fn main() { - build_server(|| make_server()) -} diff --git a/tests/crashes/96304.rs b/tests/crashes/96304.rs deleted file mode 100644 index 637012f45858f..0000000000000 --- a/tests/crashes/96304.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #96304 - -#![feature(asm_sym)] -core::arch::global_asm!("/* {} */", sym<&'static ()>::clone); - -pub fn main() {} diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr index 9a639d4b5e4ef..a71b6ab0e9949 100644 --- a/tests/ui/argument-suggestions/basic.stderr +++ b/tests/ui/argument-suggestions/basic.stderr @@ -42,9 +42,8 @@ LL | fn missing(_i: u32) {} | ^^^^^^^ ------- help: provide the argument | -LL - missing(); -LL + missing(/* u32 */); - | +LL | missing(/* u32 */); + | +++++++++ error[E0308]: arguments to this function are incorrect --> $DIR/basic.rs:23:5 @@ -98,9 +97,8 @@ LL | let closure = |x| x; | ^^^ help: provide the argument | -LL - closure(); -LL + closure(/* x */); - | +LL | closure(/* x */); + | +++++++ error: aborting due to 6 previous errors diff --git a/tests/ui/argument-suggestions/display-is-suggestable.stderr b/tests/ui/argument-suggestions/display-is-suggestable.stderr index bb5df1ec234cd..921cc12333870 100644 --- a/tests/ui/argument-suggestions/display-is-suggestable.stderr +++ b/tests/ui/argument-suggestions/display-is-suggestable.stderr @@ -11,9 +11,8 @@ LL | fn foo(x: &(dyn Display + Send)) {} | ^^^ ------------------------ help: provide the argument | -LL - foo(); -LL + foo(/* &dyn std::fmt::Display + Send */); - | +LL | foo(/* &dyn std::fmt::Display + Send */); + | +++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr index 62670316cd163..28500908e7ea3 100644 --- a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr +++ b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr @@ -17,9 +17,8 @@ LL | fn dstfn(src: i32, dst: err); | ^^^^^ --- help: provide the argument | -LL - dstfn(1); -LL + dstfn(1, /* dst */); - | +LL | dstfn(1, /* dst */); + | +++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/argument-suggestions/issue-97197.stderr b/tests/ui/argument-suggestions/issue-97197.stderr index acaf4f1510735..ae56e12c975f8 100644 --- a/tests/ui/argument-suggestions/issue-97197.stderr +++ b/tests/ui/argument-suggestions/issue-97197.stderr @@ -11,9 +11,8 @@ LL | pub fn g(a1: (), a2: bool, a3: bool, a4: bool, a5: bool, a6: ()) -> () {} | ^ -------- -------- -------- -------- help: provide the arguments | -LL - g((), ()); -LL + g((), /* bool */, /* bool */, /* bool */, /* bool */, ()); - | +LL | g((), /* bool */, /* bool */, /* bool */, /* bool */, ()); + | +++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/issue-98894.stderr b/tests/ui/argument-suggestions/issue-98894.stderr index 44353cb33388a..141355ff153bd 100644 --- a/tests/ui/argument-suggestions/issue-98894.stderr +++ b/tests/ui/argument-suggestions/issue-98894.stderr @@ -11,9 +11,8 @@ LL | (|_, ()| ())(if true {} else {return;}); | ^^^^^^^ help: provide the argument | -LL - (|_, ()| ())(if true {} else {return;}); -LL + (|_, ()| ())(if true {} else {return;}, ()); - | +LL | (|_, ()| ())(if true {} else {return;}, ()); + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/issue-98897.stderr b/tests/ui/argument-suggestions/issue-98897.stderr index fd3ef467b1c39..a85e723368902 100644 --- a/tests/ui/argument-suggestions/issue-98897.stderr +++ b/tests/ui/argument-suggestions/issue-98897.stderr @@ -11,9 +11,8 @@ LL | (|_, ()| ())([return, ()]); | ^^^^^^^ help: provide the argument | -LL - (|_, ()| ())([return, ()]); -LL + (|_, ()| ())([return, ()], ()); - | +LL | (|_, ()| ())([return, ()], ()); + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/issue-99482.stderr b/tests/ui/argument-suggestions/issue-99482.stderr index b3c39604a99b0..972ab401958b0 100644 --- a/tests/ui/argument-suggestions/issue-99482.stderr +++ b/tests/ui/argument-suggestions/issue-99482.stderr @@ -11,9 +11,8 @@ LL | let f = |_: (), f: fn()| f; | ^^^^^^^^^^^^^^^^ help: provide the argument | -LL - let _f = f(main); -LL + let _f = f((), main); - | +LL | let _f = f((), main); + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/missing_arguments.stderr b/tests/ui/argument-suggestions/missing_arguments.stderr index 264c485cbe1c3..9dc13c41113b6 100644 --- a/tests/ui/argument-suggestions/missing_arguments.stderr +++ b/tests/ui/argument-suggestions/missing_arguments.stderr @@ -11,9 +11,8 @@ LL | fn one_arg(_a: i32) {} | ^^^^^^^ ------- help: provide the argument | -LL - one_arg(); -LL + one_arg(/* i32 */); - | +LL | one_arg(/* i32 */); + | +++++++++ error[E0061]: this function takes 2 arguments but 0 arguments were supplied --> $DIR/missing_arguments.rs:14:3 diff --git a/tests/ui/asm/asm-with-nested-closure.rs b/tests/ui/asm/asm-with-nested-closure.rs new file mode 100644 index 0000000000000..d8374627dc573 --- /dev/null +++ b/tests/ui/asm/asm-with-nested-closure.rs @@ -0,0 +1,10 @@ +//@ build-pass + +fn foo() {} + +core::arch::global_asm!("/* {} */", sym foo::<{ + || {}; + 0 +}>); + +fn main() {} diff --git a/tests/ui/asm/global-asm-with-lifetimes.rs b/tests/ui/asm/global-asm-with-lifetimes.rs new file mode 100644 index 0000000000000..8ff0d263fdb1f --- /dev/null +++ b/tests/ui/asm/global-asm-with-lifetimes.rs @@ -0,0 +1,7 @@ +//@ build-pass + +fn foo() {} + +core::arch::global_asm!("/* {} */", sym foo::<&'static ()>); + +fn main() {} diff --git a/tests/ui/asm/inline-asm-with-lifetimes.bad.stderr b/tests/ui/asm/inline-asm-with-lifetimes.bad.stderr new file mode 100644 index 0000000000000..cd3aa8e619046 --- /dev/null +++ b/tests/ui/asm/inline-asm-with-lifetimes.bad.stderr @@ -0,0 +1,17 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/inline-asm-with-lifetimes.rs:16:26 + | +LL | fn test<'a: 'a, T>() { + | -- the parameter type `T` must be valid for the lifetime `'a` as defined here... +LL | unsafe { +LL | asm!("/* {} */", sym dep::<'a, T> ); + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | fn test<'a: 'a, T: 'a>() { + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/asm/inline-asm-with-lifetimes.rs b/tests/ui/asm/inline-asm-with-lifetimes.rs new file mode 100644 index 0000000000000..79c40214f53cf --- /dev/null +++ b/tests/ui/asm/inline-asm-with-lifetimes.rs @@ -0,0 +1,21 @@ +//@ revisions: good bad +//@[good] build-pass + +use std::arch::asm; + +// lifetime requirement, we should check it!! +#[cfg(bad)] +fn dep<'a, T: 'a>() {} + +// no lifetime requirement +#[cfg(good)] +fn dep<'a: 'a, T>() {} + +fn test<'a: 'a, T>() { + unsafe { + asm!("/* {} */", sym dep::<'a, T> ); + //[bad]~^ ERROR the parameter type `T` may not live long enough + } +} + +fn main() {} diff --git a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr index e68ba503c5059..041c9b485f0a3 100644 --- a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr +++ b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr @@ -16,12 +16,10 @@ LL | const ID: i32 = 1; | ^^^^^^^^^^^^^ help: use fully-qualified syntax to disambiguate | -LL - const X: i32 = ::ID; -LL + const X: i32 = ::ID; - | -LL - const X: i32 = ::ID; -LL + const X: i32 = ::ID; - | +LL | const X: i32 = ::ID; + | ++++++ +LL | const X: i32 = ::ID; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/associated-consts/issue-93775.rs b/tests/ui/associated-consts/issue-93775.rs index 88e88b559870f..a9b8d10a83fbf 100644 --- a/tests/ui/associated-consts/issue-93775.rs +++ b/tests/ui/associated-consts/issue-93775.rs @@ -2,11 +2,13 @@ // Similar to stress testing, the test case requires a larger call stack, // so we ignore rustc's debug assertions. -//@ build-pass -// ignore-tidy-linelength - // Regression for #93775, needs build-pass to test it. +//@ build-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![recursion_limit = "1001"] use std::marker::PhantomData; @@ -14,7 +16,64 @@ use std::marker::PhantomData; struct Z; struct S(PhantomData); -type Nested = S>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; +type Nested = S>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; trait AsNum { const NUM: u32; diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr index 18455f4669e91..59f8526a73e59 100644 --- a/tests/ui/associated-inherent-types/issue-109768.stderr +++ b/tests/ui/associated-inherent-types/issue-109768.stderr @@ -43,9 +43,8 @@ LL | struct Wrapper(T); | ^^^^^^^ help: provide the argument | -LL - const WRAPPED_ASSOC_3: Wrapper = Wrapper(); -LL + const WRAPPED_ASSOC_3: Wrapper = Wrapper(/* value */); - | +LL | const WRAPPED_ASSOC_3: Wrapper = Wrapper(/* value */); + | +++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/associated-item/associated-item-enum.stderr b/tests/ui/associated-item/associated-item-enum.stderr index 49f168b854407..c3ce7c34d0569 100644 --- a/tests/ui/associated-item/associated-item-enum.stderr +++ b/tests/ui/associated-item/associated-item-enum.stderr @@ -9,9 +9,8 @@ LL | Enum::mispellable(); | help: there is an associated function `misspellable` with a similar name | -LL - Enum::mispellable(); -LL + Enum::misspellable(); - | +LL | Enum::misspellable(); + | + error[E0599]: no variant or associated item named `mispellable_trait` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:18:11 @@ -24,9 +23,8 @@ LL | Enum::mispellable_trait(); | help: there is an associated function `misspellable_trait` with a similar name | -LL - Enum::mispellable_trait(); -LL + Enum::misspellable_trait(); - | +LL | Enum::misspellable_trait(); + | + error[E0599]: no variant or associated item named `MISPELLABLE` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:19:11 @@ -39,9 +37,8 @@ LL | Enum::MISPELLABLE; | help: there is an associated constant `MISSPELLABLE` with a similar name | -LL - Enum::MISPELLABLE; -LL + Enum::MISSPELLABLE; - | +LL | Enum::MISSPELLABLE; + | + error: aborting due to 3 previous errors diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.rs b/tests/ui/associated-types/associated-types-overridden-binding-2.rs index fed60ccf089d0..247724eaaf112 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.rs +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.rs @@ -4,5 +4,5 @@ trait I32Iterator = Iterator; fn main() { let _: &dyn I32Iterator = &vec![42].into_iter(); - //~^ ERROR expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` + //~^ ERROR conflicting associated type bounds } diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr index 4dfd275a19058..71a4a2610aac4 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -1,11 +1,13 @@ -error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/associated-types-overridden-binding-2.rs:6:43 +error: conflicting associated type bounds for `Item` when expanding trait alias + --> $DIR/associated-types-overridden-binding-2.rs:6:13 | +LL | trait I32Iterator = Iterator; + | ---------- `Item` is specified to be `i32` here +... LL | let _: &dyn I32Iterator = &vec![42].into_iter(); - | ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` - | - = note: required for the cast from `&std::vec::IntoIter` to `&dyn Iterator` + | ^^^^^^^^^^^^^^^^----------^ + | | + | `Item` is specified to be `u32` here error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/associated-types-overridden-binding.rs b/tests/ui/associated-types/associated-types-overridden-binding.rs index 9a64a06c31bad..333a3e30c7dcf 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.rs +++ b/tests/ui/associated-types/associated-types-overridden-binding.rs @@ -8,4 +8,5 @@ trait U32Iterator = I32Iterator; //~ ERROR type annotations needed fn main() { let _: &dyn I32Iterator; + //~^ ERROR conflicting associated type bounds } diff --git a/tests/ui/associated-types/associated-types-overridden-binding.stderr b/tests/ui/associated-types/associated-types-overridden-binding.stderr index dc087e4185fb6..3b20015dfcab3 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding.stderr @@ -22,6 +22,17 @@ note: required by a bound in `I32Iterator` LL | trait I32Iterator = Iterator; | ^^^^^^^^^^ required by this bound in `I32Iterator` -error: aborting due to 2 previous errors +error: conflicting associated type bounds for `Item` when expanding trait alias + --> $DIR/associated-types-overridden-binding.rs:10:13 + | +LL | trait I32Iterator = Iterator; + | ---------- `Item` is specified to be `i32` here +... +LL | let _: &dyn I32Iterator; + | ^^^^^^^^^^^^^^^^----------^ + | | + | `Item` is specified to be `u32` here + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/binop/placement-syntax.stderr b/tests/ui/binop/placement-syntax.stderr index e398c0b0702ab..c07ee7184c775 100644 --- a/tests/ui/binop/placement-syntax.stderr +++ b/tests/ui/binop/placement-syntax.stderr @@ -6,9 +6,8 @@ LL | if x<-1 { | help: if you meant to write a comparison against a negative value, add a space in between `<` and `-` | -LL - if x<-1 { -LL + if x< -1 { - | +LL | if x< -1 { + | + error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr b/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr index d953ed2ad3ef0..5cc5b87cd44b7 100644 --- a/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr +++ b/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr @@ -116,9 +116,8 @@ LL | let _s2 = T { ..s0 }; | help: clone the value from the field instead of using the functional record update syntax | -LL - let _s2 = T { ..s0 }; -LL + let _s2 = T { b: s0.b.clone(), ..s0 }; - | +LL | let _s2 = T { b: s0.b.clone(), ..s0 }; + | ++++++++++++++++ error[E0509]: cannot move out of type `T`, which implements the `Drop` trait --> $DIR/borrowck-struct-update-with-dtor.rs:47:32 diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr index 1e3570fc85570..a392177ffe2f3 100644 --- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr +++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr @@ -9,9 +9,8 @@ LL | let sfoo: *mut Foo = &mut SFOO; = note: `#[warn(static_mut_refs)]` on by default help: use `&raw mut` instead to create a raw pointer | -LL - let sfoo: *mut Foo = &mut SFOO; -LL + let sfoo: *mut Foo = &raw mut SFOO; - | +LL | let sfoo: *mut Foo = &raw mut SFOO; + | +++ warning: 1 warning emitted diff --git a/tests/ui/borrowck/issue-85765-closure.stderr b/tests/ui/borrowck/issue-85765-closure.stderr index fa4e544150877..cd2544ec5c952 100644 --- a/tests/ui/borrowck/issue-85765-closure.stderr +++ b/tests/ui/borrowck/issue-85765-closure.stderr @@ -6,9 +6,8 @@ LL | rofl.push(Vec::new()); | help: consider changing this binding's type | -LL - let rofl: &Vec> = &mut test; -LL + let rofl: &mut Vec> = &mut test; - | +LL | let rofl: &mut Vec> = &mut test; + | +++ error[E0594]: cannot assign to `*r`, which is behind a `&` reference --> $DIR/issue-85765-closure.rs:13:9 @@ -29,9 +28,8 @@ LL | *x = 1; | help: consider changing this binding's type | -LL - let x: &usize = &mut{0}; -LL + let x: &mut usize = &mut{0}; - | +LL | let x: &mut usize = &mut{0}; + | +++ error[E0594]: cannot assign to `*y`, which is behind a `&` reference --> $DIR/issue-85765-closure.rs:27:9 @@ -41,9 +39,8 @@ LL | *y = 1; | help: consider changing this binding's type | -LL - let y: &usize = &mut(0); -LL + let y: &mut usize = &mut(0); - | +LL | let y: &mut usize = &mut(0); + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/borrowck/issue-85765.stderr b/tests/ui/borrowck/issue-85765.stderr index 9354294f52b21..e252f3d44d976 100644 --- a/tests/ui/borrowck/issue-85765.stderr +++ b/tests/ui/borrowck/issue-85765.stderr @@ -6,9 +6,8 @@ LL | rofl.push(Vec::new()); | help: consider changing this binding's type | -LL - let rofl: &Vec> = &mut test; -LL + let rofl: &mut Vec> = &mut test; - | +LL | let rofl: &mut Vec> = &mut test; + | +++ error[E0594]: cannot assign to `*r`, which is behind a `&` reference --> $DIR/issue-85765.rs:12:5 @@ -29,9 +28,8 @@ LL | *x = 1; | help: consider changing this binding's type | -LL - let x: &usize = &mut{0}; -LL + let x: &mut usize = &mut{0}; - | +LL | let x: &mut usize = &mut{0}; + | +++ error[E0594]: cannot assign to `*y`, which is behind a `&` reference --> $DIR/issue-85765.rs:26:5 @@ -41,9 +39,8 @@ LL | *y = 1; | help: consider changing this binding's type | -LL - let y: &usize = &mut(0); -LL + let y: &mut usize = &mut(0); - | +LL | let y: &mut usize = &mut(0); + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index 061eae9729e2e..39dfb2548a3bb 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -17,9 +17,8 @@ LL | fn foo(f: isize, x: u8, ...); | ^^^ - - help: provide the arguments | -LL - foo(); -LL + foo(/* isize */, /* u8 */); - | +LL | foo(/* isize */, /* u8 */); + | +++++++++++++++++++++ error[E0060]: this function takes at least 2 arguments but 1 argument was supplied --> $DIR/variadic-ffi-1.rs:23:9 @@ -34,9 +33,8 @@ LL | fn foo(f: isize, x: u8, ...); | ^^^ - help: provide the argument | -LL - foo(1); -LL + foo(1, /* u8 */); - | +LL | foo(1, /* u8 */); + | ++++++++++ error[E0308]: mismatched types --> $DIR/variadic-ffi-1.rs:25:56 diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr index 402ee27386ddd..0b2ab1dfc4c17 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.stderr +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -48,9 +48,8 @@ LL | struct MyType<'a>(Cell>>, Pin); | ^^^^^^ help: provide the argument | -LL - let mut unpinned = MyType(Cell::new(None)); -LL + let mut unpinned = MyType(Cell::new(None), /* value */); - | +LL | let mut unpinned = MyType(Cell::new(None), /* value */); + | +++++++++++++ error[E0606]: casting `&MyType<'_>` as `*const Cell>>` is invalid --> $DIR/ice-cast-type-with-error-124848.rs:14:20 diff --git a/tests/ui/closures/deduce-from-object-supertrait.rs b/tests/ui/closures/deduce-from-object-supertrait.rs new file mode 100644 index 0000000000000..aff750dc62ea3 --- /dev/null +++ b/tests/ui/closures/deduce-from-object-supertrait.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// This test checks that we look at consider the super traits of trait objects +// when deducing closure signatures. + +trait Foo: Fn(Bar) {} +impl Foo for T where T: Fn(Bar) {} + +struct Bar; +impl Bar { + fn bar(&self) {} +} + +fn main() { + let x: &dyn Foo = &|x| { + x.bar(); + }; +} diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.stderr b/tests/ui/conditional-compilation/cfg-attr-parse.stderr index 1605761e59195..76f199caace37 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-parse.stderr @@ -7,9 +7,8 @@ LL | #[cfg_attr()] = note: for more information, visit help: missing condition and attribute | -LL - #[cfg_attr()] -LL + #[cfg_attr(condition, attribute, other_attribute, ...)] - | +LL | #[cfg_attr(condition, attribute, other_attribute, ...)] + | ++++++++++++++++++++++++++++++++++++++++++ error: expected `,`, found end of `cfg_attr` input --> $DIR/cfg-attr-parse.rs:8:17 diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr index be0ffefc80dee..0d76f142d174d 100644 --- a/tests/ui/consts/const_let_assign2.stderr +++ b/tests/ui/consts/const_let_assign2.stderr @@ -9,9 +9,8 @@ LL | let ptr = unsafe { &mut BB }; = note: `#[warn(static_mut_refs)]` on by default help: use `&raw mut` instead to create a raw pointer | -LL - let ptr = unsafe { &mut BB }; -LL + let ptr = unsafe { &raw mut BB }; - | +LL | let ptr = unsafe { &raw mut BB }; + | +++ warning: 1 warning emitted diff --git a/tests/ui/coroutine/issue-102645.stderr b/tests/ui/coroutine/issue-102645.stderr index bec0518d8c602..be16674668ead 100644 --- a/tests/ui/coroutine/issue-102645.stderr +++ b/tests/ui/coroutine/issue-102645.stderr @@ -8,9 +8,8 @@ note: method defined here --> $SRC_DIR/core/src/ops/coroutine.rs:LL:COL help: provide the argument | -LL - Pin::new(&mut b).resume(); -LL + Pin::new(&mut b).resume(()); - | +LL | Pin::new(&mut b).resume(()); + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/resume-arg-outlives.stderr b/tests/ui/coroutine/resume-arg-outlives.stderr index 0150009c8fa23..045c77e8d054c 100644 --- a/tests/ui/coroutine/resume-arg-outlives.stderr +++ b/tests/ui/coroutine/resume-arg-outlives.stderr @@ -9,9 +9,8 @@ LL | generator | help: consider changing `impl Coroutine<&'not_static str> + 'static`'s explicit `'static` bound to the lifetime of argument `s` | -LL - fn demo<'not_static>(s: &'not_static str) -> Pin + 'static>> { -LL + fn demo<'not_static>(s: &'not_static str) -> Pin + 'not_static>> { - | +LL | fn demo<'not_static>(s: &'not_static str) -> Pin + 'not_static>> { + | ++++ help: alternatively, add an explicit `'static` bound to this reference | LL - fn demo<'not_static>(s: &'not_static str) -> Pin + 'static>> { diff --git a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr b/tests/ui/coverage-attr/bad-attr-ice.feat.stderr index a8a70e363b7e6..dc84394fe3c0c 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr +++ b/tests/ui/coverage-attr/bad-attr-ice.feat.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr b/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr index 6443fafef3e41..49b8974bfdfb8 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr +++ b/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error[E0658]: the `#[coverage]` attribute is an experimental feature --> $DIR/bad-attr-ice.rs:11:1 diff --git a/tests/ui/coverage-attr/bad-syntax.stderr b/tests/ui/coverage-attr/bad-syntax.stderr index 3123066e7bf97..fa500b542097d 100644 --- a/tests/ui/coverage-attr/bad-syntax.stderr +++ b/tests/ui/coverage-attr/bad-syntax.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:20:1 @@ -36,12 +34,10 @@ LL | #[coverage()] | help: the following are the possible correct uses | -LL - #[coverage()] -LL + #[coverage(off)] - | -LL - #[coverage()] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++ +LL | #[coverage(on)] + | ++ error: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:26:1 diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr index c034149d8ec92..612301885dcc8 100644 --- a/tests/ui/coverage-attr/word-only.stderr +++ b/tests/ui/coverage-attr/word-only.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:17:5 @@ -21,12 +19,10 @@ LL | #![coverage] | help: the following are the possible correct uses | -LL - #![coverage] -LL + #![coverage(off)] - | -LL - #![coverage] -LL + #![coverage(on)] - | +LL | #![coverage(off)] + | +++++ +LL | #![coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:21:1 @@ -36,12 +32,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:29:5 @@ -51,12 +45,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:26:1 @@ -66,12 +58,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:39:5 @@ -81,12 +71,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:44:5 @@ -96,12 +84,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:35:1 @@ -111,12 +97,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:53:5 @@ -126,12 +110,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:58:5 @@ -141,12 +123,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:50:1 @@ -156,12 +136,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:64:1 @@ -171,12 +149,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error[E0788]: coverage attribute not allowed here --> $DIR/word-only.rs:21:1 diff --git a/tests/ui/destructuring-assignment/struct_destructure_fail.stderr b/tests/ui/destructuring-assignment/struct_destructure_fail.stderr index 7efc0b20e54be..2d02e33b2586b 100644 --- a/tests/ui/destructuring-assignment/struct_destructure_fail.stderr +++ b/tests/ui/destructuring-assignment/struct_destructure_fail.stderr @@ -31,9 +31,8 @@ LL + Struct { a, b } = Struct { a: 1, b: 2 }; | help: if you don't care about this missing field, you can explicitly ignore it | -LL - Struct { a, _ } = Struct { a: 1, b: 2 }; -LL + Struct { a, b: _ } = Struct { a: 1, b: 2 }; - | +LL | Struct { a, b: _ } = Struct { a: 1, b: 2 }; + | ++ help: or always ignore missing fields here | LL - Struct { a, _ } = Struct { a: 1, b: 2 }; diff --git a/tests/ui/diagnostic_namespace/suggest_typos.stderr b/tests/ui/diagnostic_namespace/suggest_typos.stderr index f41e2f6555675..86d778c6ec05b 100644 --- a/tests/ui/diagnostic_namespace/suggest_typos.stderr +++ b/tests/ui/diagnostic_namespace/suggest_typos.stderr @@ -11,9 +11,8 @@ LL | #![deny(unknown_or_malformed_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: an attribute with a similar name exists | -LL - #[diagnostic::onunimplemented] -LL + #[diagnostic::on_unimplemented] - | +LL | #[diagnostic::on_unimplemented] + | + error: unknown diagnostic attribute --> $DIR/suggest_typos.rs:9:15 @@ -35,9 +34,8 @@ LL | #[diagnostic::on_implemented] | help: an attribute with a similar name exists | -LL - #[diagnostic::on_implemented] -LL + #[diagnostic::on_unimplemented] - | +LL | #[diagnostic::on_unimplemented] + | ++ error: aborting due to 3 previous errors diff --git a/tests/ui/dyn-compatibility/multiple-supers-should-work.rs b/tests/ui/dyn-compatibility/multiple-supers-should-work.rs new file mode 100644 index 0000000000000..6f381da9a2200 --- /dev/null +++ b/tests/ui/dyn-compatibility/multiple-supers-should-work.rs @@ -0,0 +1,21 @@ +//@ check-pass + +// We previously incorrectly deduplicated the list of projection bounds +// of trait objects, causing us to incorrectly reject this code, cc #136458. + +trait Sup { + type Assoc; +} + +impl Sup for () { + type Assoc = T; +} + +trait Trait: Sup + Sup {} + +impl Trait for () {} + +fn main() { + let x: &dyn Trait<(), _> = &(); + let y: &dyn Trait<_, ()> = x; +} diff --git a/tests/ui/error-codes/E0027.stderr b/tests/ui/error-codes/E0027.stderr index 3a1ebf2971946..72f20a845567b 100644 --- a/tests/ui/error-codes/E0027.stderr +++ b/tests/ui/error-codes/E0027.stderr @@ -25,19 +25,16 @@ LL | Dog { name: x, } => {} | help: include the missing field in the pattern | -LL - Dog { name: x, } => {} -LL + Dog { name: x, age } => {} - | +LL | Dog { name: x, age } => {} + | +++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - Dog { name: x, } => {} -LL + Dog { name: x, age: _ } => {} - | +LL | Dog { name: x, age: _ } => {} + | ++++++ help: or always ignore missing fields here | -LL - Dog { name: x, } => {} -LL + Dog { name: x, .. } => {} - | +LL | Dog { name: x, .. } => {} + | ++ error[E0027]: pattern does not mention field `age` --> $DIR/E0027.rs:19:9 @@ -47,19 +44,16 @@ LL | Dog { name: x , } => {} | help: include the missing field in the pattern | -LL - Dog { name: x , } => {} -LL + Dog { name: x, age } => {} - | +LL | Dog { name: x, age } => {} + | ~~~~~~~ help: if you don't care about this missing field, you can explicitly ignore it | -LL - Dog { name: x , } => {} -LL + Dog { name: x, age: _ } => {} - | +LL | Dog { name: x, age: _ } => {} + | ~~~~~~~~~~ help: or always ignore missing fields here | -LL - Dog { name: x , } => {} -LL + Dog { name: x, .. } => {} - | +LL | Dog { name: x, .. } => {} + | ~~~~~~ error[E0027]: pattern does not mention fields `name`, `age` --> $DIR/E0027.rs:22:9 @@ -69,19 +63,16 @@ LL | Dog {} => {} | help: include the missing fields in the pattern | -LL - Dog {} => {} -LL + Dog { name, age } => {} - | +LL | Dog { name, age } => {} + | +++++++++ help: if you don't care about these missing fields, you can explicitly ignore them | -LL - Dog {} => {} -LL + Dog { name: _, age: _ } => {} - | +LL | Dog { name: _, age: _ } => {} + | +++++++++++++++ help: or always ignore missing fields here | -LL - Dog {} => {} -LL + Dog { .. } => {} - | +LL | Dog { .. } => {} + | ++ error: aborting due to 4 previous errors diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr index 35bd842b2cf4c..26c9689b9c58e 100644 --- a/tests/ui/error-codes/E0057.stderr +++ b/tests/ui/error-codes/E0057.stderr @@ -11,9 +11,8 @@ LL | let f = |x| x * 3; | ^^^ help: provide the argument | -LL - let a = f(); -LL + let a = f(/* x */); - | +LL | let a = f(/* x */); + | +++++++ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/E0057.rs:5:13 diff --git a/tests/ui/error-codes/E0060.stderr b/tests/ui/error-codes/E0060.stderr index fc52c6fc5ea50..7065b623ad325 100644 --- a/tests/ui/error-codes/E0060.stderr +++ b/tests/ui/error-codes/E0060.stderr @@ -11,9 +11,8 @@ LL | fn printf(_: *const u8, ...) -> u32; | ^^^^^^ - help: provide the argument | -LL - unsafe { printf(); } -LL + unsafe { printf(/* *const u8 */); } - | +LL | unsafe { printf(/* *const u8 */); } + | +++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0061.stderr b/tests/ui/error-codes/E0061.stderr index b70d607ebeb64..cab72a984a6b0 100644 --- a/tests/ui/error-codes/E0061.stderr +++ b/tests/ui/error-codes/E0061.stderr @@ -11,9 +11,8 @@ LL | fn f(a: u16, b: &str) {} | ^ ------- help: provide the argument | -LL - f(0); -LL + f(0, /* &str */); - | +LL | f(0, /* &str */); + | ++++++++++++ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/E0061.rs:9:5 @@ -28,9 +27,8 @@ LL | fn f2(a: u16) {} | ^^ ------ help: provide the argument | -LL - f2(); -LL + f2(/* u16 */); - | +LL | f2(/* u16 */); + | +++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0259.stderr b/tests/ui/error-codes/E0259.stderr index 08d3deb68d233..1833fe90f3d5c 100644 --- a/tests/ui/error-codes/E0259.stderr +++ b/tests/ui/error-codes/E0259.stderr @@ -10,9 +10,8 @@ LL | extern crate test as alloc; = note: `alloc` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate test as alloc; -LL + extern crate test as other_alloc; - | +LL | extern crate test as other_alloc; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0260.stderr b/tests/ui/error-codes/E0260.stderr index cb47b77904a38..10811d1f31871 100644 --- a/tests/ui/error-codes/E0260.stderr +++ b/tests/ui/error-codes/E0260.stderr @@ -10,9 +10,8 @@ LL | mod alloc { = note: `alloc` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate alloc; -LL + extern crate alloc as other_alloc; - | +LL | extern crate alloc as other_alloc; + | ++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr index 54bde98b57f9f..d9acdbea3fc02 100644 --- a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr +++ b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr @@ -12,11 +12,8 @@ LL | | )) {} = note: `#[warn(anonymous_parameters)]` on by default help: try naming the parameter or explicitly ignoring it | -LL ~ fn test(x: u32, _: ( -LL + -LL + -LL ~ )) {} - | +LL | fn test(x: u32, _: ( + | ++ warning: 1 warning emitted diff --git a/tests/ui/extern/extern-crate-rename.stderr b/tests/ui/extern/extern-crate-rename.stderr index 4d4a585de60c1..88b78a07485d4 100644 --- a/tests/ui/extern/extern-crate-rename.stderr +++ b/tests/ui/extern/extern-crate-rename.stderr @@ -9,9 +9,8 @@ LL | extern crate m2 as m1; = note: `m1` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate m2 as m1; -LL + extern crate m2 as other_m1; - | +LL | extern crate m2 as other_m1; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index 214725b77c049..7768c25bd2c37 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -165,9 +165,8 @@ LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} found signature `extern "rust-call" fn(&Bar, ()) -> ()` help: change the self-receiver type to match the trait | -LL - extern "rust-call" fn call_mut(&self, args: ()) -> () {} -LL + extern "rust-call" fn call_mut(&mut self, args: ()) -> () {} - | +LL | extern "rust-call" fn call_mut(&mut self, args: ()) -> () {} + | +++ error[E0046]: not all trait items implemented, missing: `Output` --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:1 diff --git a/tests/ui/fmt/no-inline-literals-out-of-range.stderr b/tests/ui/fmt/no-inline-literals-out-of-range.stderr index e17023887046f..0800fb2497619 100644 --- a/tests/ui/fmt/no-inline-literals-out-of-range.stderr +++ b/tests/ui/fmt/no-inline-literals-out-of-range.stderr @@ -13,9 +13,8 @@ LL + format_args!("{}", 0x8f_u8); // issue #115423 | help: to use as a negative number (decimal `-113`), consider using the type `u8` for the literal and cast it to `i8` | -LL - format_args!("{}", 0x8f_i8); // issue #115423 -LL + format_args!("{}", 0x8f_u8 as i8); // issue #115423 - | +LL | format_args!("{}", 0x8f_u8 as i8); // issue #115423 + | +++++ error: literal out of range for `u8` --> $DIR/no-inline-literals-out-of-range.rs:6:24 diff --git a/tests/ui/fn/issue-3044.stderr b/tests/ui/fn/issue-3044.stderr index 8351818dc897c..787eeec09cc2f 100644 --- a/tests/ui/fn/issue-3044.stderr +++ b/tests/ui/fn/issue-3044.stderr @@ -11,8 +11,8 @@ note: method defined here --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: provide the argument | -LL ~ needlesArr.iter().fold(|x, y| { -LL + +LL | needlesArr.iter().fold(|x, y| { +LL | LL ~ }, /* f */); | diff --git a/tests/ui/fn/param-mismatch-foreign.stderr b/tests/ui/fn/param-mismatch-foreign.stderr index 88aa3cd036833..835e0a3343e9a 100644 --- a/tests/ui/fn/param-mismatch-foreign.stderr +++ b/tests/ui/fn/param-mismatch-foreign.stderr @@ -11,9 +11,8 @@ LL | fn foo(x: i32, y: u32, z: i32); | ^^^ - help: provide the argument | -LL - foo(1i32, 2i32); -LL + foo(1i32, /* u32 */, 2i32); - | +LL | foo(1i32, /* u32 */, 2i32); + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr index 4f9fc0ac6492c..9f94b3aff8821 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr @@ -11,9 +11,8 @@ LL | fn f(i: I) | ^ ---- help: provide the argument | -LL - f(&[f()]); -LL + f(&[f(/* i */)]); - | +LL | f(&[f(/* i */)]); + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/implicit-capture-late.rs b/tests/ui/impl-trait/implicit-capture-late.rs index 986620b101bdd..13cbcd66f8d87 100644 --- a/tests/ui/impl-trait/implicit-capture-late.rs +++ b/tests/ui/impl-trait/implicit-capture-late.rs @@ -1,13 +1,13 @@ -//@ known-bug: #117647 +//@ edition: 2024 -#![feature(lifetime_capture_rules_2024)] #![feature(rustc_attrs)] #![allow(internal_features)] #![rustc_variance_of_opaques] use std::ops::Deref; -fn foo(x: Vec) -> Box Deref> { +fn foo(x: Vec) -> Box Deref> { //~ ['a: o] + //~^ ERROR cannot capture higher-ranked lifetime Box::new(x) } diff --git a/tests/ui/impl-trait/implicit-capture-late.stderr b/tests/ui/impl-trait/implicit-capture-late.stderr index 3adf78322d2e5..085d3eaedd48c 100644 --- a/tests/ui/impl-trait/implicit-capture-late.stderr +++ b/tests/ui/impl-trait/implicit-capture-late.stderr @@ -1,17 +1,17 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/implicit-capture-late.rs:10:55 + --> $DIR/implicit-capture-late.rs:9:55 | LL | fn foo(x: Vec) -> Box Deref> { | ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here - --> $DIR/implicit-capture-late.rs:10:36 + --> $DIR/implicit-capture-late.rs:9:36 | LL | fn foo(x: Vec) -> Box Deref> { | ^^ error: ['a: o] - --> $DIR/implicit-capture-late.rs:10:55 + --> $DIR/implicit-capture-late.rs:9:55 | LL | fn foo(x: Vec) -> Box Deref> { | ^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr index b7797317ea68f..7c064cc717699 100644 --- a/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr +++ b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr @@ -12,9 +12,8 @@ LL | fn bar(&self) -> impl Iterator + '_ { = note: `#[warn(refining_impl_trait_internal)]` on by default help: replace the return type so that it matches the trait | -LL - fn bar(&self) -> impl Iterator + '_ { -LL + fn bar(&self) -> impl Iterator + '_ { - | +LL | fn bar(&self) -> impl Iterator + '_ { + | +++++++++++++++++++ warning: 1 warning emitted diff --git a/tests/ui/impl-trait/in-trait/refine-captures.stderr b/tests/ui/impl-trait/in-trait/refine-captures.stderr index 8a5c8d3c77b0f..166991894d166 100644 --- a/tests/ui/impl-trait/in-trait/refine-captures.stderr +++ b/tests/ui/impl-trait/in-trait/refine-captures.stderr @@ -9,9 +9,8 @@ LL | fn test() -> impl Sized + use<> {} = note: `#[warn(refining_impl_trait_internal)]` on by default help: modify the `use<..>` bound to capture the same lifetimes that the trait does | -LL - fn test() -> impl Sized + use<> {} -LL + fn test() -> impl Sized + use<'a> {} - | +LL | fn test() -> impl Sized + use<'a> {} + | ++ warning: impl trait in impl method captures fewer lifetimes than in trait --> $DIR/refine-captures.rs:22:31 @@ -23,9 +22,8 @@ LL | fn test() -> impl Sized + use<> {} = note: we are soliciting feedback, see issue #121718 for more information help: modify the `use<..>` bound to capture the same lifetimes that the trait does | -LL - fn test() -> impl Sized + use<> {} -LL + fn test() -> impl Sized + use<'a> {} - | +LL | fn test() -> impl Sized + use<'a> {} + | ++ warning: impl trait in impl method captures fewer lifetimes than in trait --> $DIR/refine-captures.rs:27:31 @@ -37,9 +35,8 @@ LL | fn test() -> impl Sized + use<'b> {} = note: we are soliciting feedback, see issue #121718 for more information help: modify the `use<..>` bound to capture the same lifetimes that the trait does | -LL - fn test() -> impl Sized + use<'b> {} -LL + fn test() -> impl Sized + use<'a, 'b> {} - | +LL | fn test() -> impl Sized + use<'a, 'b> {} + | ++++ error: `impl Trait` must mention all type parameters in scope in `use<...>` --> $DIR/refine-captures.rs:32:18 diff --git a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 46561b66c8ee1..ba7d7770e5038 100644 --- a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -41,9 +41,8 @@ LL + fn elided2(x: &i32) -> impl Copy + '_ { x } | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn elided2(x: &i32) -> impl Copy + 'static { x } -LL + fn elided2(x: &'static i32) -> impl Copy + 'static { x } - | +LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } + | +++++++ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:12:55 @@ -172,9 +171,8 @@ LL + fn elided4(x: &i32) -> Box { Box::new(x) } | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn elided4(x: &i32) -> Box { Box::new(x) } -LL + fn elided4(x: &'static i32) -> Box { Box::new(x) } - | +LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } + | +++++++ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:27:60 diff --git a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs index 3dc8523e9635d..925f03589e894 100644 --- a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs +++ b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs @@ -1,9 +1,8 @@ //@ check-pass +//@ edition: 2024 // Show how precise captures allow us to skip capturing a higher-ranked lifetime -#![feature(lifetime_capture_rules_2024)] - trait Trait<'a> { type Item; } diff --git a/tests/ui/impl-trait/precise-capturing/outlives.rs b/tests/ui/impl-trait/precise-capturing/outlives.rs index f86a61be1e078..45e46848eea7c 100644 --- a/tests/ui/impl-trait/precise-capturing/outlives.rs +++ b/tests/ui/impl-trait/precise-capturing/outlives.rs @@ -1,9 +1,8 @@ //@ check-pass +//@ edition: 2024 // Show that precise captures allow us to skip a lifetime param for outlives -#![feature(lifetime_capture_rules_2024)] - fn hello<'a: 'a, 'b: 'b>() -> impl Sized + use<'a> { } fn outlives<'a, T: 'a>(_: T) {} diff --git a/tests/ui/impl-trait/variance.e2024.stderr b/tests/ui/impl-trait/variance.e2024.stderr index 361a165da66f3..adbe8b91e866f 100644 --- a/tests/ui/impl-trait/variance.e2024.stderr +++ b/tests/ui/impl-trait/variance.e2024.stderr @@ -1,23 +1,23 @@ error: ['a: *, 'a: o] - --> $DIR/variance.rs:13:36 + --> $DIR/variance.rs:11:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: ['a: *, 'a: o] - --> $DIR/variance.rs:18:32 + --> $DIR/variance.rs:15:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:20:40 + --> $DIR/variance.rs:17:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:25:36 + --> $DIR/variance.rs:21:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.new.stderr b/tests/ui/impl-trait/variance.new.stderr deleted file mode 100644 index 361a165da66f3..0000000000000 --- a/tests/ui/impl-trait/variance.new.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: ['a: *, 'a: o] - --> $DIR/variance.rs:13:36 - | -LL | fn not_captured_early<'a: 'a>() -> impl Sized {} - | ^^^^^^^^^^ - -error: ['a: *, 'a: o] - --> $DIR/variance.rs:18:32 - | -LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: ['a: o] - --> $DIR/variance.rs:20:40 - | -LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} - | ^^^^^^^^^^ - -error: ['a: o] - --> $DIR/variance.rs:25:36 - | -LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors - diff --git a/tests/ui/impl-trait/variance.old.stderr b/tests/ui/impl-trait/variance.old.stderr index 578d6fd14cd20..57ffa7cde31c4 100644 --- a/tests/ui/impl-trait/variance.old.stderr +++ b/tests/ui/impl-trait/variance.old.stderr @@ -1,23 +1,23 @@ error: ['a: *] - --> $DIR/variance.rs:13:36 + --> $DIR/variance.rs:11:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: ['a: *, 'a: o] - --> $DIR/variance.rs:18:32 + --> $DIR/variance.rs:15:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [] - --> $DIR/variance.rs:20:40 + --> $DIR/variance.rs:17:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:25:36 + --> $DIR/variance.rs:21:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.rs b/tests/ui/impl-trait/variance.rs index 1e359f033ff52..bde3a886a4d38 100644 --- a/tests/ui/impl-trait/variance.rs +++ b/tests/ui/impl-trait/variance.rs @@ -1,8 +1,6 @@ -//@ revisions: old new e2024 +//@ revisions: old e2024 //@[e2024] edition: 2024 -#![cfg_attr(new, feature(lifetime_capture_rules_2024))] - #![feature(rustc_attrs)] #![allow(internal_features)] #![rustc_variance_of_opaques] @@ -12,15 +10,13 @@ impl Captures<'_> for T {} fn not_captured_early<'a: 'a>() -> impl Sized {} //[old]~^ ['a: *] -//[new]~^^ ['a: *, 'a: o] -//[e2024]~^^^ ['a: *, 'a: o] +//[e2024]~^^ ['a: *, 'a: o] fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ ['a: *, 'a: o] fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} //[old]~^ [] -//[new]~^^ ['a: o] -//[e2024]~^^^ ['a: o] +//[e2024]~^^ ['a: o] fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ ['a: o] diff --git a/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr b/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr index 9a3ebfddc49c5..ec700cf7e5900 100644 --- a/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr +++ b/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr @@ -6,9 +6,8 @@ LL | extern crate self; | help: rename the `self` crate to be able to import it | -LL - extern crate self; -LL + extern crate self as name; - | +LL | extern crate self as name; + | +++++++ error: `#[macro_use]` is not supported on `extern crate self` --> $DIR/extern-crate-self-fail.rs:3:1 diff --git a/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr b/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr index def0676a0f82c..2621f913186ee 100644 --- a/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr +++ b/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr @@ -7,9 +7,8 @@ LL | extern crate std; = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate std; -LL + extern crate std as other_std; - | +LL | extern crate std as other_std; + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/import-self.stderr b/tests/ui/imports/issue-45829/import-self.stderr index b392d93c15410..5094a50635d53 100644 --- a/tests/ui/imports/issue-45829/import-self.stderr +++ b/tests/ui/imports/issue-45829/import-self.stderr @@ -62,9 +62,8 @@ LL | use foo::{self as A}; = note: `A` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use foo::{self as A}; -LL + use foo::{self as OtherA}; - | +LL | use foo::{self as OtherA}; + | +++++ error: aborting due to 5 previous errors diff --git a/tests/ui/imports/issue-45829/issue-45829.stderr b/tests/ui/imports/issue-45829/issue-45829.stderr index 9fd0e5a767295..618fac350f023 100644 --- a/tests/ui/imports/issue-45829/issue-45829.stderr +++ b/tests/ui/imports/issue-45829/issue-45829.stderr @@ -9,9 +9,8 @@ LL | use foo::{A, B as A}; = note: `A` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use foo::{A, B as A}; -LL + use foo::{A, B as OtherA}; - | +LL | use foo::{A, B as OtherA}; + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr b/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr index 98fe16824ff76..f33b093725f06 100644 --- a/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr +++ b/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr @@ -9,9 +9,8 @@ LL | extern crate issue_45829_b as bar; = note: `bar` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate issue_45829_b as bar; -LL + extern crate issue_45829_b as other_bar; - | +LL | extern crate issue_45829_b as other_bar; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-extern.stderr b/tests/ui/imports/issue-45829/rename-extern.stderr index f99f433c64241..2a3a05d1e7b48 100644 --- a/tests/ui/imports/issue-45829/rename-extern.stderr +++ b/tests/ui/imports/issue-45829/rename-extern.stderr @@ -9,9 +9,8 @@ LL | extern crate issue_45829_b as issue_45829_a; = note: `issue_45829_a` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate issue_45829_b as issue_45829_a; -LL + extern crate issue_45829_b as other_issue_45829_a; - | +LL | extern crate issue_45829_b as other_issue_45829_a; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr b/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr index e0647cd3ab68b..399de74a5919c 100644 --- a/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr +++ b/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr @@ -9,9 +9,8 @@ LL | use std as issue_45829_b; = note: `issue_45829_b` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std as issue_45829_b; -LL + use std as other_issue_45829_b; - | +LL | use std as other_issue_45829_b; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-with-path.stderr b/tests/ui/imports/issue-45829/rename-with-path.stderr index 45fdd46850e04..fc30eb1cf8d7e 100644 --- a/tests/ui/imports/issue-45829/rename-with-path.stderr +++ b/tests/ui/imports/issue-45829/rename-with-path.stderr @@ -9,9 +9,8 @@ LL | use std::{collections::HashMap as A, sync::Arc as A}; = note: `A` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std::{collections::HashMap as A, sync::Arc as A}; -LL + use std::{collections::HashMap as A, sync::Arc as OtherA}; - | +LL | use std::{collections::HashMap as A, sync::Arc as OtherA}; + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename.stderr b/tests/ui/imports/issue-45829/rename.stderr index dc5775e3d56d2..a17dc6964dada 100644 --- a/tests/ui/imports/issue-45829/rename.stderr +++ b/tests/ui/imports/issue-45829/rename.stderr @@ -9,9 +9,8 @@ LL | use std as core; = note: `core` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std as core; -LL + use std as other_core; - | +LL | use std as other_core; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr index 4a5c85479d33d..bc9755732813c 100644 --- a/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr +++ b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr @@ -14,9 +14,8 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can use `as` to change the binding name of the import | -LL - extern crate std as core; -LL + extern crate std as other_core; - | +LL | extern crate std as other_core; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr b/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr index 8b87ae93b4d5e..f1b60bbe39d5b 100644 --- a/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr +++ b/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr @@ -14,9 +14,8 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can use `as` to change the binding name of the import | -LL - extern crate std as empty; -LL + extern crate std as other_empty; - | +LL | extern crate std as other_empty; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr b/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr index 9a9e538740d7b..13e1aaacd7025 100644 --- a/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr +++ b/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr @@ -20,9 +20,8 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can use `as` to change the binding name of the import | -LL - extern crate std as non_existent; -LL + extern crate std as other_non_existent; - | +LL | extern crate std as other_non_existent; + | ++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/imports/no-std-inject.stderr b/tests/ui/imports/no-std-inject.stderr index d3952a50cd311..7299c2e8a9f39 100644 --- a/tests/ui/imports/no-std-inject.stderr +++ b/tests/ui/imports/no-std-inject.stderr @@ -7,9 +7,8 @@ LL | extern crate core; = note: `core` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate core; -LL + extern crate core as other_core; - | +LL | extern crate core as other_core; + | +++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/include-macros/parent_dir.stderr b/tests/ui/include-macros/parent_dir.stderr index 23029e911203c..d0a1f4fd3b91f 100644 --- a/tests/ui/include-macros/parent_dir.stderr +++ b/tests/ui/include-macros/parent_dir.stderr @@ -20,9 +20,8 @@ LL | let _ = include_str!("hello.rs"); = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) help: there is a file with the same name in a different directory | -LL - let _ = include_str!("hello.rs"); -LL + let _ = include_str!("../hello.rs"); - | +LL | let _ = include_str!("../hello.rs"); + | +++ error: couldn't read `$DIR/../../data.bin`: $FILE_NOT_FOUND_MSG --> $DIR/parent_dir.rs:8:13 diff --git a/tests/ui/issues/issue-20225.stderr b/tests/ui/issues/issue-20225.stderr index 6a3c4e2a836e0..775f23dd7e623 100644 --- a/tests/ui/issues/issue-20225.stderr +++ b/tests/ui/issues/issue-20225.stderr @@ -10,9 +10,8 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {} found signature `extern "rust-call" fn(&Foo, (_,))` help: change the parameter type to match the trait | -LL - extern "rust-call" fn call(&self, (_,): (T,)) {} -LL + extern "rust-call" fn call(&self, (_,): (&'a T,)) {} - | +LL | extern "rust-call" fn call(&self, (_,): (&'a T,)) {} + | +++ error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/issue-20225.rs:11:51 @@ -26,9 +25,8 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} found signature `extern "rust-call" fn(&mut Foo, (_,))` help: change the parameter type to match the trait | -LL - extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} -LL + extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} - | +LL | extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} + | +++ error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/issue-20225.rs:18:47 @@ -43,9 +41,8 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} found signature `extern "rust-call" fn(Foo, (_,))` help: change the parameter type to match the trait | -LL - extern "rust-call" fn call_once(self, (_,): (T,)) {} -LL + extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} - | +LL | extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} + | +++ error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-23073.stderr b/tests/ui/issues/issue-23073.stderr index 8aa86887bcfc6..87dcf3b328923 100644 --- a/tests/ui/issues/issue-23073.stderr +++ b/tests/ui/issues/issue-23073.stderr @@ -6,9 +6,8 @@ LL | type FooT = <::Foo>::T; | help: if there were a trait named `Example` with associated type `T` implemented for `::Foo`, you could use the fully-qualified path | -LL - type FooT = <::Foo>::T; -LL + type FooT = <::Foo as Example>::T; - | +LL | type FooT = <::Foo as Example>::T; + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr index eabb08421121e..f54990d5d8618 100644 --- a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr +++ b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr @@ -6,9 +6,8 @@ LL | let foo::Foo {} = foo::Foo::default(); | help: ignore the inaccessible and unused fields | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { .. } = foo::Foo::default(); - | +LL | let foo::Foo { .. } = foo::Foo::default(); + | ++ error: pattern requires `..` due to inaccessible fields --> $DIR/issue-76077-1.rs:16:9 diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.rs b/tests/ui/layout/gce-rigid-const-in-array-len.rs new file mode 100644 index 0000000000000..8e57907a2c5ec --- /dev/null +++ b/tests/ui/layout/gce-rigid-const-in-array-len.rs @@ -0,0 +1,27 @@ +//! With `feature(generic_const_exprs)`, anon consts (e.g. length in array types) will +//! inherit their parent's predicates. When combined with `feature(trivial_bounds)`, it +//! is possible to have an unevaluated constant that is rigid, but not generic. +//! +//! This is what happens below: `u8: A` does not hold in the global environment, but +//! with trivial bounds + GCE it it possible that `::B` can appear in an array +//! length without causing a compile error. This constant is *rigid* (i.e. it cannot be +//! normalized further), but it is *not generic* (i.e. it does not depend on any generic +//! parameters). +//! +//! This test ensures that we do not ICE in layout computation when encountering such a +//! constant. + +#![feature(rustc_attrs)] +#![feature(generic_const_exprs)] //~ WARNING: the feature `generic_const_exprs` is incomplete +#![feature(trivial_bounds)] + +#![crate_type = "lib"] + +trait A { + const B: usize; +} + +#[rustc_layout(debug)] +struct S([u8; ::B]) //~ ERROR: the type `[u8; ::B]` has an unknown layout +where + u8: A; diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.stderr b/tests/ui/layout/gce-rigid-const-in-array-len.stderr new file mode 100644 index 0000000000000..6149debdfe88d --- /dev/null +++ b/tests/ui/layout/gce-rigid-const-in-array-len.stderr @@ -0,0 +1,17 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gce-rigid-const-in-array-len.rs:15:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: the type `[u8; ::B]` has an unknown layout + --> $DIR/gce-rigid-const-in-array-len.rs:25:1 + | +LL | struct S([u8; ::B]) + | ^^^^^^^^ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs new file mode 100644 index 0000000000000..c9b1e0a4b9ec3 --- /dev/null +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -0,0 +1,18 @@ +//! Regression test for . +//! +//! This used to ICE in layout computation, because `::B` fails to normalize +//! due to the unconstrained param on the impl. + +#![feature(rustc_attrs)] +#![crate_type = "lib"] + +trait A { + const B: usize; +} + +impl A for u8 { //~ ERROR: the type parameter `C` is not constrained + const B: usize = 42; +} + +#[rustc_layout(debug)] +struct S([u8; ::B]); //~ ERROR: the type has an unknown layout diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr new file mode 100644 index 0000000000000..615c131eb9045 --- /dev/null +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -0,0 +1,15 @@ +error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-param-ice-137308.rs:13:6 + | +LL | impl A for u8 { + | ^ unconstrained type parameter + +error: the type has an unknown layout + --> $DIR/unconstrained-param-ice-137308.rs:18:1 + | +LL | struct S([u8; ::B]); + | ^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/lifetimes/borrowck-let-suggestion.stderr b/tests/ui/lifetimes/borrowck-let-suggestion.stderr index 4703d7f10dc28..9020ee22f9bd8 100644 --- a/tests/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/tests/ui/lifetimes/borrowck-let-suggestion.stderr @@ -13,7 +13,7 @@ LL | x.use_mut(); help: consider consuming the `Vec` when turning it into an `Iterator` | LL | let mut x = vec![1].into_iter(); - | +++++ + | +++++ help: consider using a `let` binding to create a longer lived value | LL ~ let binding = vec![1]; diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr index 8aa94f66812f3..bdf911367653b 100644 --- a/tests/ui/lifetimes/issue-26638.stderr +++ b/tests/ui/lifetimes/issue-26638.stderr @@ -56,9 +56,8 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } | help: provide the argument | -LL - fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } -LL + fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) } - | +LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) } + | +++++++++ error[E0308]: mismatched types --> $DIR/issue-26638.rs:4:47 diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr index 337d5d0b307ee..00a2ca99f241c 100644 --- a/tests/ui/lint/static-mut-refs.e2021.stderr +++ b/tests/ui/lint/static-mut-refs.e2021.stderr @@ -22,9 +22,8 @@ LL | let _y = &mut X; = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - let _y = &mut X; -LL + let _y = &raw mut X; - | +LL | let _y = &raw mut X; + | +++ warning: creating a shared reference to mutable static is discouraged --> $DIR/static-mut-refs.rs:50:22 diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr index cf7f0a86f4fe7..ff41f316250d1 100644 --- a/tests/ui/lint/static-mut-refs.e2024.stderr +++ b/tests/ui/lint/static-mut-refs.e2024.stderr @@ -22,9 +22,8 @@ LL | let _y = &mut X; = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - let _y = &mut X; -LL + let _y = &raw mut X; - | +LL | let _y = &raw mut X; + | +++ error: creating a shared reference to mutable static is discouraged --> $DIR/static-mut-refs.rs:50:22 diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index 6ba0c9d907c5e..4d6403b1e7db2 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -26,9 +26,8 @@ LL + let fail = 0b1000_0001u8; | help: to use as a negative number (decimal `-127`), consider using the type `u8` for the literal and cast it to `i8` | -LL - let fail = 0b1000_0001i8; -LL + let fail = 0b1000_0001u8 as i8; - | +LL | let fail = 0b1000_0001u8 as i8; + | +++++ warning: literal out of range for `i64` --> $DIR/type-overflow.rs:15:16 @@ -44,9 +43,8 @@ LL + let fail = 0x8000_0000_0000_0000u64; | help: to use as a negative number (decimal `-9223372036854775808`), consider using the type `u64` for the literal and cast it to `i64` | -LL - let fail = 0x8000_0000_0000_0000i64; -LL + let fail = 0x8000_0000_0000_0000u64 as i64; - | +LL | let fail = 0x8000_0000_0000_0000u64 as i64; + | ++++++ warning: literal out of range for `u32` --> $DIR/type-overflow.rs:19:16 diff --git a/tests/ui/lint/unaligned_references_fake_borrow.rs b/tests/ui/lint/unaligned_references_fake_borrow.rs new file mode 100644 index 0000000000000..b0ef8b471caad --- /dev/null +++ b/tests/ui/lint/unaligned_references_fake_borrow.rs @@ -0,0 +1,27 @@ +//@ check-pass + +// Regression test for . + +// Ensure that we don't emit unaligned packed field reference errors for the fake +// borrows that we generate during match lowering. These fake borrows are there to +// ensure in *borrow-checking* that we don't modify the value being matched, but +// they are removed after the MIR is processed by `CleanupPostBorrowck`. + +#[repr(packed)] +pub struct Packed(i32); + +fn f(x: Packed) { + match &x { + Packed(4) => {}, + _ if true => {}, + _ => {} + } + + match x { + Packed(4) => {}, + _ if true => {}, + _ => {} + } +} + +fn main() {} diff --git a/tests/ui/malformed/malformed-special-attrs.stderr b/tests/ui/malformed/malformed-special-attrs.stderr index a6220710cf912..b6a1a6b50e468 100644 --- a/tests/ui/malformed/malformed-special-attrs.stderr +++ b/tests/ui/malformed/malformed-special-attrs.stderr @@ -7,9 +7,8 @@ LL | #[cfg_attr] = note: for more information, visit help: missing condition and attribute | -LL - #[cfg_attr] -LL + #[cfg_attr(condition, attribute, other_attribute, ...)] - | +LL | #[cfg_attr(condition, attribute, other_attribute, ...)] + | ++++++++++++++++++++++++++++++++++++++++++++ error: malformed `cfg_attr` attribute input --> $DIR/malformed-special-attrs.rs:4:1 diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 7cda928aca9d3..95de40ff891be 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -28,9 +28,8 @@ LL | fn one(self, _: isize) -> Foo { self } | ^^^ -------- help: provide the argument | -LL - .one() -LL + .one(/* isize */) - | +LL | .one(/* isize */) + | +++++++++++ error[E0061]: this method takes 2 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:15:7 @@ -45,9 +44,8 @@ LL | fn two(self, _: isize, _: isize) -> Foo { self } | ^^^ -------- help: provide the argument | -LL - .two(0); -LL + .two(0, /* isize */); - | +LL | .two(0, /* isize */); + | +++++++++++++ error[E0599]: `Foo` is not an iterator --> $DIR/method-call-err-msg.rs:19:7 @@ -84,9 +82,8 @@ LL | fn three(self, _: T, _: T, _: T) -> Foo { self } | ^^^^^ ---- ---- ---- help: provide the arguments | -LL - y.three::(); -LL + y.three::(/* usize */, /* usize */, /* usize */); - | +LL | y.three::(/* usize */, /* usize */, /* usize */); + | +++++++++++++++++++++++++++++++++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/mismatched_types/closure-arg-count.stderr b/tests/ui/mismatched_types/closure-arg-count.stderr index 8704d0f661be2..e0fcf9beb3c4c 100644 --- a/tests/ui/mismatched_types/closure-arg-count.stderr +++ b/tests/ui/mismatched_types/closure-arg-count.stderr @@ -8,9 +8,8 @@ LL | [1, 2, 3].sort_by(|| panic!()); | help: consider changing the closure to take and ignore the expected arguments | -LL - [1, 2, 3].sort_by(|| panic!()); -LL + [1, 2, 3].sort_by(|_, _| panic!()); - | +LL | [1, 2, 3].sort_by(|_, _| panic!()); + | ++++ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument --> $DIR/closure-arg-count.rs:7:15 @@ -64,9 +63,8 @@ LL | fn f>(_: F) {} | ^^^^^^^^^^^^ required by this bound in `f` help: consider changing the closure to take and ignore the expected argument | -LL - f(|| panic!()); -LL + f(|_| panic!()); - | +LL | f(|_| panic!()); + | + error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments --> $DIR/closure-arg-count.rs:15:5 @@ -84,9 +82,8 @@ LL | fn f>(_: F) {} | ^^^^^^^^^^^^ required by this bound in `f` help: consider changing the closure to take and ignore the expected argument | -LL - f( move || panic!()); -LL + f( move |_| panic!()); - | +LL | f( move |_| panic!()); + | + error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments --> $DIR/closure-arg-count.rs:18:53 diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr index 7756217b56000..61786ef14c252 100644 --- a/tests/ui/mismatched_types/issue-13033.stderr +++ b/tests/ui/mismatched_types/issue-13033.stderr @@ -13,9 +13,8 @@ LL | fn bar(&mut self, other: &mut dyn Foo); found signature `fn(&mut Baz, &dyn Foo)` help: change the parameter type to match the trait | -LL - fn bar(&mut self, other: &dyn Foo) {} -LL + fn bar(&mut self, other: &mut dyn Foo) {} - | +LL | fn bar(&mut self, other: &mut dyn Foo) {} + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr b/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr index dbd313fada99c..13f51cb7b094a 100644 --- a/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr +++ b/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr @@ -8,9 +8,8 @@ note: method defined here --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: provide the argument | -LL - f.call_once() -LL + f.call_once(/* args */) - | +LL | f.call_once(/* args */) + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr index d9d99f3d1cf52..8ed4530e85e3c 100644 --- a/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr +++ b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr @@ -11,9 +11,8 @@ LL | fn foo(&mut self) -> _ { | ^^^ --------- help: provide the argument | -LL - Self::foo() -LL + Self::foo(/* value */) - | +LL | Self::foo(/* value */) + | +++++++++++ error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/mismatch-args-crash-issue-130400.rs:2:26 diff --git a/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr b/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr index 7acc361fdb8df..b949b4ea298ad 100644 --- a/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr +++ b/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr @@ -11,9 +11,8 @@ LL | unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {} | ^^^^^^^^^^^^ ------ help: provide the argument | -LL - test_va_copy(); -LL + test_va_copy(/* u64 */); - | +LL | test_va_copy(/* u64 */); + | +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/overloaded-calls-bad.stderr b/tests/ui/mismatched_types/overloaded-calls-bad.stderr index 9f5c35a30097d..0a872da601482 100644 --- a/tests/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/tests/ui/mismatched_types/overloaded-calls-bad.stderr @@ -25,9 +25,8 @@ LL | impl FnMut<(isize,)> for S { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: provide the argument | -LL - let ans = s(); -LL + let ans = s(/* isize */); - | +LL | let ans = s(/* isize */); + | +++++++++++ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/overloaded-calls-bad.rs:37:15 diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index d232cc50e5230..45a02982289de 100644 --- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -32,9 +32,8 @@ LL | fn bar(&mut self, bar: &mut Bar); found signature `fn(&mut Bar, &Bar)` help: change the parameter type to match the trait | -LL - fn bar(&mut self, bar: &Bar) { } -LL + fn bar(&mut self, bar: &mut Bar) { } - | +LL | fn bar(&mut self, bar: &mut Bar) { } + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr index 7e11b23d681b8..9dbd676969364 100644 --- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr +++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr @@ -9,9 +9,8 @@ LL | S1 { a: unsafe { &mut X1 } } = note: `#[warn(static_mut_refs)]` on by default help: use `&raw mut` instead to create a raw pointer | -LL - S1 { a: unsafe { &mut X1 } } -LL + S1 { a: unsafe { &raw mut X1 } } - | +LL | S1 { a: unsafe { &raw mut X1 } } + | +++ warning: 1 warning emitted diff --git a/tests/ui/not-enough-arguments.stderr b/tests/ui/not-enough-arguments.stderr index 637c2774d5a31..099d82eb93552 100644 --- a/tests/ui/not-enough-arguments.stderr +++ b/tests/ui/not-enough-arguments.stderr @@ -11,9 +11,8 @@ LL | fn foo(a: isize, b: isize, c: isize, d:isize) { | ^^^ ------- help: provide the argument | -LL - foo(1, 2, 3); -LL + foo(1, 2, 3, /* isize */); - | +LL | foo(1, 2, 3, /* isize */); + | +++++++++++++ error[E0061]: this function takes 6 arguments but 3 arguments were supplied --> $DIR/not-enough-arguments.rs:29:3 @@ -35,9 +34,8 @@ LL | f: i32, | ------ help: provide the arguments | -LL - bar(1, 2, 3); -LL + bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */); - | +LL | bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */); + | +++++++++++++++++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/obsolete-in-place/bad.stderr b/tests/ui/obsolete-in-place/bad.stderr index 1409a6637890f..a1321a46351a9 100644 --- a/tests/ui/obsolete-in-place/bad.stderr +++ b/tests/ui/obsolete-in-place/bad.stderr @@ -6,9 +6,8 @@ LL | x <- y; | help: if you meant to write a comparison against a negative value, add a space in between `<` and `-` | -LL - x <- y; -LL + x < - y; - | +LL | x < - y; + | + error: expected expression, found keyword `in` --> $DIR/bad.rs:10:5 diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr index 0482a5c58559e..4ceea779b29dc 100644 --- a/tests/ui/on-unimplemented/bad-annotation.stderr +++ b/tests/ui/on-unimplemented/bad-annotation.stderr @@ -6,12 +6,10 @@ LL | #[rustc_on_unimplemented] | help: the following are the possible correct uses | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented = "message"] - | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] - | +LL | #[rustc_on_unimplemented = "message"] + | +++++++++++ +LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] + | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0230]: there is no parameter `C` on trait `BadAnnotation2` --> $DIR/bad-annotation.rs:22:1 diff --git a/tests/ui/on-unimplemented/issue-104140.stderr b/tests/ui/on-unimplemented/issue-104140.stderr index 5c9d5e8d55398..3c317135dd43a 100644 --- a/tests/ui/on-unimplemented/issue-104140.stderr +++ b/tests/ui/on-unimplemented/issue-104140.stderr @@ -6,12 +6,10 @@ LL | #[rustc_on_unimplemented] | help: the following are the possible correct uses | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented = "message"] - | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] - | +LL | #[rustc_on_unimplemented = "message"] + | +++++++++++ +LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] + | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/weak-lang-item.stderr b/tests/ui/panic-handler/weak-lang-item.stderr index e9d444c1c4d8c..5dcb37df68921 100644 --- a/tests/ui/panic-handler/weak-lang-item.stderr +++ b/tests/ui/panic-handler/weak-lang-item.stderr @@ -7,9 +7,8 @@ LL | extern crate core; = note: `core` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate core; -LL + extern crate core as other_core; - | +LL | extern crate core as other_core; + | +++++++++++++ error: `#[panic_handler]` function required, but not found diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr index f0e90082bff9d..ef4e647b9f506 100644 --- a/tests/ui/parser/emoji-identifiers.stderr +++ b/tests/ui/parser/emoji-identifiers.stderr @@ -81,9 +81,8 @@ LL | fn full_of_✨() -> 👀 { | ^^^^^^^^^^^^^^^^^^^^^ help: there is an associated function `full_of_✨` with a similar name | -LL - 👀::full_of✨() -LL + 👀::full_of_✨() - | +LL | 👀::full_of_✨() + | + error[E0425]: cannot find function `i_like_to_😄_a_lot` in this scope --> $DIR/emoji-identifiers.rs:13:13 diff --git a/tests/ui/parser/extern-crate-unexpected-token.stderr b/tests/ui/parser/extern-crate-unexpected-token.stderr index 3d48f0adfa11a..033db85a6c7f1 100644 --- a/tests/ui/parser/extern-crate-unexpected-token.stderr +++ b/tests/ui/parser/extern-crate-unexpected-token.stderr @@ -6,9 +6,8 @@ LL | extern crte foo; | help: there is a keyword `crate` with a similar name | -LL - extern crte foo; -LL + extern crate foo; - | +LL | extern crate foo; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/misspelled-keywords/const-fn.stderr b/tests/ui/parser/misspelled-keywords/const-fn.stderr index 46a6d8ca779fc..cc4c0f92917db 100644 --- a/tests/ui/parser/misspelled-keywords/const-fn.stderr +++ b/tests/ui/parser/misspelled-keywords/const-fn.stderr @@ -6,9 +6,8 @@ LL | cnst fn code() {} | help: there is a keyword `const` with a similar name | -LL - cnst fn code() {} -LL + const fn code() {} - | +LL | const fn code() {} + | + error: aborting due to 1 previous error diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr index 23821decd6e43..d241f417553fc 100644 --- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr @@ -37,7 +37,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match ref_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -100,7 +100,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match res_u32_never { LL + Ok(_) => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -374,7 +374,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `&[]` not covered @@ -415,7 +415,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -462,7 +462,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match array_0_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index 84aefe7d96370..ea63d7ba1afd1 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr @@ -46,7 +46,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match ref_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -76,7 +76,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match res_u32_never { LL + Ok(_) => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered @@ -321,7 +321,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `&[!, ..]` not covered @@ -376,7 +376,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty @@ -390,7 +390,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match array_0_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -502,7 +502,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *ref_tuple_half_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index f3af74c16c30f..a1a44e7774428 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr @@ -37,7 +37,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match ref_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -67,7 +67,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match res_u32_never { LL + Ok(_) => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered @@ -312,7 +312,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered @@ -367,7 +367,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty @@ -381,7 +381,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match array_0_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -493,7 +493,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *ref_tuple_half_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr index 34f8eb1e1635d..c3e1c267b6140 100644 --- a/tests/ui/pattern/usefulness/impl-trait.stderr +++ b/tests/ui/pattern/usefulness/impl-trait.stderr @@ -36,7 +36,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match return_never_rpit(x) { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -118,7 +118,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match return_never_tait(x) { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr index 914c6ed60c839..7caee64a33fbc 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr @@ -154,7 +154,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match 7usize { LL + _ => todo!(), -LL + } +LL ~ } | error: aborting due to 12 previous errors diff --git a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr index 2acde84965066..c37a9a5157904 100644 --- a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr +++ b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr @@ -15,7 +15,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match a { LL + _ => todo!(), -LL + } +LL ~ } | error: aborting due to 1 previous error diff --git a/tests/ui/pattern/usefulness/unstable-gated-fields.stderr b/tests/ui/pattern/usefulness/unstable-gated-fields.stderr index 4487f2735345a..bd51aca65ee2d 100644 --- a/tests/ui/pattern/usefulness/unstable-gated-fields.stderr +++ b/tests/ui/pattern/usefulness/unstable-gated-fields.stderr @@ -6,19 +6,16 @@ LL | let UnstableStruct { stable, stable2, } = UnstableStruct::default(); | help: include the missing field in the pattern | -LL - let UnstableStruct { stable, stable2, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, stable2, unstable } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, stable2, unstable } = UnstableStruct::default(); + | ++++++++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - let UnstableStruct { stable, stable2, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, stable2, unstable: _ } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, stable2, unstable: _ } = UnstableStruct::default(); + | +++++++++++ help: or always ignore missing fields here | -LL - let UnstableStruct { stable, stable2, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); + | ++ error[E0027]: pattern does not mention field `stable2` --> $DIR/unstable-gated-fields.rs:13:9 @@ -28,19 +25,16 @@ LL | let UnstableStruct { stable, unstable, } = UnstableStruct::default(); | help: include the missing field in the pattern | -LL - let UnstableStruct { stable, unstable, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, unstable, stable2 } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, unstable, stable2 } = UnstableStruct::default(); + | +++++++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - let UnstableStruct { stable, unstable, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, unstable, stable2: _ } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, unstable, stable2: _ } = UnstableStruct::default(); + | ++++++++++ help: or always ignore missing fields here | -LL - let UnstableStruct { stable, unstable, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, unstable, .. } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, unstable, .. } = UnstableStruct::default(); + | ++ error: aborting due to 2 previous errors diff --git a/tests/ui/regions/region-object-lifetime-in-coercion.stderr b/tests/ui/regions/region-object-lifetime-in-coercion.stderr index 3880ae8228377..5f6a11786cc8e 100644 --- a/tests/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/tests/ui/regions/region-object-lifetime-in-coercion.stderr @@ -13,9 +13,8 @@ LL + fn a(v: &[u8]) -> Box { | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn a(v: &[u8]) -> Box { -LL + fn a(v: &'static [u8]) -> Box { - | +LL | fn a(v: &'static [u8]) -> Box { + | +++++++ error: lifetime may not live long enough --> $DIR/region-object-lifetime-in-coercion.rs:14:5 @@ -32,9 +31,8 @@ LL + fn b(v: &[u8]) -> Box { | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn b(v: &[u8]) -> Box { -LL + fn b(v: &'static [u8]) -> Box { - | +LL | fn b(v: &'static [u8]) -> Box { + | +++++++ error: lifetime may not live long enough --> $DIR/region-object-lifetime-in-coercion.rs:21:5 diff --git a/tests/ui/regions/regions-proc-bound-capture.stderr b/tests/ui/regions/regions-proc-bound-capture.stderr index 3149cd8c9a1bc..75e04bcb7c2a4 100644 --- a/tests/ui/regions/regions-proc-bound-capture.stderr +++ b/tests/ui/regions/regions-proc-bound-capture.stderr @@ -14,9 +14,8 @@ LL + fn static_proc(x: &isize) -> Box (isize) + '_> { | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn static_proc(x: &isize) -> Box (isize) + 'static> { -LL + fn static_proc(x: &'static isize) -> Box (isize) + 'static> { - | +LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> { + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr b/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr index f1db2d71b6a66..a9b45a18af397 100644 --- a/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr +++ b/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr @@ -3,9 +3,8 @@ error[E0259]: the name `std` is defined multiple times = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate std; -LL + extern crate std as other_std; - | +LL | extern crate std as other_std; + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr b/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr index 40c76821bb835..ef8723408dae8 100644 --- a/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr +++ b/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr @@ -7,9 +7,8 @@ LL | use std::slice as std; = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std::slice as std; -LL + use std::slice as other_std; - | +LL | use std::slice as other_std; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr index 45a0ca01a5603..100e0a501e016 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr @@ -38,7 +38,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match NonExhaustiveEnum::Unit { LL + NonExhaustiveEnum::Unit | NonExhaustiveEnum::Tuple(_) | NonExhaustiveEnum::Struct { .. } => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `NormalEnum::Unit`, `NormalEnum::Tuple(_)` and `NormalEnum::Struct { .. }` not covered @@ -65,7 +65,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match NormalEnum::Unit { LL + NormalEnum::Unit | NormalEnum::Tuple(_) | NormalEnum::Struct { .. } => todo!(), -LL + } +LL ~ } | error: aborting due to 3 previous errors diff --git a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr index 8843efc6ff8c9..a30cf605829f8 100644 --- a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr +++ b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr @@ -13,9 +13,8 @@ LL | foo_cpp_ref.0.frobnicate_ref(); | ++ help: there is a method `frobnicate_cpp_ref` with a similar name | -LL - foo_cpp_ref.frobnicate_ref(); -LL + foo_cpp_ref.frobnicate_cpp_ref(); - | +LL | foo_cpp_ref.frobnicate_cpp_ref(); + | ++++ error[E0599]: no method named `frobnicate_self` found for struct `CppRef` in the current scope --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:32:17 diff --git a/tests/ui/span/missing-unit-argument.stderr b/tests/ui/span/missing-unit-argument.stderr index e77ec3c8447a5..e83f7b6cb70f3 100644 --- a/tests/ui/span/missing-unit-argument.stderr +++ b/tests/ui/span/missing-unit-argument.stderr @@ -8,9 +8,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL help: provide the argument | -LL - let _: Result<(), String> = Ok(); -LL + let _: Result<(), String> = Ok(()); - | +LL | let _: Result<(), String> = Ok(()); + | ++ error[E0061]: this function takes 2 arguments but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:12:5 @@ -25,9 +24,8 @@ LL | fn foo(():(), ():()) {} | ^^^ ----- ----- help: provide the arguments | -LL - foo(); -LL + foo((), ()); - | +LL | foo((), ()); + | ++++++ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/missing-unit-argument.rs:13:5 @@ -42,9 +40,8 @@ LL | fn foo(():(), ():()) {} | ^^^ ----- help: provide the argument | -LL - foo(()); -LL + foo((), ()); - | +LL | foo((), ()); + | ++++ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:14:5 @@ -59,9 +56,8 @@ LL | fn bar(():()) {} | ^^^ ----- help: provide the argument | -LL - bar(); -LL + bar(()); - | +LL | bar(()); + | ++ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:15:7 @@ -76,9 +72,8 @@ LL | fn baz(self, (): ()) { } | ^^^ ------ help: provide the argument | -LL - S.baz(); -LL + S.baz(()); - | +LL | S.baz(()); + | ++ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:16:7 @@ -93,9 +88,8 @@ LL | fn generic(self, _: T) { } | ^^^^^^^ ---- help: provide the argument | -LL - S.generic::<()>(); -LL + S.generic::<()>(()); - | +LL | S.generic::<()>(()); + | ++ error: aborting due to 6 previous errors diff --git a/tests/ui/statics/static-mut-shared-parens.stderr b/tests/ui/statics/static-mut-shared-parens.stderr index 3d4b55909cdee..30a586c286ae7 100644 --- a/tests/ui/statics/static-mut-shared-parens.stderr +++ b/tests/ui/statics/static-mut-shared-parens.stderr @@ -22,9 +22,8 @@ LL | let _ = unsafe { ((&mut TEST)) as *const usize }; = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - let _ = unsafe { ((&mut TEST)) as *const usize }; -LL + let _ = unsafe { ((&raw mut TEST)) as *const usize }; - | +LL | let _ = unsafe { ((&raw mut TEST)) as *const usize }; + | +++ warning: 2 warnings emitted diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr index 48cac28a6eb51..69f334a5636af 100644 --- a/tests/ui/statics/static-mut-xc.stderr +++ b/tests/ui/statics/static-mut-xc.stderr @@ -67,9 +67,8 @@ LL | static_bound_set(&mut static_mut_xc::a); = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - static_bound_set(&mut static_mut_xc::a); -LL + static_bound_set(&raw mut static_mut_xc::a); - | +LL | static_bound_set(&raw mut static_mut_xc::a); + | +++ warning: 7 warnings emitted diff --git a/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr b/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr index c7689cfd323a0..09506703b7ec0 100644 --- a/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr +++ b/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr @@ -66,9 +66,8 @@ LL | let _ = S { }; | help: all remaining fields have default values, if you added `#![feature(default_field_values)]` to your crate you could use those values with `..` | -LL - let _ = S { }; -LL + let _ = S { .. }; - | +LL | let _ = S { .. }; + | ++ error[E0063]: missing fields `field1` and `field2` in initializer of `S` --> $DIR/non-exhaustive-ctor.rs:26:13 diff --git a/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr b/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr index d9b8e76aa0de6..229f47093adcc 100644 --- a/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr +++ b/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr @@ -6,9 +6,8 @@ LL | let _ = S { }; | help: all remaining fields have default values, you can use those values with `..` | -LL - let _ = S { }; -LL + let _ = S { .. }; - | +LL | let _ = S { .. }; + | ++ error[E0063]: missing fields `field1` and `field2` in initializer of `S` --> $DIR/non-exhaustive-ctor.rs:26:13 diff --git a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr index 8644f4a1dd452..2ad9c807e48ac 100644 --- a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr +++ b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr @@ -60,9 +60,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: provide the argument | -LL - let _: Option<(i8,)> = Some(); -LL + let _: Option<(i8,)> = Some(/* (i8,) */); - | +LL | let _: Option<(i8,)> = Some(/* (i8,) */); + | +++++++++++ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple-errors.rs:14:34 diff --git a/tests/ui/suggestions/args-instead-of-tuple.stderr b/tests/ui/suggestions/args-instead-of-tuple.stderr index 4b0bab971ee71..4093d06970e1b 100644 --- a/tests/ui/suggestions/args-instead-of-tuple.stderr +++ b/tests/ui/suggestions/args-instead-of-tuple.stderr @@ -34,9 +34,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: provide the argument | -LL - let _: Option<()> = Some(); -LL + let _: Option<()> = Some(()); - | +LL | let _: Option<()> = Some(()); + | ++ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple.rs:14:34 diff --git a/tests/ui/suggestions/bad-hex-float-lit.stderr b/tests/ui/suggestions/bad-hex-float-lit.stderr index 94c0715a4e683..351dc879be3c7 100644 --- a/tests/ui/suggestions/bad-hex-float-lit.stderr +++ b/tests/ui/suggestions/bad-hex-float-lit.stderr @@ -8,9 +8,8 @@ LL | let _f: f32 = 0xAAf32; | help: rewrite this as a decimal floating point literal, or use `as` to turn a hex literal into a float | -LL - let _f: f32 = 0xAAf32; -LL + let _f: f32 = 0xAA as f32; - | +LL | let _f: f32 = 0xAA as f32; + | ++ LL - let _f: f32 = 0xAAf32; LL + let _f: f32 = 170_f32; | diff --git a/tests/ui/suggestions/incorrect-variant-literal.svg b/tests/ui/suggestions/incorrect-variant-literal.svg index 0f2ade633c5ad..279fd30f2165c 100644 --- a/tests/ui/suggestions/incorrect-variant-literal.svg +++ b/tests/ui/suggestions/incorrect-variant-literal.svg @@ -1,4 +1,4 @@ - + Foo for Bar where for<'a> <&'a S>::Item: Foo {} | help: use fully-qualified syntax | -LL - impl Foo for Bar where for<'a> <&'a S>::Item: Foo {} -LL + impl Foo for Bar where for<'a> <&'a S as IntoAsyncIterator>::Item: Foo {} - | -LL - impl Foo for Bar where for<'a> <&'a S>::Item: Foo {} -LL + impl Foo for Bar where for<'a> <&'a S as IntoIterator>::Item: Foo {} - | +LL | impl Foo for Bar where for<'a> <&'a S as IntoAsyncIterator>::Item: Foo {} + | ++++++++++++++++++++ +LL | impl Foo for Bar where for<'a> <&'a S as IntoIterator>::Item: Foo {} + | +++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/test-attrs/inaccessible-test-modules.stderr b/tests/ui/test-attrs/inaccessible-test-modules.stderr index dfb6985730af5..c66dc0d0fc26c 100644 --- a/tests/ui/test-attrs/inaccessible-test-modules.stderr +++ b/tests/ui/test-attrs/inaccessible-test-modules.stderr @@ -13,7 +13,7 @@ LL | use test as y; help: consider importing this module instead | LL | use test::test as y; - | ++++++ + | ++++++ error: aborting due to 2 previous errors diff --git a/tests/crashes/126944.rs b/tests/ui/traits/object/crash-due-to-projections-modulo-norm.rs similarity index 77% rename from tests/crashes/126944.rs rename to tests/ui/traits/object/crash-due-to-projections-modulo-norm.rs index c0c5622e26020..b1f7c4a600021 100644 --- a/tests/crashes/126944.rs +++ b/tests/ui/traits/object/crash-due-to-projections-modulo-norm.rs @@ -1,9 +1,12 @@ -//@ known-bug: rust-lang/rust#126944 +//@ check-pass + +// Regression test for #126944. + // Step 1: Create two names for a single type: `Thing` and `AlsoThing` struct Thing; struct Dummy; -pub trait DummyTrait { +trait DummyTrait { type DummyType; } impl DummyTrait for Dummy { @@ -13,7 +16,7 @@ type AlsoThing = ::DummyType; // Step 2: Create names for a single trait object type: `TraitObject` and `AlsoTraitObject` -pub trait SomeTrait { +trait SomeTrait { type Item; } type TraitObject = dyn SomeTrait; @@ -21,12 +24,12 @@ type AlsoTraitObject = dyn SomeTrait; // Step 3: Force the compiler to check whether the two names are the same type -pub trait Supertrait { +trait Supertrait { type Foo; } -pub trait Subtrait: Supertrait {} +trait Subtrait: Supertrait {} -pub trait HasOutput { +trait HasOutput { type Output; } @@ -36,3 +39,5 @@ where { todo!() } + +fn main() {} diff --git a/tests/ui/traits/object/incomplete-multiple-super-projection.rs b/tests/ui/traits/object/incomplete-multiple-super-projection.rs new file mode 100644 index 0000000000000..c7294eca4bdbe --- /dev/null +++ b/tests/ui/traits/object/incomplete-multiple-super-projection.rs @@ -0,0 +1,32 @@ +// Regression test for #133361. + +trait Sup { + type Assoc; +} + +impl Sup for () { + type Assoc = T; +} +impl Dyn for () {} + +trait Dyn: Sup + Sup {} + +trait Trait { + type Assoc; +} +impl Trait for dyn Dyn<(), ()> { + type Assoc = &'static str; +} +impl Trait for dyn Dyn { +//~^ ERROR conflicting implementations of trait `Trait` for type `(dyn Dyn<(), ()> + 'static)` + type Assoc = usize; +} + +fn call(x: usize) -> as Trait>::Assoc { + x +} + +fn main() { + let x: &'static str = call::<(), ()>(0xDEADBEEF); + println!("{x}"); +} diff --git a/tests/ui/traits/object/incomplete-multiple-super-projection.stderr b/tests/ui/traits/object/incomplete-multiple-super-projection.stderr new file mode 100644 index 0000000000000..b4271f70ed055 --- /dev/null +++ b/tests/ui/traits/object/incomplete-multiple-super-projection.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Dyn<(), ()> + 'static)` + --> $DIR/incomplete-multiple-super-projection.rs:20:1 + | +LL | impl Trait for dyn Dyn<(), ()> { + | ------------------------------ first implementation here +... +LL | impl Trait for dyn Dyn { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Dyn<(), ()> + 'static)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/crashes/79590.rs b/tests/ui/traits/object/infer-shadows-implied-projection.rs similarity index 92% rename from tests/crashes/79590.rs rename to tests/ui/traits/object/infer-shadows-implied-projection.rs index b73864cce2349..628912c54faaa 100644 --- a/tests/crashes/79590.rs +++ b/tests/ui/traits/object/infer-shadows-implied-projection.rs @@ -1,4 +1,4 @@ -//@ known-bug: #79590 +//@ check-pass trait Database: Restriction {} diff --git a/tests/ui/traits/object/outlives-super-proj.rs b/tests/ui/traits/object/outlives-super-proj.rs new file mode 100644 index 0000000000000..15b67d9ab68e7 --- /dev/null +++ b/tests/ui/traits/object/outlives-super-proj.rs @@ -0,0 +1,24 @@ +//@ check-pass + +// Make sure that we still deduce outlives bounds from supertrait projections +// and require them for well-formedness. + +trait Trait { + type Assoc; +} + +trait Bar { + type Assoc; +} + +trait Foo<'a, T: 'a>: Bar { + +} + +fn outlives<'a, T: 'a>() {} + +fn implied_outlives<'a, T: Trait>(x: &dyn Foo<'a, T::Assoc>) { + outlives::<'a, T::Assoc>(); +} + +fn main() {} diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr index 2f9fdf151f08c..37fe142951d89 100644 --- a/tests/ui/traits/object/pretty.stderr +++ b/tests/ui/traits/object/pretty.stderr @@ -154,12 +154,12 @@ error[E0308]: mismatched types --> $DIR/pretty.rs:41:56 | LL | fn dyn_has_gat(x: &dyn HasGat = ()>) { x } - | - ^ expected `()`, found `&dyn HasGat = ()>` + | - ^ expected `()`, found `&dyn HasGat` | | - | help: try adding a return type: `-> &dyn HasGat = ()>` + | help: try adding a return type: `-> &dyn HasGat` | = note: expected unit type `()` - found reference `&dyn HasGat = ()>` + found reference `&dyn HasGat` error: aborting due to 14 previous errors; 1 warning emitted diff --git a/tests/ui/traits/object/redundant.rs b/tests/ui/traits/object/redundant.rs new file mode 100644 index 0000000000000..be07b15713898 --- /dev/null +++ b/tests/ui/traits/object/redundant.rs @@ -0,0 +1,12 @@ +//@ check-pass + +trait Foo: Bar {} +trait Bar { + type Out; +} + +fn w(x: &dyn Foo) { + let x: &dyn Foo = x; +} + +fn main() {} diff --git a/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr index c4deafd4f6b7a..03fd43d43a931 100644 --- a/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr +++ b/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr @@ -11,9 +11,8 @@ LL | V(u8) | ^ help: provide the argument | -LL - ::V(); -LL + ::V(/* u8 */); - | +LL | ::V(/* u8 */); + | ++++++++ error[E0308]: mismatched types --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17 diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr index 55df117d0664c..38fbff9d59dae 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr @@ -69,7 +69,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match x { LL + UninhabitedVariants::Tuple(_) => todo!(), -LL + } +LL ~ } | error: aborting due to 5 previous errors diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr index 6d9c8eabfad59..5c9a4688105ff 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr +++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr @@ -9,7 +9,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match empty_opaque() { LL + _ => todo!(), -LL + } +LL ~ } | error: aborting due to 1 previous error diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index 52d603c598082..adfb0cebf26ec 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -11,9 +11,8 @@ LL | fn infer(&self, a: A, b: B) {} | ^^^^^ ---- help: provide the argument | -LL - s.infer(0i32); -LL + s.infer(0i32, /* b */); - | +LL | s.infer(0i32, /* b */); + | +++++++++ error[E0308]: mismatched types --> $DIR/point-at-inference-4.rs:18:24 diff --git a/tests/ui/typeck/issue-110052.stderr b/tests/ui/typeck/issue-110052.stderr index 649fc8429b9c2..832cdf6f710be 100644 --- a/tests/ui/typeck/issue-110052.stderr +++ b/tests/ui/typeck/issue-110052.stderr @@ -6,12 +6,10 @@ LL | for<'iter> dyn Validator<<&'iter I>::Item>:, | help: use fully-qualified syntax | -LL - for<'iter> dyn Validator<<&'iter I>::Item>:, -LL + for<'iter> dyn Validator<<&'iter I as IntoAsyncIterator>::Item>:, - | -LL - for<'iter> dyn Validator<<&'iter I>::Item>:, -LL + for<'iter> dyn Validator<<&'iter I as IntoIterator>::Item>:, - | +LL | for<'iter> dyn Validator<<&'iter I as IntoAsyncIterator>::Item>:, + | ++++++++++++++++++++ +LL | for<'iter> dyn Validator<<&'iter I as IntoIterator>::Item>:, + | +++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/issue-13853-5.stderr b/tests/ui/typeck/issue-13853-5.stderr index 388d5ec746ce6..4e483a0a58ef1 100644 --- a/tests/ui/typeck/issue-13853-5.stderr +++ b/tests/ui/typeck/issue-13853-5.stderr @@ -14,8 +14,8 @@ LL | fn deserialize_token>(_x: D, _y: &'a str) -> &'a st | help: consider returning the local binding `_y` | -LL ~ fn deserialize_token>(_x: D, _y: &'a str) -> &'a str { -LL + _y +LL | fn deserialize_token>(_x: D, _y: &'a str) -> &'a str { +LL ~ _y LL ~ | diff --git a/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr b/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr index ed0e4eb9ece81..da9caebb2d635 100644 --- a/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr +++ b/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr @@ -6,19 +6,16 @@ LL | let foo::Foo {} = foo::Foo::default(); | help: include the missing field in the pattern and ignore the inaccessible fields | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { visible, .. } = foo::Foo::default(); - | +LL | let foo::Foo { visible, .. } = foo::Foo::default(); + | +++++++++++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { visible: _, .. } = foo::Foo::default(); - | +LL | let foo::Foo { visible: _, .. } = foo::Foo::default(); + | ++++++++++++++ help: or always ignore missing fields here | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { .. } = foo::Foo::default(); - | +LL | let foo::Foo { .. } = foo::Foo::default(); + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr index d1003fbb6b313..690851ad19adb 100644 --- a/tests/ui/typeck/struct-enum-wrong-args.stderr +++ b/tests/ui/typeck/struct-enum-wrong-args.stderr @@ -38,9 +38,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL help: provide the argument | -LL - let _ = Ok(); -LL + let _ = Ok(/* value */); - | +LL | let _ = Ok(/* value */); + | +++++++++++ error[E0061]: this struct takes 1 argument but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:9:13 @@ -55,9 +54,8 @@ LL | struct Wrapper(i32); | ^^^^^^^ help: provide the argument | -LL - let _ = Wrapper(); -LL + let _ = Wrapper(/* i32 */); - | +LL | let _ = Wrapper(/* i32 */); + | +++++++++ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 @@ -89,9 +87,8 @@ LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ help: provide the arguments | -LL - let _ = DoubleWrapper(); -LL + let _ = DoubleWrapper(/* i32 */, /* i32 */); - | +LL | let _ = DoubleWrapper(/* i32 */, /* i32 */); + | ++++++++++++++++++++ error[E0061]: this struct takes 2 arguments but 1 argument was supplied --> $DIR/struct-enum-wrong-args.rs:12:13 @@ -106,9 +103,8 @@ LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ help: provide the argument | -LL - let _ = DoubleWrapper(5); -LL + let _ = DoubleWrapper(5, /* i32 */); - | +LL | let _ = DoubleWrapper(5, /* i32 */); + | +++++++++++ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13