diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 03ee270d66ba1..c8ec5deb92c43 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -129,23 +129,23 @@ fn get_substructure_equality_expr( EnumMatching(.., fields) | Struct(.., fields) => { let combine = move |acc, field| { let rhs = get_field_equality_expr(cx, field); - if let Some(lhs) = acc { + match acc { // Combine the previous comparison with the current field // using logical AND. - return Some(cx.expr_binary(field.span, BinOpKind::And, lhs, rhs)); + Some(lhs) => Some(cx.expr_binary(field.span, BinOpKind::And, lhs, rhs)), + // Start the chain with the first field's comparison. + None => Some(rhs), } - // Start the chain with the first field's comparison. - Some(rhs) }; // First compare scalar fields, then compound fields, combining all // with logical AND. - return fields + fields .iter() .filter(|field| !field.maybe_scalar) .fold(fields.iter().filter(|field| field.maybe_scalar).fold(None, combine), combine) // If there are no fields, treat as always equal. - .unwrap_or_else(|| cx.expr_bool(span, true)); + .unwrap_or_else(|| cx.expr_bool(span, true)) } EnumDiscr(disc, match_expr) => { let lhs = get_field_equality_expr(cx, disc); @@ -154,7 +154,7 @@ fn get_substructure_equality_expr( }; // Compare the discriminant first (cheaper), then the rest of the // fields. - return cx.expr_binary(disc.span, BinOpKind::And, lhs, match_expr.clone()); + cx.expr_binary(disc.span, BinOpKind::And, lhs, match_expr.clone()) } StaticEnum(..) => cx.dcx().span_bug( span, diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 24b2bd37aa46c..9bace9d2acf61 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -136,6 +136,17 @@ fn create_wrapper_function( None }; + if tcx.sess.target.is_like_gpu { + // Conservatively apply convergent to all functions in case they may call + // a convergent function. Rely on LLVM to optimize away the unnecessary + // convergent attributes. + attributes::apply_to_llfn( + llfn, + llvm::AttributePlace::Function, + &[llvm::AttributeKind::Convergent.create_attr(cx.llcx)], + ); + } + let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) }; let mut bx = SBuilder::build(&cx, llbb); diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 8f69f176138cf..d7b8a304e9591 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -14,7 +14,7 @@ use std::borrow::Borrow; use itertools::Itertools; -use rustc_codegen_ssa::traits::TypeMembershipCodegenMethods; +use rustc_codegen_ssa::traits::{MiscCodegenMethods, TypeMembershipCodegenMethods}; use rustc_data_structures::fx::FxIndexSet; use rustc_middle::ty::{Instance, Ty}; use rustc_sanitizers::{cfi, kcfi}; @@ -70,6 +70,13 @@ pub(crate) fn declare_raw_fn<'ll, 'tcx>( let mut attrs = SmallVec::<[_; 4]>::new(); + if cx.sess().target.is_like_gpu { + // Conservatively apply convergent to all functions in case they may call + // a convergent function. Rely on LLVM to optimize away the unnecessary + // convergent attributes. + attrs.push(llvm::AttributeKind::Convergent.create_attr(cx.llcx)); + } + if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.disable_redzone) { attrs.push(llvm::AttributeKind::NoRedZone.create_attr(cx.llcx)); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 0ad74c9ca43a7..bc24f1692fcf2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -293,6 +293,7 @@ pub(crate) enum AttributeKind { CapturesNone = 46, SanitizeRealtimeNonblocking = 47, SanitizeRealtimeBlocking = 48, + Convergent = 49, } /// LLVMIntPredicate diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index b9ca0abb12863..b288720db9cc7 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2439,25 +2439,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .partition(|field| field.2); err.span_labels(used_private_fields.iter().map(|(_, span, _)| *span), "private field"); - if !remaining_private_fields.is_empty() { - let names = if remaining_private_fields.len() > 6 { - String::new() - } else { - format!( - "{} ", - listify(&remaining_private_fields, |(name, _, _)| format!("`{name}`")) - .expect("expected at least one private field to report") - ) - }; - err.note(format!( - "{}private field{s} {names}that {were} not provided", - if used_fields.is_empty() { "" } else { "...and other " }, - s = pluralize!(remaining_private_fields.len()), - were = pluralize!("was", remaining_private_fields.len()), - )); - } if let ty::Adt(def, _) = adt_ty.kind() { + if (def.did().is_local() || !used_fields.is_empty()) + && !remaining_private_fields.is_empty() + { + let names = if remaining_private_fields.len() > 6 { + String::new() + } else { + format!( + "{} ", + listify(&remaining_private_fields, |(name, _, _)| format!("`{name}`")) + .expect("expected at least one private field to report") + ) + }; + err.note(format!( + "{}private field{s} {names}that {were} not provided", + if used_fields.is_empty() { "" } else { "...and other " }, + s = pluralize!(remaining_private_fields.len()), + were = pluralize!("was", remaining_private_fields.len()), + )); + } + let def_id = def.did(); let mut items = self .tcx diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d50ac8dbaa742..6b8dcf1258d45 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -119,6 +119,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => {} } + // Don't emit the lint if we are in an impl marked as `#[automatically_derive]`. + // This is relevant for deriving `Clone` and `PartialEq` on types containing `!`. + if self.tcx.is_automatically_derived(self.tcx.parent(id.owner.def_id.into())) { + return; + } + // Don't warn twice. self.diverges.set(Diverges::WarnedAlways); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index f0cda4493c851..f7fccf6296bd1 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -365,6 +365,7 @@ enum class LLVMRustAttributeKind { CapturesNone = 46, SanitizeRealtimeNonblocking = 47, SanitizeRealtimeBlocking = 48, + Convergent = 49, }; static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { @@ -461,6 +462,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) { return Attribute::SanitizeRealtime; case LLVMRustAttributeKind::SanitizeRealtimeBlocking: return Attribute::SanitizeRealtimeBlocking; + case LLVMRustAttributeKind::Convergent: + return Attribute::Convergent; } report_fatal_error("bad LLVMRustAttributeKind"); } diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index cbe31fd7d1325..bd18a215aea70 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -152,6 +152,7 @@ impl<'tcx> MatchPairTree<'tcx> { } PatKind::Range(ref range) => { + assert_eq!(pattern.ty, range.ty); if range.is_full_range(cx.tcx) == Some(true) { None } else { @@ -380,7 +381,6 @@ impl<'tcx> MatchPairTree<'tcx> { place, testable_case, subpairs, - pattern_ty: pattern.ty, pattern_span: pattern.span, }) } else { diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index d4f5fe84e0ff9..5604e86e06722 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1277,7 +1277,7 @@ enum PatConstKind { /// tested, and a test to perform on that place. /// /// Each node also has a list of subpairs (possibly empty) that must also match, -/// and a reference to the THIR pattern it represents. +/// and some additional information from the THIR pattern it represents. #[derive(Debug, Clone)] pub(crate) struct MatchPairTree<'tcx> { /// This place... @@ -1301,9 +1301,7 @@ pub(crate) struct MatchPairTree<'tcx> { /// that tests its field for the value `3`. subpairs: Vec, - /// Type field of the pattern this node was created from. - pattern_ty: Ty<'tcx>, - /// Span field of the pattern this node was created from. + /// Span field of the THIR pattern this node was created from. pattern_span: Span, } diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index d8911870d3ad4..9b7b6f574fe3f 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -44,10 +44,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TestKind::ScalarEq { value } } - TestableCase::Range(ref range) => { - assert_eq!(range.ty, match_pair.pattern_ty); - TestKind::Range(Arc::clone(range)) - } + TestableCase::Range(ref range) => TestKind::Range(Arc::clone(range)), TestableCase::Slice { len, op } => TestKind::SliceLen { len, op }, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index baabc1afe3fac..b0ccf1f85181d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -532,6 +532,18 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { | hir::MatchSource::AwaitDesugar | hir::MatchSource::FormatArgs => None, }; + + // Check if the match would be exhaustive if all guards were removed. + // If so, we leave a note that guards don't count towards exhaustivity. + let would_be_exhaustive_without_guards = { + let any_arm_has_guard = tarms.iter().any(|arm| arm.has_guard); + any_arm_has_guard && { + let guardless_arms: Vec<_> = + tarms.iter().map(|arm| MatchArm { has_guard: false, ..*arm }).collect(); + rustc_pattern_analysis::rustc::analyze_match(&cx, &guardless_arms, scrut.ty) + .is_ok_and(|report| report.non_exhaustiveness_witnesses.is_empty()) + } + }; self.error = Err(report_non_exhaustive_match( &cx, self.thir, @@ -540,6 +552,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { witnesses, arms, braces_span, + would_be_exhaustive_without_guards, )); } } @@ -1100,8 +1113,7 @@ fn report_arm_reachability<'p, 'tcx>( let arm_span = cx.tcx.hir_span(hir_id); let whole_arm_span = if is_match_arm { // If the arm is followed by a comma, extend the span to include it. - let with_whitespace = sm.span_extend_while_whitespace(arm_span); - if let Some(comma) = sm.span_look_ahead(with_whitespace, ",", Some(1)) { + if let Some(comma) = sm.span_followed_by(arm_span, ",") { Some(arm_span.to(comma)) } else { Some(arm_span) @@ -1154,6 +1166,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( witnesses: Vec>, arms: &[ArmId], braces_span: Option, + would_be_exhaustive_without_guards: bool, ) -> ErrorGuaranteed { let is_empty_match = arms.is_empty(); let non_empty_enum = match scrut_ty.kind() { @@ -1364,8 +1377,7 @@ fn report_non_exhaustive_match<'p, 'tcx>( }, ); - let all_arms_have_guards = arms.iter().all(|arm_id| thir[*arm_id].guard.is_some()); - if !is_empty_match && all_arms_have_guards { + if would_be_exhaustive_without_guards { err.subdiagnostic(NonExhaustiveMatchAllArmsGuarded); } if let Some((span, sugg)) = suggestion { diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index f3415aa47d336..bce298118b7a7 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -72,12 +72,11 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let close_spacing = if let Some(close_delim) = self.token.kind.close_delim() { if close_delim == open_delim { // Correct delimiter. - let (open_delimiter, open_delimiter_span) = - self.diag_info.open_delimiters.pop().unwrap(); + self.diag_info.open_delimiters.pop().unwrap(); let close_delimiter_span = self.token.span; if tts.is_empty() && close_delim == Delimiter::Brace { - let empty_block_span = open_delimiter_span.to(close_delimiter_span); + let empty_block_span = pre_span.to(close_delimiter_span); if !sm.is_multiline(empty_block_span) { // Only track if the block is in the form of `{}`, otherwise it is // likely that it was written on purpose. @@ -86,11 +85,9 @@ impl<'psess, 'src> Lexer<'psess, 'src> { } // only add braces - if let (Delimiter::Brace, Delimiter::Brace) = (open_delimiter, open_delim) { + if Delimiter::Brace == open_delim { // Add all the matching spans, we will sort by span later - self.diag_info - .matching_block_spans - .push((open_delimiter_span, close_delimiter_span)); + self.diag_info.matching_block_spans.push((pre_span, close_delimiter_span)); } // Move past the closing delimiter. diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index 12f653a13371d..6f07e922ceef4 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -495,6 +495,15 @@ impl Slice { other.kind.covers_length(self.arity()) } + // Getters. They are used by rust-analyzer. + pub fn array_len(self) -> Option { + self.array_len + } + + pub fn kind(self) -> SliceKind { + self.kind + } + /// This computes constructor splitting for variable-length slices, as explained at the top of /// the file. /// diff --git a/compiler/rustc_pattern_analysis/src/errors.rs b/compiler/rustc_pattern_analysis/src/errors.rs index 514d1e2a97299..109acf0ec4107 100644 --- a/compiler/rustc_pattern_analysis/src/errors.rs +++ b/compiler/rustc_pattern_analysis/src/errors.rs @@ -1,4 +1,3 @@ -use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; @@ -99,25 +98,17 @@ pub struct ExclusiveRangeMissingGap { pub gap_with: Vec, } +#[derive(Subdiagnostic)] +#[label( + "this could appear to continue range `{$first_range}`, but `{$gap}` isn't matched by either of them" +)] pub struct GappedRange { + #[primary_span] pub span: Span, pub gap: String, // a printed pattern pub first_range: String, // a printed pattern } -impl Subdiagnostic for GappedRange { - fn add_to_diag(self, diag: &mut Diag<'_, G>) { - let GappedRange { span, gap, first_range } = self; - - // FIXME(mejrs) Use `#[subdiagnostic(eager)]` instead - let message = format!( - "this could appear to continue range `{first_range}`, but `{gap}` isn't matched by \ - either of them" - ); - diag.span_label(span, message); - } -} - #[derive(Diagnostic)] #[diag("some variants are not matched explicitly")] #[help("ensure that all variants are matched explicitly by adding the suggested match arms")] diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index b7561d58401ab..95d68e2f8b393 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1467,11 +1467,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // `const name: Ty = expr;`. This is a heuristic, it will // break down in the presence of macros. let sm = self.tcx.sess.source_map(); - let type_span = match sm.span_look_ahead( - original_rib_ident_def.span, - ":", - None, - ) { + let type_span = match sm + .span_followed_by(original_rib_ident_def.span, ":") + { None => { Some(original_rib_ident_def.span.shrink_to_hi()) } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0d4af99c38752..467f03fa46fdd 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1989,10 +1989,25 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // where a brace being opened means a block is being started. Look // ahead for the next text to see if `span` is followed by a `{`. let sm = self.r.tcx.sess.source_map(); - if let Some(followed_brace_span) = sm.span_look_ahead(span, "{", Some(50)) { + if let Some(open_brace_span) = sm.span_followed_by(span, "{") { // In case this could be a struct literal that needs to be surrounded // by parentheses, find the appropriate span. - let close_brace_span = sm.span_look_ahead(followed_brace_span, "}", Some(50)); + let close_brace_span = + sm.span_to_next_source(open_brace_span).ok().and_then(|next_source| { + // Find the matching `}` accounting for nested braces. + let mut depth: u32 = 1; + let offset = next_source.char_indices().find_map(|(i, c)| { + match c { + '{' => depth += 1, + '}' if depth == 1 => return Some(i), + '}' => depth -= 1, + _ => {} + } + None + })?; + let start = open_brace_span.hi() + rustc_span::BytePos(offset as u32); + Some(open_brace_span.with_lo(start).with_hi(start + rustc_span::BytePos(1))) + }); let closing_brace = close_brace_span.map(|sp| span.to(sp)); (true, closing_brace) } else { @@ -4110,8 +4125,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let sugg: String = std::iter::repeat_n(existing_name.as_str(), lt.count) .intersperse(", ") .collect(); - let is_empty_brackets = - source_map.span_look_ahead(lt.span, ">", Some(50)).is_some(); + let is_empty_brackets = source_map.span_followed_by(lt.span, ">").is_some(); let sugg = if is_empty_brackets { sugg } else { format!("{sugg}, ") }; (lt.span.shrink_to_hi(), sugg) } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index ec335e7b43390..a42d4e0d05557 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -964,21 +964,13 @@ impl SourceMap { Span::new(BytePos(start_of_next_point), end_of_next_point, sp.ctxt, None) } - /// Check whether span is followed by some specified expected string in limit scope - pub fn span_look_ahead(&self, span: Span, expect: &str, limit: Option) -> Option { - let mut sp = span; - for _ in 0..limit.unwrap_or(100_usize) { - sp = self.next_point(sp); - if let Ok(ref snippet) = self.span_to_snippet(sp) { - if snippet == expect { - return Some(sp); - } - if snippet.chars().any(|c| !c.is_whitespace()) { - break; - } - } - } - None + /// Check whether span is followed by some specified target string, ignoring whitespace. + /// *Only suitable for diagnostics.* + pub fn span_followed_by(&self, span: Span, target: &str) -> Option { + let span = self.span_extend_while_whitespace(span); + self.span_to_next_source(span).ok()?.strip_prefix(target).map(|_| { + Span::new(span.hi(), span.hi() + BytePos(target.len() as u32), span.ctxt(), None) + }) } /// Finds the width of the character, either before or after the end of provided span, diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index 16d28f393d7f2..4cc243667f224 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -752,6 +752,25 @@ fn test_next_point() { assert!(sm.span_to_snippet(span).is_err()); } +#[test] +fn test_span_followed_by_stops_at_end_of_file() { + let sm = SourceMap::new(FilePathMapping::empty()); + sm.new_source_file(filename(&sm, "example.rs"), "x".to_string()); + + let span = Span::with_root_ctxt(BytePos(0), BytePos(1)); + assert_eq!(sm.span_followed_by(span, "y"), None); +} + +#[test] +fn test_span_followed_by_skips_whitespace() { + let sm = SourceMap::new(FilePathMapping::empty()); + sm.new_source_file(filename(&sm, "example.rs"), "x \n yz".to_string()); + + let span = Span::with_root_ctxt(BytePos(0), BytePos(1)); + let span = sm.span_followed_by(span, "yz").unwrap(); + assert_eq!(sm.span_to_snippet(span), Ok("yz".to_string())); +} + #[cfg(target_os = "linux")] #[test] fn read_binary_file_handles_lying_stat() { diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 643eeaa00ce7b..1c84e92b662ea 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -623,7 +623,7 @@ impl InlineAsmRegClass { Self::Hexagon(r) => r.supported_types(arch), Self::LoongArch(r) => r.supported_types(arch), Self::Mips(r) => r.supported_types(arch), - Self::S390x(r) => r.supported_types(arch, allow_experimental_reg), + Self::S390x(r) => r.supported_types(arch), Self::Sparc(r) => r.supported_types(arch), Self::SpirV(r) => r.supported_types(arch), Self::Wasm(r) => r.supported_types(arch), diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 37176c0d73eaf..cd4f54f823ece 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -38,22 +38,14 @@ impl S390xInlineAsmRegClass { pub fn supported_types( self, _arch: InlineAsmArch, - allow_experimental_reg: bool, ) -> &'static [(InlineAsmType, Option)] { match self { Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; }, Self::freg => types! { _: F16, F32, F64; }, - Self::vreg => { - if allow_experimental_reg { - // non-clobber-only vector register support is unstable. - types! { - vector: I32, F16, F32, I64, F64, I128, F128, - VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2); - } - } else { - &[] - } - } + Self::vreg => types! { + vector: I32, F16, F32, I64, F64, I128, F128, + VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2); + }, Self::areg => &[], } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index da6552b7df64f..5e7a59bd7ae8e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -459,7 +459,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (cand.self_ty().kind(), main_trait_predicate.self_ty().skip_binder().kind()) { // Wrap method receivers and `&`-references in parens - let suggestion = if self.tcx.sess.source_map().span_look_ahead(span, ".", Some(50)).is_some() { + let suggestion = if self.tcx.sess.source_map().span_followed_by(span, ".").is_some() { vec![ (span.shrink_to_lo(), format!("(")), (span.shrink_to_hi(), format!(" as {})", cand.self_ty())), diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index e7278c662a779..1ca0aa3bab199 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -603,6 +603,9 @@ fn receiver_for_self_ty<'tcx>( /// contained by the trait object, because the object that needs to be coerced is behind /// a pointer. /// +/// If lowering already produced an error in the receiver type, we conservatively treat it as +/// undispatchable instead of asking the solver. +/// /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in /// a new check that `Trait` is dyn-compatible, creating a cycle. /// Instead, we emulate a placeholder by introducing a new type parameter `U` such that @@ -630,6 +633,10 @@ fn receiver_is_dispatchable<'tcx>( ) -> bool { debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty); + if receiver_ty.references_error() { + return false; + } + let (Some(unsize_did), Some(dispatch_from_dyn_did)) = (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait()) else { diff --git a/library/core/src/field.rs b/library/core/src/field.rs index e8ef309b9c84f..0e537e2f92fcf 100644 --- a/library/core/src/field.rs +++ b/library/core/src/field.rs @@ -8,7 +8,10 @@ use crate::marker::PhantomData; #[expect(missing_debug_implementations)] #[fundamental] pub struct FieldRepresentingType { - _phantom: PhantomData, + // We want this type to be invariant over `T`, because otherwise `field_of!(Struct<'short>, + // field)` is a subtype of `field_of!(Struct<'long>, field)`. This subtype relationship does not + // have an immediately obvious meaning and we want to prevent people from relying on it. + _phantom: PhantomData T>, } // SAFETY: `FieldRepresentingType` doesn't contain any `T` diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 9f7ac7da2dbda..ce80874a23897 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -1,3 +1,4 @@ +use crate::marker::Destruct; use crate::num::NonZero; use crate::ops::{ControlFlow, Try}; @@ -38,7 +39,8 @@ use crate::ops::{ControlFlow, Try}; /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "DoubleEndedIterator"] -pub trait DoubleEndedIterator: Iterator { +#[rustc_const_unstable(feature = "const_iter", issue = "92476")] +pub const trait DoubleEndedIterator: [const] Iterator { /// Removes and returns an element from the end of the iterator. /// /// Returns `None` when there are no more elements. @@ -135,6 +137,7 @@ pub trait DoubleEndedIterator: Iterator { /// [`Err(k)`]: Err #[inline] #[unstable(feature = "iter_advance_by", issue = "77404")] + #[rustc_non_const_trait_method] fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { for i in 0..n { if self.next_back().is_none() { @@ -188,6 +191,7 @@ pub trait DoubleEndedIterator: Iterator { /// ``` #[inline] #[stable(feature = "iter_nth_back", since = "1.37.0")] + #[rustc_non_const_trait_method] fn nth_back(&mut self, n: usize) -> Option { if self.advance_back_by(n).is_err() { return None; @@ -230,8 +234,8 @@ pub trait DoubleEndedIterator: Iterator { fn try_rfold(&mut self, init: B, mut f: F) -> R where Self: Sized, - F: FnMut(B, Self::Item) -> R, - R: Try, + F: [const] FnMut(B, Self::Item) -> R + [const] Destruct, + R: [const] Try, { let mut accum = init; while let Some(x) = self.next_back() { @@ -300,8 +304,8 @@ pub trait DoubleEndedIterator: Iterator { #[stable(feature = "iter_rfold", since = "1.27.0")] fn rfold(mut self, init: B, mut f: F) -> B where - Self: Sized, - F: FnMut(B, Self::Item) -> B, + Self: Sized + [const] Destruct, + F: [const] FnMut(B, Self::Item) -> B + [const] Destruct, { let mut accum = init; while let Some(x) = self.next_back() { @@ -363,6 +367,7 @@ pub trait DoubleEndedIterator: Iterator { /// ``` #[inline] #[stable(feature = "iter_rfind", since = "1.27.0")] + #[rustc_non_const_trait_method] fn rfind

(&mut self, predicate: P) -> Option where Self: Sized, diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index fd21b149db8f1..0a2cfd1c85985 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml @@ -12,6 +12,7 @@ jobs: uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main with: github-app-id: ${{ vars.APP_CLIENT_ID }} + pr-author: "workflows-rustc-dev-guide[bot]" zulip-stream-id: 196385 zulip-bot-email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com" pr-base-branch: main diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index a51e46f6191a3..ac3099d845931 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -562dee4820c458d823175268e41601d4c060588a +30d0309fa821f7a0984a9629e0d227ca3c0d2eda diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 22f4da50b62c3..9a9861186011d 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -72,6 +72,7 @@ - [WASI](notification-groups/wasi.md) - [WebAssembly](notification-groups/wasm.md) - [Windows](notification-groups/windows.md) + - [GPU target](notification-groups/gpu-target.md) - [Licenses](./licenses.md) - [Editions](guides/editions.md) @@ -100,9 +101,9 @@ - [Parallel compilation](./parallel-rustc.md) - [Rustdoc internals](./rustdoc-internals.md) - [Search](./rustdoc-internals/search.md) - - [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md) - - [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md) - - [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md) + - [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md) + - [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md) + - [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md) - [GPU offload internals](./offload/internals.md) - [Installation](./offload/installation.md) - [Usage](./offload/usage.md) @@ -189,6 +190,7 @@ - [Significant changes and quirks](./solve/significant-changes.md) - [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md) - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md) + - [Having separate `Trait` and `Projection` bounds](./traits/separate-projection-bounds.md) - [Variance](./variance.md) - [Coherence checking](./coherence.md) - [HIR Type checking](./hir-typeck/summary.md) diff --git a/src/doc/rustc-dev-guide/src/appendix/code-index.md b/src/doc/rustc-dev-guide/src/appendix/code-index.md index 3e1eed17eba64..25c770d4fbe8c 100644 --- a/src/doc/rustc-dev-guide/src/appendix/code-index.md +++ b/src/doc/rustc-dev-guide/src/appendix/code-index.md @@ -1,15 +1,15 @@ # Code Index -rustc has a lot of important data structures. This is an attempt to give some -guidance on where to learn more about some of the key data structures of the -compiler. +rustc has a lot of important data structures. +This is an attempt to give some guidance on where to learn more +about some of the key data structures of the compiler. Item | Kind | Short description | Chapter | Declaration ----------------|----------|-----------------------------|--------------------|------------------- `BodyId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.BodyId.html) `Compiler` | struct | Represents a compiler session and can be used to drive a compilation. | [The Rustc Driver and Interface] | [compiler/rustc_interface/src/interface.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Compiler.html) `ast::Crate` | struct | A syntax-level representation of a parsed crate | [The parser] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.Crate.html) -`rustc_hir::Crate` | struct | A more abstract, compiler-friendly form of a crate's AST | [The Hir] | [compiler/rustc_hir/src/hir.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Crate.html) +`hir::Crate` | struct | A more abstract, compiler-friendly form of a crate's AST | [The Hir] | [compiler/rustc_middle/src/hir/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/struct.Crate.html) `DefId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/def_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html) `Diag` | struct | A struct for a compiler diagnostic, such as an error or lint | [Emitting Diagnostics] | [compiler/rustc_errors/src/diagnostic.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html) `DocContext` | struct | A state container used by rustdoc when crawling through a crate to gather its documentation | [Rustdoc] | [src/librustdoc/core.rs](https://github.com/rust-lang/rust/blob/HEAD/src/librustdoc/core.rs) diff --git a/src/doc/rustc-dev-guide/src/appendix/glossary.md b/src/doc/rustc-dev-guide/src/appendix/glossary.md index 43935b12a2383..30959f4b39e6f 100644 --- a/src/doc/rustc-dev-guide/src/appendix/glossary.md +++ b/src/doc/rustc-dev-guide/src/appendix/glossary.md @@ -1,17 +1,22 @@ # Glossary -Term | Meaning -------------------------------------------------------|-------- +Term | Meaning +-----------------------------------------------|-------- +1-ZST | A *one-aligned [zero-sized type](#zst)*. A type of size zero with an [alignment][size-align] of one. arena, arena allocation | An _arena_ is a large memory buffer from which other memory allocations are made. This style of allocation is called _arena allocation_. See [this chapter](../memory.md) for more info. -AST | The _abstract syntax tree_ produced by the `rustc_ast` crate; reflects user syntax very closely. -APIT | An argument-position `impl Trait`. Also known as an anonymous type parameter. ([see the reference](https://doc.rust-lang.org/reference/types/impl-trait.html#anonymous-type-parameters)). -binder | A _binder_ is a place where a variable or type is declared; for example, the `` is a binder for the generic type parameter `T` in `fn foo(..)`, and \|`a`\|` ...` is a binder for the parameter `a`. See [the background chapter for more](./background.md#free-vs-bound). -`BodyId` | An identifier that refers to a specific body (definition of a function or constant) in the crate. See [the HIR chapter for more](../hir.md#identifiers-in-the-hir). -bound variable | A _bound variable_ is one that is declared within an expression/term. For example, the variable `a` is bound within the closure expression \|`a`\|` a * 2`. See [the background chapter for more](./background.md#free-vs-bound) +AFIDT | Short for _async function in `dyn Trait`_. See also [AFIT](#afit). +AFIT | Short for _async function in trait_. They desugar to [RPITITs](#rpitit). +AST | The _abstract syntax tree_ (an [IR](#ir)) produced by the parser; reflects the surface / user syntax very closely. +APIT | Short for _argument-position `impl Trait`_. Also known as universial `impl Trait` (as opposed to existential) or anonymous type parameter. ([see the reference](https://doc.rust-lang.org/reference/types/impl-trait.html#anonymous-type-parameters)). +ATPIT | Short for _associated-type-position `impl Trait`_. Also known as [ITIAT](#itiat). +binder | A _binder_ is a place where a variable or type is declared; for example, the `` is a binder for the type parameter `T` in `fn foo(..)`, `for<'a>` is a binder for the lifetime parameter `'a` and `\|a\| …` is a binder for the parameter `a`. See [the background chapter for more](./background.md#free-vs-bound). +body | The definition of a function or constant that contains "executable code". +`BodyId` | An identifier that refers to a specific [body](#body) in the crate. See [the HIR chapter for more](../hir.md#identifiers-in-the-hir). +bound variable | A _bound variable_ is one that is declared within an expression or term (in the general sense). For example, the variable `a` is bound within the closure expression `\|a\| a * 2` and lifetime variable `'a` is bound within the type expression `for<'a> fn(&'a str) -> bool`. See [the background chapter for more](./background.md#free-vs-bound) codegen | Short for _code generation_. The code to translate MIR into LLVM IR. codegen unit | When we produce LLVM IR, we group the Rust code into a number of codegen units (sometimes abbreviated as CGUs). Each of these units is processed by LLVM independently from one another, enabling parallelism. They are also the unit of incremental re-use. ([see more](../backend/codegen.md)) completeness | A technical term in type theory, it means that every type-safe program also type-checks. Having both soundness and completeness is very hard, and usually soundness is more important. (see "soundness"). -control-flow graph | A representation of the control-flow of a program; see [the background chapter for more](./background.md#cfg) +control-flow graph, CFG | A representation of the control-flow of a program; see [the background chapter for more](./background.md#cfg) CTFE | Short for _compile-time function evaluation_, this is the ability of the compiler to evaluate `const fn`s at compile time. This is part of the compiler's constant evaluation system. ([see more](../const-eval.md)) `cx` | We tend to use _cx_ as an abbreviation for _context_. See also `tcx`, `infcx`, etc. `ctxt` | We also use _ctxt_ as an abbreviation for _context_, e.g. [`TyCtxt`](#TyCtxt). See also [cx](#cx) or [tcx](#tcx). @@ -23,14 +28,18 @@ Term | Meaning double pointer | A pointer with additional metadata. See [fat pointer](#fat-ptr) for more. drop glue | (Internal) compiler-generated instructions that handle calling the destructors (`Drop`) for data types. DST | Short for *dynamically-sized type*, this is a type for which the compiler cannot statically know the size in memory (e.g. `str` or `[u8]`). Such types don't implement `Sized` and cannot be allocated on the stack. They can only occur as the last field in a struct. They can only be used behind a pointer (e.g. `&str` or `&[u8]`). -early-bound lifetime | A lifetime region that is substituted at its definition site. Bound in an item's `Generics` and substituted/instantiated using a `GenericArgs`. Contrast with **late-bound lifetime**. ([see more](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/region_kind/enum.RegionKind.html#bound-regions)) +early-bound lifetime | A lifetime / region that is substituted at its definition site. Bound in an item's `Generics` and substituted/instantiated using a `GenericArgs`. Contrast with **late-bound lifetime**. ([see more](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/region_kind/enum.RegionKind.html#bound-regions)) effects | Right now only means const traits and `~const` bounds. ([see more](../effects.md)) empty type | See [uninhabited type](#ut). fat pointer | A two word value carrying the address of some value, along with some further information necessary to put the value to use. Rust includes two kinds of _fat pointers_: references to slices, and trait objects. A reference to a slice carries the starting address of the slice and its length. A trait object carries a value's address and a pointer to the trait's implementation appropriate to that value. "Fat pointers" are also known as "wide pointers", and "double pointers". -free variable | A _free variable_ is one that is not bound within an expression or term; see [the background chapter for more](./background.md#free-vs-bound) +free variable | A _free variable_ is one that is not bound within an expression or term (in the general sense); see [the background chapter for more](./background.md#free-vs-bound) +GAC | A _generic associated constant_, an associated constant with (own) generic parameters or a where-clause. Part of feature [`generic_const_items`] (GCI). +GAT | A _generic associated type_, an associated type that has (own) generic parameters or a where-clause. Introduced in [RFC 1598]. generics | The list of generic parameters defined on an item. There are three kinds of generic parameters: Type, lifetime and const parameters. -HIR | The _high-level [IR](#ir)_, created by lowering and desugaring the AST. ([see more](../hir.md)) +HIR | The _high-level [IR](#ir)_, created by lowering / desugaring the AST. ([see more](../hir.md)) `HirId` | Identifies a particular node in the HIR by combining a def-id with an "intra-definition offset". See [the HIR chapter for more](../hir.md#identifiers-in-the-hir). +IAC | A (more often than not type-level) _inherent associated constant_, an associated constant in an inherent impl `impl Type { … }`. Often mentioned in the context of feature [`min_generic_const_items`] (mGCA, MGCA). An IGAC is an inherent [GAC](#gac). +IAT | An _inherent associated type_, an associated type defined in an inherent impl `impl Type { … }`. An IGAT is an inherent [GAT](#gat), a generic IAT. ICE | Short for _internal compiler error_, this is when the compiler crashes. ICH | Short for _incremental compilation hash_, these are used as fingerprints for things such as HIR and crate metadata, to check if changes have been made. This is useful in incremental compilation to see if part of a crate has changed and should be recompiled. `infcx` | The type inference context (`InferCtxt`). (see `rustc_middle::infer`) @@ -41,12 +50,17 @@ Term | Meaning IR | Short for _intermediate representation_, a general term in compilers. During compilation, the code is transformed from raw source (ASCII text) to various IRs. In Rust, these are primarily HIR, MIR, and LLVM IR. Each IR is well-suited for some set of computations. For example, MIR is well-suited for the borrow checker, and LLVM IR is well-suited for codegen because LLVM accepts it. IRLO, irlo | Sometimes used as an abbreviation for [internals.rust-lang.org](https://internals.rust-lang.org). item | A kind of "definition" in the language, such as a static, const, use statement, module, struct, etc. Concretely, this corresponds to the `Item` type. +item signature | The type signature / annotation / ascription of an item (e.g., struct, function). Often mentioned in the context of type inference since they are a place where we don't perform inference contrary to types in [bodies](#body). +ITIAT | Short for _`impl Trait` in associated type_. Also known as [ATPIT](#atpit). lang item | Items that represent concepts intrinsic to the language itself, such as special built-in traits like `Sync` and `Send`; or traits representing operations such as `Add`; or functions that are called by the compiler. ([see more](https://doc.rust-lang.org/1.9.0/book/lang-items.html)) -late-bound lifetime | A lifetime region that is substituted at its call site. Bound in a HRTB and substituted by specific functions in the compiler, such as `liberate_late_bound_regions`. Contrast with **early-bound lifetime**. ([see more](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/region_kind/enum.RegionKind.html#bound-regions)) +late-bound lifetime | A lifetime / region that is substituted at its call site. Bound in a HRTB and substituted by specific functions in the compiler, such as `liberate_late_bound_regions`. Contrast with **early-bound lifetime**. ([see more](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/region_kind/enum.RegionKind.html#bound-regions)) local crate | The crate currently being compiled. This is in contrast to "upstream crates" which refer to dependencies of the local crate. +lowering | The act of converting a higher-level [IR](#ir) to a lower-level one. E.g., AST lowering (from [AST](#ast) to [HIR](#hir)) or HIR ty lowering (from HIR to [middle ty IR](#middle-ty-ir)). +LTA | A _lazy type alias_, a type alias that gets "properly" represented as an alias in the [middle ty IR](#middle-ty-ir); contrary to (eager) type aliases whose reference sites get expanded to the underlying aliased type (the RHS of the type alias after instantiation) during HIR ty lowering, its reference sites get [lowered](#lowering) to an [`AliasTy`]. LTO | Short for *link-time optimizations*, this is a set of optimizations offered by LLVM that occur just before the final binary is linked. These include optimizations like removing functions that are never used in the final program, for example. _ThinLTO_ is a variant of LTO that aims to be a bit more scalable and efficient, but possibly sacrifices some optimizations. You may also read issues in the Rust repo about "FatLTO", which is the loving nickname given to non-Thin LTO. LLVM documentation: [here][lto] and [here][thinlto]. [LLVM] | (actually not an acronym :P) an open-source compiler backend. It accepts LLVM IR and outputs native binaries. Various languages (e.g. Rust) can then implement a compiler front-end that outputs LLVM IR and use LLVM to compile to all the platforms LLVM supports. memoization | The process of storing the results of (pure) computations (such as pure function calls) to avoid having to repeat them in the future. This is typically a trade-off between execution speed and memory usage. +middle ty IR | The collection of types defined in module [`rustc_middle::ty`] used by the type checker and the trait solver. They essentially form an [IR](#ir). MIR | The _mid-level [IR](#ir)_ that is created after type-checking for use by borrowck and codegen. ([see more](../mir/index.md)) Miri | A tool to detect Undefined Behavior in (unsafe) Rust code. ([see more](https://github.com/rust-lang/miri)) monomorphization | The process of taking generic implementations of types and functions and instantiating them with concrete types. For example, in the code we might have `Vec`, but in the final executable, we will have a copy of the `Vec` code for every concrete type used in the program (e.g. a copy for `Vec`, a copy for `Vec`, etc). @@ -66,39 +80,49 @@ Term | Meaning recovery | Recovery refers to handling invalid syntax during parsing (e.g. a missing comma) and continuing to parse the AST. This avoid showing spurious errors to the user (e.g. showing 'missing field' errors when the struct definition contains errors). region | Another term for "lifetime" often used in the literature and in the borrow checker. rib | A data structure in the name resolver that keeps track of a single scope for names. ([see more](../name-resolution.md)) -RPIT | A return-position `impl Trait`. ([see the reference](https://doc.rust-lang.org/reference/types/impl-trait.html#abstract-return-types)). -RPITIT | A return-position `impl Trait` in trait. Unlike RPIT, this is desugared to a generic associated type (GAT). Introduced in [RFC 3425](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html). ([see more](../return-position-impl-trait-in-trait.md)) -rustbuild | A deprecated term for the part of bootstrap that is written in Rust +RPIT | Short for _return-position `impl Trait`_. An existential `impl Trait` (as opposed to universial) like [TAITs](#tait) and [ATPIT](#atpit). ([see the reference](https://doc.rust-lang.org/reference/types/impl-trait.html#abstract-return-types)). +RPITIT | Short for _return-position `impl Trait` in trait_. Unlike [RPIT](#rpit), this is desugared to a generic associated type ([GAT](#gat)). Introduced in [RFC 3425]. ([see more](../return-position-impl-trait-in-trait.md)) +rustbuild 👎 | A **deprecated** term for the part of bootstrap that is written in Rust scrutinee | A scrutinee is the expression that is matched on in `match` expressions and similar pattern matching constructs. For example, in `match x { A => 1, B => 2 }`, the expression `x` is the scrutinee. `sess` | The compiler _session_, which stores global data used throughout compilation side tables | Because the [AST](#ast) and HIR are immutable once created, we often carry extra information about them in the form of hashtables, indexed by the id of a particular node. sigil | Like a keyword but composed entirely of non-alphanumeric tokens. For example, `&` is a sigil for references. soundness | A technical term in type theory. Roughly, if a type system is sound, then a program that type-checks is type-safe. That is, one can never (in safe rust) force a value into a variable of the wrong type. (see "completeness"). span | A location in the user's source code, used for error reporting primarily. These are like a file-name/line-number/column tuple on steroids: they carry a start/end point, and also track macro expansions and compiler desugaring. All while being packed into a few bytes (really, it's an index into a table). See the [`Span`] datatype for more. -subst | The act of _substituting_ the generic parameters inside of a type, constant expression, etc. with concrete generic arguments by supplying [substs](#substs). Nowadays referred to as _instantiating_ in the compiler. -substs | The _substitutions_ for a given generic item (e.g. the `i32`, `u32` in `HashMap`). Nowadays referred to as the list of _generic arguments_ in the compiler (but note that strictly speaking these two concepts differ, see the literature). +subst 👎 | The act of _substituting_ the generic parameters inside of a type, constant expression, etc. with concrete generic arguments by supplying [substs](#substs). Nowadays referred to as _instantiating_ in the compiler. +substs 👎 | The _substitutions_ for a given generic item (e.g. the `i32`, `u32` in `HashMap`). Nowadays referred to as the list of _generic arguments_ in the compiler (but note that strictly speaking these two concepts differ, see the literature). sysroot | The directory for build artifacts that are loaded by the compiler at runtime. ([see more](../building/bootstrapping/what-bootstrapping-does.html#what-is-a-sysroot)) tag | The "tag" of an enum/generator encodes the [discriminant](#discriminant) of the active variant/state. Tags can either be "direct" (simply storing the discriminant in a field) or use a ["niche"](#niche). -TAIT | A type-alias `impl Trait`. Introduced in [RFC 2515](https://rust-lang.github.io/rfcs/2515-type_alias_impl_trait.html). +TAIT | Short for _type-alias `impl Trait`_. Introduced in [RFC 2515]. `tcx` | Standard variable name for the "typing context" (`TyCtxt`), main data structure of the compiler. ([see more](../ty.md)) `'tcx` | The lifetime of the allocation arenas used by `TyCtxt`. Most data interned during a compilation session will use this lifetime with the exception of HIR data which uses the `'hir` lifetime. ([see more](../ty.md)) token | The smallest unit of parsing. Tokens are produced after lexing ([see more](../the-parser.md)). -[TLS] | *Thread-local storage*. Variables may be defined so that each thread has its own copy (rather than all threads sharing the variable). This has some interactions with LLVM. Not all platforms support TLS. +[TLS] | _Thread-local storage_. Variables may be defined so that each thread has its own copy (rather than all threads sharing the variable). This has some interactions with LLVM. Not all platforms support TLS. trait reference, trait ref | The name of a trait along with a suitable list of generic arguments. ([see more](../traits/goals-and-clauses.md#trait-ref)) -trans | Short for _translation_, the code to translate MIR into LLVM IR. Renamed to [codegen](#codegen). +trans 👎 | Short for _translation_, the code to translate MIR into LLVM IR. **Renamed to** [codegen](#codegen). `Ty` | The internal representation of a type. ([see more](../ty.md)) `TyCtxt` | The data structure often referred to as [`tcx`](#tcx) in code which provides access to session data and the query system. -UFCS | Short for _universal function call syntax_, this is an unambiguous syntax for calling a method. **Term no longer in use!** Prefer _fully-qualified path/syntax_. ([see more](../hir-typeck/summary.md), [see the reference](https://doc.rust-lang.org/reference/expressions/call-expr.html#disambiguating-function-calls)) +UFCS 👎 | Short for _universal function call syntax_, this is an unambiguous syntax for calling a method. **Term no longer in use!** Prefer _fully-qualified path / syntax_. ([see more](../hir-typeck/summary.md), [see the reference](https://doc.rust-lang.org/reference/expressions/call-expr.html#disambiguating-function-calls)) uninhabited type | A type which has _no_ values. This is not the same as a ZST, which has exactly 1 value. An example of an uninhabited type is `enum Foo {}`, which has no variants, and so, can never be created. The compiler can treat code that deals with uninhabited types as dead code, since there is no such value to be manipulated. `!` (the never type) is an uninhabited type. Uninhabited types are also called _empty types_. upvar | A variable captured by a closure from outside the closure. variance | Determines how changes to a generic parameter affect subtyping; for example, if `T` is a subtype of `U`, then `Vec` is a subtype `Vec` because `Vec` is _covariant_ in its generic parameter. See [the background chapter](./background.md#variance) for a more general explanation. See the [variance chapter](../variance.md) for an explanation of how type checking handles variance. variant index | In an enum, identifies a variant by assigning them indices starting at 0. This is purely internal and not to be confused with the ["discriminant"](#discriminant) which can be overwritten by the user (e.g. `enum Bool { True = 42, False = 0 }`). -well-formedness | Semantically: An expression that evaluates to meaningful result. In type systems: A type related construct which follows rules of the type system. +well-formedness, wfness, wf | Semantically: An expression that evaluates to meaningful result. In type systems: A type related construct which follows rules of the type system. wide pointer | A pointer with additional metadata. See [fat pointer](#fat-ptr) for more. ZST | *Zero-sized type*. A type whose values have size 0 bytes. Since `2^0 = 1`, such types can have exactly one value. For example, `()` (unit) is a ZST. `struct Foo;` is also a ZST. The compiler can do some nice optimizations around ZSTs. +See also . + [LLVM]: https://llvm.org/ -[lto]: https://llvm.org/docs/LinkTimeOptimization.html +[RFC 1598]: https://rust-lang.github.io/rfcs/1598-generic_associated_types.html +[RFC 2515]: https://rust-lang.github.io/rfcs/2515-type_alias_impl_trait.html +[RFC 3425]: https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html +[TLS]: https://llvm.org/docs/LangRef.html#thread-local-storage-models +[`AliasTy`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.AliasTy.html [`Span`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html +[`generic_const_items`]: https://github.com/rust-lang/rust/issues/113521 +[`min_generic_const_items`]: https://github.com/rust-lang/rust/issues/132980 +[`rustc_middle::ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html +[lto]: https://llvm.org/docs/LinkTimeOptimization.html +[size-align]: https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment [thinlto]: https://clang.llvm.org/docs/ThinLTO.html -[TLS]: https://llvm.org/docs/LangRef.html#thread-local-storage-models diff --git a/src/doc/rustc-dev-guide/src/const-eval/interpret.md b/src/doc/rustc-dev-guide/src/const-eval/interpret.md index 8487b2bed43ab..0462876ef359c 100644 --- a/src/doc/rustc-dev-guide/src/const-eval/interpret.md +++ b/src/doc/rustc-dev-guide/src/const-eval/interpret.md @@ -1,8 +1,9 @@ # Interpreter The interpreter is a virtual machine for executing MIR without compiling to -machine code. It is usually invoked via `tcx.const_eval_*` functions. The -interpreter is shared between the compiler (for compile-time function +machine code. +It is usually invoked via `tcx.const_eval_*` functions. +The interpreter is shared between the compiler (for compile-time function evaluation, CTFE) and the tool [Miri](https://github.com/rust-lang/miri/), which uses the same virtual machine to detect Undefined Behavior in (unsafe) Rust code. @@ -26,7 +27,8 @@ The compiler needs to figure out the length of the array before being able to create items that use the type (locals, constants, function arguments, ...). To obtain the (in this case empty) parameter environment, one can call -`let param_env = tcx.param_env(length_def_id);`. The `GlobalId` needed is +`let param_env = tcx.param_env(length_def_id);`. +The `GlobalId` needed is ```rust,ignore let gid = GlobalId { @@ -36,7 +38,8 @@ let gid = GlobalId { ``` Invoking `tcx.const_eval(param_env.and(gid))` will now trigger the creation of -the MIR of the array length expression. The MIR will look something like this: +the MIR of the array length expression. +The MIR will look something like this: ```mir Foo::{{constant}}#0: usize = { @@ -59,37 +62,45 @@ Before the evaluation, a virtual memory location (in this case essentially a `vec![u8; 4]` or `vec![u8; 8]`) is created for storing the evaluation result. At the start of the evaluation, `_0` and `_1` are -`Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef))`. This is quite +`Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef))`. +This is quite a mouthful: [`Operand`] can represent either data stored somewhere in the [interpreter memory](#memory) (`Operand::Indirect`), or (as an optimization) -immediate data stored in-line. And [`Immediate`] can either be a single +immediate data stored in-line. +And [`Immediate`] can either be a single (potentially uninitialized) [scalar value][`Scalar`] (integer or thin pointer), -or a pair of two of them. In our case, the single scalar value is *not* (yet) -initialized. +or a pair of two of them. +In our case, the single scalar value is *not* (yet) initialized. When the initialization of `_1` is invoked, the value of the `FOO` constant is required, and triggers another call to `tcx.const_eval_*`, which will not be shown -here. If the evaluation of FOO is successful, `42` will be subtracted from its +here. +If the evaluation of FOO is successful, `42` will be subtracted from its value `4096` and the result stored in `_1` as `Operand::Immediate(Immediate::ScalarPair(Scalar::Raw { data: 4054, .. }, -Scalar::Raw { data: 0, .. })`. The first part of the pair is the computed value, -the second part is a bool that's true if an overflow happened. A `Scalar::Raw` +Scalar::Raw { data: 0, .. })`. +The first part of the pair is the computed value, +the second part is a bool that's true if an overflow happened. +A `Scalar::Raw` also stores the size (in bytes) of this scalar value; we are eliding that here. -The next statement asserts that said boolean is `0`. In case the assertion +The next statement asserts that said boolean is `0`. +In case the assertion fails, its error message is used for reporting a compile-time error. Since it does not fail, `Operand::Immediate(Immediate::Scalar(Scalar::Raw { data: 4054, .. }))` is stored in the virtual memory it was allocated before the -evaluation. `_0` always refers to that location directly. +evaluation. +`_0` always refers to that location directly. After the evaluation is done, the return value is converted from [`Operand`] to [`ConstValue`] by [`op_to_const`]: the former representation is geared towards what is needed *during* const evaluation, while [`ConstValue`] is shaped by the needs of the remaining parts of the compiler that consume the results of const -evaluation. As part of this conversion, for types with scalar values, even if +evaluation. +As part of this conversion, for types with scalar values, even if the resulting [`Operand`] is `Indirect`, it will return an immediate -`ConstValue::Scalar(computed_value)` (instead of the usual `ConstValue::ByRef`). +`ConstValue::Scalar(computed_value)` (instead of the usual `ConstValue::Indirect`). This makes using the result much more efficient and also more convenient, as no further queries need to be executed in order to get at something as simple as a `usize`. @@ -107,12 +118,13 @@ the interpreter, but just use the cached result. The interpreter's outside-facing datastructures can be found in [rustc_middle/src/mir/interpret](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_middle/src/mir/interpret). -This is mainly the error enum and the [`ConstValue`] and [`Scalar`] types. A -`ConstValue` can be either `Scalar` (a single `Scalar`, i.e., integer or thin +This is mainly the error enum and the [`ConstValue`] and [`Scalar`] types. +A `ConstValue` can be either `Scalar` (a single `Scalar`, i.e., integer or thin pointer), `Slice` (to represent byte slices and strings, as needed for pattern -matching) or `ByRef`, which is used for anything else and refers to a virtual -allocation. These allocations can be accessed via the methods on -`tcx.interpret_interner`. A `Scalar` is either some `Raw` integer or a pointer; +matching) or `Indirect`, which is used for anything else and refers to a virtual +allocation. +These allocations can be accessed via the methods on `tcx.interpret_interner`. +A `Scalar` is either some `Raw` integer or a pointer; see [the next section](#memory) for more on that. If you are expecting a numeric result, you can use `eval_usize` (panics on @@ -122,29 +134,38 @@ in an `Option` yielding the `Scalar` if possible. ## Memory To support any kind of pointers, the interpreter needs to have a "virtual memory" that the -pointers can point to. This is implemented in the [`Memory`] type. In the -simplest model, every global variable, stack variable and every dynamic -allocation corresponds to an [`Allocation`] in that memory. (Actually using an +pointers can point to. +This is implemented in the [`Memory`] type. +In the simplest model, every global variable, stack variable and every dynamic +allocation corresponds to an [`Allocation`] in that memory. +(Actually using an allocation for every MIR stack variable would be very inefficient; that's why we have `Operand::Immediate` for stack variables that are both small and never have -their address taken. But that is purely an optimization.) +their address taken. +But that is purely an optimization.) Such an `Allocation` is basically just a sequence of `u8` storing the value of -each byte in this allocation. (Plus some extra data, see below.) Every -`Allocation` has a globally unique `AllocId` assigned in `Memory`. With that, a +each byte in this allocation. +(Plus some extra data, see below.) Every +`Allocation` has a globally unique `AllocId` assigned in `Memory`. +With that, a [`Pointer`] consists of a pair of an `AllocId` (indicating the allocation) and an offset into the allocation (indicating which byte of the allocation the -pointer points to). It may seem odd that a `Pointer` is not just an integer +pointer points to). +It may seem odd that a `Pointer` is not just an integer address, but remember that during const evaluation, we cannot know at which actual integer address the allocation will end up -- so we use `AllocId` as -symbolic base addresses, which means we need a separate offset. (As an aside, +symbolic base addresses, which means we need a separate offset. +(As an aside, it turns out that pointers at run-time are [more than just integers, too](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#pointer-provenance).) These allocations exist so that references and raw pointers have something to -point to. There is no global linear heap in which things are allocated, but each +point to. +There is no global linear heap in which things are allocated, but each allocation (be it for a local variable, a static or a (future) heap allocation) -gets its own little memory with exactly the required size. So if you have a +gets its own little memory with exactly the required size. +So if you have a pointer to an allocation for a local variable `a`, there is no possible (no matter how unsafe) operation that you can do that would ever change said pointer to a pointer to a different local variable `b`. @@ -152,31 +173,35 @@ Pointer arithmetic on `a` will only ever change its offset; the `AllocId` stays This, however, causes a problem when we want to store a `Pointer` into an `Allocation`: we cannot turn it into a sequence of `u8` of the right length! -`AllocId` and offset together are twice as big as a pointer "seems" to be. This -is what the `relocation` field of `Allocation` is for: the byte offset of the +`AllocId` and offset together are twice as big as a pointer "seems" to be. +This is what the `relocation` field of `Allocation` is for: the byte offset of the `Pointer` gets stored as a bunch of `u8`, while its `AllocId` gets stored -out-of-band. The two are reassembled when the `Pointer` is read from memory. +out-of-band. +The two are reassembled when the `Pointer` is read from memory. The other bit of extra data an `Allocation` needs is `undef_mask` for keeping track of which of its bytes are initialized. ### Global memory and exotic allocations `Memory` exists only during evaluation; it gets destroyed when the -final value of the constant is computed. In case that constant contains any +final value of the constant is computed. +In case that constant contains any pointers, those get "interned" and moved to a global "const eval memory" that is -part of `TyCtxt`. These allocations stay around for the remaining computation +part of `TyCtxt`. +These allocations stay around for the remaining computation and get serialized into the final output (so that dependent crates can use them). Moreover, to also support function pointers, the global memory in `TyCtxt` can also contain "virtual allocations": instead of an `Allocation`, these contain an -`Instance`. That allows a `Pointer` to point to either normal data or a +`Instance`. +That allows a `Pointer` to point to either normal data or a function, which is needed to be able to evaluate casts from function pointers to raw pointers. Finally, the [`GlobalAlloc`] type used in the global memory also contains a -variant `Static` that points to a particular `const` or `static` item. This is -needed to support circular statics, where we need to have a `Pointer` to a +variant `Static` that points to a particular `const` or `static` item. +This is needed to support circular statics, where we need to have a `Pointer` to a `static` for which we cannot yet have an `Allocation` as we do not know the bytes of its value. @@ -188,17 +213,19 @@ bytes of its value. ### Pointer values vs Pointer types One common cause of confusion in the interpreter is that being a pointer *value* and having -a pointer *type* are entirely independent properties. By "pointer value", we +a pointer *type* are entirely independent properties. +By "pointer value", we refer to a `Scalar::Ptr` containing a `Pointer` and thus pointing somewhere into -the interpreter's virtual memory. This is in contrast to `Scalar::Raw`, which is just some -concrete integer. +the interpreter's virtual memory. +This is in contrast to `Scalar::Raw`, which is just some concrete integer. However, a variable of pointer or reference *type*, such as `*const T` or `&T`, does not have to have a pointer *value*: it could be obtained by casting or -transmuting an integer to a pointer. +transmuting an integer to a pointer. And similarly, when casting or transmuting a reference to some actual allocation to an integer, we end up with a pointer *value* -(`Scalar::Ptr`) at integer *type* (`usize`). This is a problem because we +(`Scalar::Ptr`) at integer *type* (`usize`). + This is a problem because we cannot meaningfully perform integer operations such as division on pointer values. @@ -207,30 +234,33 @@ values. Although the main entry point to constant evaluation is the `tcx.const_eval_*` functions, there are additional functions in [rustc_const_eval/src/const_eval](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/index.html) -that allow accessing the fields of a `ConstValue` (`ByRef` or otherwise). You should +that allow accessing the fields of a `ConstValue` (`Indirect` or otherwise). +You should never have to access an `Allocation` directly except for translating it to the compilation target (at the moment just LLVM). The interpreter starts by creating a virtual stack frame for the current constant that is -being evaluated. There's essentially no difference between a constant and a +being evaluated. +There's essentially no difference between a constant and a function with no arguments, except that constants do not allow local (named) variables at the time of writing this guide. A stack frame is defined by the `Frame` type in [rustc_const_eval/src/interpret/eval_context.rs](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_const_eval/src/interpret/eval_context.rs) -and contains all the local -variables memory (`None` at the start of evaluation). Each frame refers to the -evaluation of either the root constant or subsequent calls to `const fn`. The -evaluation of another constant simply calls `tcx.const_eval_*`, which produce an +and contains all the local variables memory (`None` at the start of evaluation). +Each frame refers to the +evaluation of either the root constant or subsequent calls to `const fn`. +The evaluation of another constant simply calls `tcx.const_eval_*`, which produce an entirely new and independent stack frame. The frames are just a `Vec`, there's no way to actually refer to a -`Frame`'s memory even if horrible shenanigans are done via unsafe code. The only -memory that can be referred to are `Allocation`s. +`Frame`'s memory even if horrible shenanigans are done via unsafe code. +The only memory that can be referred to are `Allocation`s. The interpreter now calls the `step` method (in [rustc_const_eval/src/interpret/step.rs](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_const_eval/src/interpret/step.rs) -) until it either returns an error or has no further statements to execute. Each -statement will now initialize or modify the locals or the virtual memory -referred to by a local. This might require evaluating other constants or +) until it either returns an error or has no further statements to execute. +Each statement will now initialize or modify the locals or the virtual memory +referred to by a local. +This might require evaluating other constants or statics, which just recursively invokes `tcx.const_eval_*`. diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index bdd7a3dfa9b8e..554bcfcf8e4b6 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -953,7 +953,7 @@ You can match on the following names and values, using `name = "value"`: Only `"MainFunctionType"` is supported. - `from_desugaring`: Match against a particular variant of the `DesugaringKind` enum. The desugaring is identified by its variant name, for example - `"QuestionMark"` for `?` desugaring or `"TryBlock"` for `try` blocks. + `"QuestionMark"` for `?` desugaring, or `"TryBlock"` for `try` blocks. - `Self` and any generic arguments of the trait, like `Self = "alloc::string::String"` or `Rhs="i32"`. @@ -964,6 +964,7 @@ The compiler can provide several values to match on, for example: - references to said slices and arrays. - `"fn"`, `"unsafe fn"` or `"#[target_feature] fn"` when self is a function. - `"{integer}"` and `"{float}"` if the type is a number but we haven't inferred it yet. + - `"{struct}"`, `"{enum}"` and `"{union}"` to match self as an ADT - combinations of the above, like `"[{integral}; _]"`. For example, the `Iterator` trait can be filtered in the following way: diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md index cda975a9a15ee..11a7a573f38b6 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md @@ -20,7 +20,7 @@ which boils down to a static with type [`&rustc_lint_defs::Lint`] as the macro is somewhat unwieldy to add new fields to, like all macros). -we lint against direct declarations without the use of the macro. +We lint against direct declarations without the use of the macro. Lint declarations don't carry any "state" - they are merely global identifiers and descriptions of lints. diff --git a/src/doc/rustc-dev-guide/src/early-late-parameters.md b/src/doc/rustc-dev-guide/src/early-late-parameters.md index d78d5331baac4..4dd4d74174ebf 100644 --- a/src/doc/rustc-dev-guide/src/early-late-parameters.md +++ b/src/doc/rustc-dev-guide/src/early-late-parameters.md @@ -130,9 +130,9 @@ f(&String::new()); f(&String::new()); ``` +The lifetime parameter on `foo` being early bound requires all callers of `f` to provide a borrow with the same lifetime. In this example, we call `foo`'s function item type twice, each time with a borrow of a temporary. -These two borrows could not possibly have lifetimes that overlap as the temporaries are only alive during the function call, not after. -The lifetime parameter on `foo` being early bound requires all callers of `f` to provide a borrow with the same lifetime, as this is not possible the borrow checker errors. +These two borrows could not possibly have lifetimes that overlap as the temporaries are only alive during the function call, not after, so we get a compilation error. If the lifetime parameter on `foo` was late bound, this would be able to compile as each caller could provide a different lifetime argument for its borrow. See the following example, which demonstrates this using the `bar` function defined above: diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md index 0b341a40f1ddb..c2e227dc936ce 100644 --- a/src/doc/rustc-dev-guide/src/hir.md +++ b/src/doc/rustc-dev-guide/src/hir.md @@ -1,13 +1,15 @@ # The HIR The HIR – "High-Level Intermediate Representation" – is the primary IR used -in most of rustc. It is a compiler-friendly representation of the abstract +in most of rustc. +It is a compiler-friendly representation of the abstract syntax tree (AST) that is generated after parsing, macro expansion, and name resolution (see [Lowering](./hir/lowering.md) for how the HIR is created). Many parts of HIR resemble Rust surface syntax quite closely, with the exception that some of Rust's expression forms have been desugared away. For example, `for` loops are converted into a `loop` and do not appear in -the HIR. This makes HIR more amenable to analysis than a normal AST. +the HIR. +This makes HIR more amenable to analysis than a normal AST. This chapter covers the main concepts of the HIR. @@ -30,17 +32,18 @@ cargo rustc -- -Z unpretty=hir The top-level data-structure in the HIR is the [`Crate`], which stores the contents of the crate currently being compiled (we only ever -construct HIR for the current crate). Whereas in the AST the crate +construct HIR for the current crate). +Whereas in the AST the crate data structure basically just contains the root module, the HIR `Crate` structure contains a number of maps and other things that serve to organize the content of the crate for easier access. -[`Crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Crate.html +[`Crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/struct.Crate.html For example, the contents of individual items (e.g. modules, functions, traits, impls, etc) in the HIR are not immediately -accessible in the parents. So, for example, if there is a module item -`foo` containing a function `bar()`: +accessible in the parents. +So, for example, if there is a module item `foo` containing a function `bar()`: ```rust mod foo { @@ -49,8 +52,8 @@ mod foo { ``` then in the HIR the representation of module `foo` (the [`Mod`] -struct) would only have the **`ItemId`** `I` of `bar()`. To get the -details of the function `bar()`, we would lookup `I` in the +struct) would only have the **`ItemId`** `I` of `bar()`. +To get the details of the function `bar()`, we would lookup `I` in the `items` map. [`Mod`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Mod.html @@ -62,9 +65,11 @@ There are similar maps for things like trait items and impl items, as well as "bodies" (explained below). The other reason to set up the representation this way is for better -integration with incremental compilation. This way, if you gain access +integration with incremental compilation. +This way, if you gain access to an [`&rustc_hir::Item`] (e.g. for the mod `foo`), you do not immediately -gain access to the contents of the function `bar()`. Instead, you only +gain access to the contents of the function `bar()`. +Instead, you only gain access to the **id** for `bar()`, and you must invoke some function to lookup the contents of `bar()` given its id; this gives the compiler a chance to observe that you accessed the data for @@ -79,23 +84,27 @@ the compiler a chance to observe that you accessed the data for The HIR uses a bunch of different identifiers that coexist and serve different purposes. - A [`DefId`], as the name suggests, identifies a particular definition, or top-level - item, in a given crate. It is composed of two parts: a [`CrateNum`] which identifies + item, in a given crate. + It is composed of two parts: a [`CrateNum`] which identifies the crate the definition comes from, and a [`DefIndex`] which identifies the definition - within the crate. Unlike [`HirId`]s, there isn't a [`DefId`] for every expression, which + within the crate. + Unlike [`HirId`]s, there isn't a [`DefId`] for every expression, which makes them more stable across compilations. - A [`LocalDefId`] is basically a [`DefId`] that is known to come from the current crate. This allows us to drop the [`CrateNum`] part, and use the type system to ensure that only local definitions are passed to functions that expect a local definition. -- A [`HirId`] uniquely identifies a node in the HIR of the current crate. It is composed - of two parts: an `owner` and a `local_id` that is unique within the `owner`. This - combination makes for more stable values which are helpful for incremental compilation. +- A [`HirId`] uniquely identifies a node in the HIR of the current crate. + It is composed of two parts: + an `owner` and a `local_id` that is unique within the `owner`. + This combination makes for more stable values which are helpful for incremental compilation. Unlike [`DefId`]s, a [`HirId`] can refer to [fine-grained entities][Node] like expressions, but stays local to the current crate. -- A [`BodyId`] identifies a HIR [`Body`] in the current crate. It is currently only - a wrapper around a [`HirId`]. For more info about HIR bodies, please refer to the +- A [`BodyId`] identifies a HIR [`Body`] in the current crate. + It is currently only a wrapper around a [`HirId`]. + For more info about HIR bodies, please refer to the [HIR chapter][hir-bodies]. These identifiers can be converted into one another through the `TyCtxt`. @@ -112,8 +121,8 @@ These identifiers can be converted into one another through the `TyCtxt`. ## HIR Operations -Most of the time when you are working with the HIR, you will do so via -`TyCtxt`. It contains a number of methods, defined in the `hir::map` module and +Most of the time when you are working with the HIR, you will do so via `TyCtxt`. +It contains a number of methods, defined in the `hir::map` module and mostly prefixed with `hir_`, to convert between IDs of various kinds and to lookup data associated with a HIR node. @@ -126,8 +135,10 @@ You need a `LocalDefId`, rather than a `DefId`, since only local items have HIR [local_def_id_to_hir_id]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.local_def_id_to_hir_id Similarly, you can use [`tcx.hir_node(n)`][hir_node] to lookup the node for a -[`HirId`]. This returns a `Option>`, where [`Node`] is an enum -defined in the map. By matching on this, you can find out what sort of +[`HirId`]. +This returns a `Option>`, where [`Node`] is an enum +defined in the map. +By matching on this, you can find out what sort of node the `HirId` referred to and also get a pointer to the data itself. Often, you know what sort of node `n` is – e.g. if you know that `n` must be some HIR expression, you can do @@ -148,8 +159,8 @@ calls like [`tcx.parent_hir_node(n)`][parent_hir_node]. ## HIR Bodies A [`rustc_hir::Body`] represents some kind of executable code, such as the body -of a function/closure or the definition of a constant. Bodies are -associated with an **owner**, which is typically some kind of item +of a function/closure or the definition of a constant. +Bodies are associated with an **owner**, which is typically some kind of item (e.g. an `fn()` or `const`), but could also be a closure expression (e.g. `|x, y| x + y`). You can use the `TyCtxt` to find the body associated with a given def-id ([`hir_maybe_body_owned_by`]) or to find diff --git a/src/doc/rustc-dev-guide/src/hir/lowering.md b/src/doc/rustc-dev-guide/src/hir/lowering.md index c0057a69c10d6..b7d0293bede98 100644 --- a/src/doc/rustc-dev-guide/src/hir/lowering.md +++ b/src/doc/rustc-dev-guide/src/hir/lowering.md @@ -15,8 +15,26 @@ of such structures include but are not limited to * Existential `impl Trait` * Converted to a virtual `existential type` declaration +The implementation of AST lowering is in the [`rustc_ast_lowering`] crate. +The entry point is [`lower_to_hir`], which retrieves the post-expansion AST +and resolver data from [`TyCtxt`] and builds the [`hir::Crate`] for the whole crate. + +Lowering is organized around HIR owners. [`lower_to_hir`] first indexes the +crate and then [`ItemLowerer::lower_node`] lowers each crate, item, associated +item, and foreign item. + +Most of the lowering logic lives on [`LoweringContext`]. The implementation is +split across multiple files in the [`rustc_ast_lowering`] crate such as `item.rs`, +`expr.rs`, `pat.rs`, `path.rs`, and others, but they all share the same [`LoweringContext`] +state and ID‑lowering machinery. + +Each owner is lowered in its own [`with_hir_id_owner`] scope. This is why the +`HirId` invariants below matter: `lower_node_id` maps AST `NodeId`s into the +current owner, while `next_id` creates fresh HIR-only nodes introduced during +desugaring. + Lowering needs to uphold several invariants in order to not trigger the -sanity checks in `compiler/rustc_passes/src/hir_id_validator.rs`: +sanity checks in [`compiler/rustc_passes/src/hir_id_validator.rs`][hir_id_validator]: 1. A `HirId` must be used if created. So if you use the `lower_node_id`, you *must* use the resulting `NodeId` or `HirId` (either is fine, since @@ -33,6 +51,15 @@ sanity checks in `compiler/rustc_passes/src/hir_id_validator.rs`: which produces both a new `NodeId` as well as automatically lowering it for you so you also get the `HirId`. +[`rustc_ast_lowering`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/index.html +[`lower_to_hir`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/fn.lower_to_hir.html +[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html +[`hir::Crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Crate.html +[`ItemLowerer::lower_node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/item/struct.ItemLowerer.html +[`LoweringContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html +[`with_hir_id_owner`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html#method.with_hir_id_owner +[hir_id_validator]: https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_passes/src/hir_id_validator.rs + If you are creating new `DefId`s, since each `DefId` needs to have a corresponding `NodeId`, it is advisable to add these `NodeId`s to the `AST` so you don't have to generate new ones during lowering. This has diff --git a/src/doc/rustc-dev-guide/src/notification-groups/about.md b/src/doc/rustc-dev-guide/src/notification-groups/about.md index 86797b1e0bb51..28c836dc4dba2 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/about.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/about.md @@ -28,6 +28,7 @@ Here's the list of the notification groups: - [WebAssembly](./wasm.md) - [Windows](./windows.md) - [Rust for Linux](./rust-for-linux.md) +- [GPU target](./gpu-target.md) ## What issues are a good fit for notification groups? diff --git a/src/doc/rustc-dev-guide/src/notification-groups/gpu-target.md b/src/doc/rustc-dev-guide/src/notification-groups/gpu-target.md new file mode 100644 index 0000000000000..b46233e98b413 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/notification-groups/gpu-target.md @@ -0,0 +1,18 @@ +# GPU target notification group + +**Github Label:** None
+**Ping command:** `@rustbot ping gpu-target` + +This notification group deals with linker related issues and their integration +within the compiler. + +The group also has an associated Zulip stream ([`#t-compiler/linker`]) +where people can go to ask questions and discuss GPU-related topics and issues. + +if you're interested in participating, feel free to sign up for this group! To +do so, open a PR against the [rust-lang/team] repository and add your GitHub +user to [this file][gpu-target-team]. + +[`#t-compiler/linker`]: https://rust-lang.zulipchat.com/#narrow/channel/585172-t-compiler.2Flinker +[rust-lang/team]: https://github.com/rust-lang/team +[gpu-target-team]: https://github.com/rust-lang/team/blob/main/teams/gpu-target.toml diff --git a/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md b/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md index 518cf4e821a72..268b612e3ee79 100644 --- a/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md +++ b/src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md @@ -7,7 +7,7 @@ otherwise be printed to stderr. To get diagnostics from the compiler, configure [`rustc_interface::Config`] to output diagnostic to a buffer, -and run [`rustc_hir_typeck::typeck`] for each item. +and run [`TyCtxtEnsureOk::typeck`] for each item. ```rust {{#include ../../examples/rustc-interface-getting-diagnostics.rs}} @@ -15,5 +15,4 @@ and run [`rustc_hir_typeck::typeck`] for each item. [`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html [`rustc_interface::Config`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html -[`TyCtxt.analysis`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/fn.analysis.html -[`rustc_hir_typeck::typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn.typeck.html +[`TyCtxtEnsureOk::typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.TyCtxtEnsureOk.html#method.typeck diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index 989a77290b6b9..f3fd47812a96b 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -48,7 +48,7 @@ The "entry point" to this module is The first step in [`clean::utils::krate`][ck1] is to invoke [`visit_ast::RustdocVisitor`] to process the module tree into an intermediate [`visit_ast::Module`]. This is the step that actually crawls the -[`rustc_hir::Crate`], normalizing various aspects of name resolution, such as: +[`rustc_middle::hir::Crate`], normalizing various aspects of name resolution, such as: * handling `#[doc(inline)]` and `#[doc(no_inline)]` * handling import globs and cycles, so there are no duplicates or infinite @@ -79,7 +79,7 @@ which describe the publicly-documentable items in the target crate. [`core.rs`]: https://github.com/rust-lang/rust/blob/HEAD/src/librustdoc/core.rs [`Item`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/clean/types/struct.Item.html [`run_global_ctxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/core/fn.run_global_ctxt.html -[`rustc_hir::Crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Crate.html +[`rustc_middle::hir::Crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/struct.Crate.html [`rustdoc::core::DocContext`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/core/struct.DocContext.html [`rustdoc::core::run_global_ctxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/core/fn.run_global_ctxt.html [`visit_ast::Module`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc/visit_ast/struct.Module.html @@ -108,19 +108,20 @@ Here is the list of passes as of March 2023: - `calculate-doc-coverage` calculates information used for the `--show-coverage` flag. -- `check-doc-test-visibility` runs `doctest` visibility–related `lint`s. This pass - runs before `strip-private`, which is why it needs to be separate from `run-lints`. +- `check-doc-test-visibility` runs `doctest` visibility–related `lint`s. + This pass runs before `strip-private`, + which is why it needs to be separate from `run-lints`. - `collect-intra-doc-links` resolves [intra-doc links](https://doc.rust-lang.org/nightly/rustdoc/write-documentation/linking-to-items-by-name.html). -- `collect-trait-impls` collects `trait` `impl`s for each item in the crate. For - example, if we define a `struct` that implements a `trait`, this pass will note - that the `struct` implements that `trait`. +- `collect-trait-impls` collects `trait` `impl`s for each item in the crate. + For example, if we define a `struct` that implements a `trait`, + this pass will note that the `struct` implements that `trait`. - `propagate-doc-cfg` propagates `#[doc(cfg(...))]` to child items. -- `run-lints` runs some of `rustdoc`'s `lint`s, defined in `passes/lint`. This is - the last pass to run. +- `run-lints` runs some of `rustdoc`'s `lint`s, defined in `passes/lint`. + This is the last pass to run. - `bare_urls` detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.` It suggests wrapping the link with angle brackets: @@ -233,7 +234,8 @@ is complicated from two other constraints that `rustdoc` runs under: configurations, such as `libstd` having a single package of docs that cover all supported operating systems. This means `rustdoc` has to be able to generate docs from `HIR`. -* Docs can inline across crates. Since crate metadata doesn't contain `HIR`, +* Docs can inline across crates. + Since crate metadata doesn't contain `HIR`, it must be possible to generate inlined docs from the `rustc_middle` data. The "clean" [`AST`][ast] acts as a common output format for both input formats. diff --git a/src/doc/rustc-dev-guide/src/tests/adding.md b/src/doc/rustc-dev-guide/src/tests/adding.md index ebbbb1cfc0d3a..7e2b9015f8d3e 100644 --- a/src/doc/rustc-dev-guide/src/tests/adding.md +++ b/src/doc/rustc-dev-guide/src/tests/adding.md @@ -2,12 +2,13 @@ **In general, we expect every PR that fixes a bug in rustc to come accompanied by a regression test of some kind.** This test should fail in `main` but pass -after the PR. These tests are really useful for preventing us from repeating the +after the PR. +These tests are really useful for preventing us from repeating the mistakes of the past. -The first thing to decide is which kind of test to add. This will depend on the -nature of the change and what you want to exercise. Here are some rough -guidelines: +The first thing to decide is which kind of test to add. +This will depend on the nature of the change and what you want to exercise. +Here are some rough guidelines: - The majority of compiler tests are done with [compiletest]. - The majority of compiletest tests are [UI](ui.md) tests in the [`tests/ui`] @@ -17,18 +18,24 @@ guidelines: - The majority of standard library tests are written as doctests, which illustrate and exercise typical API behavior. - Additional [unit tests](intro.md#package-tests) should go in - `library/${crate}/tests` (where `${crate}` is usually `core`, `alloc`, or - `std`). + `library/${crate}/tests` (where `${crate}` is usually `std`). + - Tests for the `alloc` or `core` crates must go in separate crates: `alloctests` or `coretests` respectively. + - NOTE: That when adding unit tests for unstable features the `#![feature(...)]` + declaration must be added to `library/${crate}tests/tests/lib.rs` and not to + `library/${crate}tests/lib.rs`. - If the code is part of an isolated system, and you are not testing compiler output, consider using a [unit or integration test](intro.md#package-tests). -- Need to run rustdoc? Prefer a `rustdoc` or `rustdoc-ui` test. Occasionally - you'll need `rustdoc-js` as well. +- Need to run rustdoc? + Prefer a `rustdoc` or `rustdoc-ui` test. + Occasionally you'll need `rustdoc-js` as well. - Other compiletest test suites are generally used for special purposes: - - Need to run gdb or lldb? Use the `debuginfo` test suite. - - Need to inspect LLVM IR or MIR IR? Use the `codegen` or `mir-opt` test - suites. - - Need to inspect the resulting binary in some way? Or if all the other test - suites are too limited for your purposes? Then use `run-make`. + - Need to run gdb or lldb? + Use the `debuginfo` test suite. + - Need to inspect LLVM IR or MIR IR? + Use the `codegen` or `mir-opt` test suites. + - Need to inspect the resulting binary in some way? + Or if all the other test suites are too limited for your purposes? + Then use `run-make`. - Use `run-make-cargo` if you need to exercise in-tree `cargo` in conjunction with in-tree `rustc`. - Check out the [compiletest] chapter for more specialized test suites. @@ -44,14 +51,16 @@ modified several years later, how can we make it easier for them?). ## UI test walkthrough The following is a basic guide for creating a [UI test](ui.md), which is one of -the most common compiler tests. For this tutorial, we'll be adding a test for an -async error message. +the most common compiler tests. +For this tutorial, we'll be adding a test for an async error message. ### Step 1: Add a test file The first step is to create a Rust source file somewhere in the [`tests/ui`] -tree. When creating a test, do your best to find a good location and name (see -[Test organization](ui.md#test-organization) for more). Since naming is the +tree. +When creating a test, do your best to find a good location and name (see +[Test organization](ui.md#test-organization) for more). +Since naming is the hardest part of development, everything should be downhill from here! Let's place our async test at `tests/ui/async-await/await-without-async.rs`: @@ -74,19 +83,23 @@ A few things to notice about our test: - The top should start with a short comment that [explains what the test is for](#explanatory_comment). - The `//@ edition:2018` comment is called a [directive](directives.md) which - provides instructions to compiletest on how to build the test. Here we need to + provides instructions to compiletest on how to build the test. + Here we need to set the edition for `async` to work (the default is edition 2015). -- Following that is the source of the test. Try to keep it succinct and to the - point. This may require some effort if you are trying to minimize an example +- Following that is the source of the test. + Try to keep it succinct and to the point. + This may require some effort if you are trying to minimize an example from a bug report. -- We end this test with an empty `fn main` function. This is because the default +- We end this test with an empty `fn main` function. + This is because the default for UI tests is a `bin` crate-type, and we don't want the "main not found" - error in our test. Alternatively, you could add `#![crate_type="lib"]`. + error in our test. + Alternatively, you could add `#![crate_type="lib"]`. ### Step 2: Generate the expected output -The next step is to create the expected output snapshots from the compiler. This -can be done with the `--bless` option: +The next step is to create the expected output snapshots from the compiler. +This can be done with the `--bless` option: ```sh ./x test tests/ui/async-await/await-without-async.rs --bless @@ -96,8 +109,8 @@ This will build the compiler (if it hasn't already been built), compile the test, and place the output of the compiler in a file called `tests/ui/async-await/await-without-async.stderr`. -However, this step will fail! You should see an error message, something like -this: +However, this step will fail! +You should see an error message, something like this: > error: /rust/tests/ui/async-await/await-without-async.rs:7: unexpected > error: '7:10: 7:16: `await` is only allowed inside `async` functions and @@ -109,7 +122,8 @@ annotations in the source file. ### Step 3: Add error annotations Every error needs to be annotated with a comment in the source with the text of -the error. In this case, we can add the following comment to our test file: +the error. +In this case, we can add the following comment to our test file: ```rust,ignore fn bar() { @@ -133,9 +147,10 @@ It should now pass, yay! ### Step 4: Review the output Somewhat hand-in-hand with the previous step, you should inspect the `.stderr` -file that was created to see if it looks like how you expect. If you are adding -a new diagnostic message, now would be a good time to also consider how readable -the message looks overall, particularly for people new to Rust. +file that was created to see if it looks like how you expect. +If you are adding a new diagnostic message, +now would be a good time to also consider how readable the message looks overall, +particularly for people new to Rust. Our example `tests/ui/async-await/await-without-async.stderr` file should look like this: @@ -158,9 +173,9 @@ You may notice some things look a little different than the regular compiler output. - The `$DIR` removes the path information which will differ between systems. -- The `LL` values replace the line numbers. That helps avoid small changes in - the source from triggering large diffs. See the - [Normalization](ui.md#normalization) section for more. +- The `LL` values replace the line numbers. + That helps avoid small changes in the source from triggering large diffs. + See the [Normalization](ui.md#normalization) section for more. Around this stage, you may need to iterate over the last few steps a few times to tweak your test, re-bless the test, and re-review the output. @@ -168,8 +183,10 @@ to tweak your test, re-bless the test, and re-review the output. ### Step 5: Check other tests Sometimes when adding or changing a diagnostic message, this will affect other -tests in the test suite. The final step before posting a PR is to check if you -have affected anything else. Running the UI suite is usually a good start: +tests in the test suite. +The final step before posting a PR is to check if you +have affected anything else. +Running the UI suite is usually a good start: ```sh ./x test tests/ui @@ -185,16 +202,18 @@ You may also need to re-bless the output with the `--bless` flag. ## Comment explaining what the test is about The first comment of a test file should **summarize the point of the test**, and -highlight what is important about it. If there is an issue number associated -with the test, include the issue number. +highlight what is important about it. +If there is an issue number associated with the test, include the issue number. -This comment doesn't have to be super extensive. Just something like "Regression -test for #18060: match arms were matching in the wrong order." might already be -enough. +This comment doesn't have to be super extensive. +Just something like the following might be enough: +"Regression test for #18060: match arms were matching in the wrong order". These comments are very useful to others later on when your test breaks, since -they often can highlight what the problem is. They are also useful if for some +they often can highlight what the problem is. +They are also useful if for some reason the tests need to be refactored, since they let others know which parts -of the test were important. Often a test must be rewritten because it no longer +of the test were important. +Often a test must be rewritten because it no longer tests what it was meant to test, and then it's useful to know what it *was* meant to test exactly. diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 7332d1fb38515..d90240af2591f 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -636,6 +636,13 @@ but not `tests/rustdoc-ui`) will specify - `-A unused` - `-W unused_attributes` (since these tend to be interesting for ui tests) - `-A internal_features` +- `-A incomplete_features` +- `-A unused_parens` +- `-A unused_braces` + +For more details, see [runtest]. + +[runtest]: https://github.com/rust-lang/rust/blob/HEAD/src/tools/compiletest/src/runtest.rs If: diff --git a/src/doc/rustc-dev-guide/src/traits/separate-projection-bounds.md b/src/doc/rustc-dev-guide/src/traits/separate-projection-bounds.md new file mode 100644 index 0000000000000..144e27316cbb4 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/traits/separate-projection-bounds.md @@ -0,0 +1,47 @@ +# Having separate `Trait` and `Projection` bounds + +Given `T: Foo` where-bound, we currently lower it to a `Trait(Foo)` and separate `Projection(::AssocA, u32)` and `Projection(::AssocB, i32)` bounds. +Why do we not represent this as a single `Trait(Foo[T], [AssocA = u32, AssocB = u32]` bound instead? + +The way we prove `Projection` bounds directly relies on proving the corresponding `Trait` bound: [old solver](https://github.com/rust-lang/rust/blob/461e9738a47e313e4457957fa95ff6a19a4b88d4/compiler/rustc_trait_selection/src/traits/project.rs#L898) [new solver](https://github.com/rust-lang/rust/blob/461e9738a47e313e4457957fa95ff6a19a4b88d4/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs#L37-L41). + +It feels like it might make more sense to just have a single implementation which checks whether a trait is implemented and returns (a way to compute) its associated types. + +This is unfortunately quite difficult, as we may use a different candidate for norm than for the corresponding trait bound. +See [alias-bound vs where-bound](https://rustc-dev-guide.rust-lang.org/solve/candidate-preference.html#we-always-consider-aliasbound-candidates) and [global where-bound vs impl](https://rustc-dev-guide.rust-lang.org/solve/candidate-preference.html#we-prefer-global-where-bounds-over-impls). + +There are also some other subtle reasons for why we can't do so. +The most stupid is that for rigid aliases; +trying to normalize them does not consider any lifetime constraints from proving the trait bound. +This is necessary due to a lack of assumptions on binders - https://github.com/rust-lang/trait-system-refactor-initiative/issues/177 - and should be fixed longterm. + +A separate issue is that, right now, +fetching the `type_of` associated types for `Trait` goals or in shadowed `Projection` candidates can cause query cycles for RPITIT. +See https://github.com/rust-lang/trait-system-refactor-initiative/issues/185. + +There are also slight differences between candidates for some of the builtin impls, these do all seem generally undesirable and I consider them to be bugs which would be fixed if we had a unified approach here. + +Finally, not having this split makes lowering where-clauses more annoying. +With the current system having duplicate where-clauses is not an issue and it can easily happen when elaborating super trait bounds. +We now need to make sure we merge all associated type constraints, e.g.: + +```rust +trait Super { + type A; + type B; +} + +trait Trait: Super {} +// how to elaborate Trait +``` +Or even worse +```rust +trait Super<'a> { + type A; + type B; +} + +trait Trait<'a>: Super<'a, A = i32> {} +// how to elaborate +// T: Trait<'a> + for<'b> Super<'b, B = u32> +``` diff --git a/src/doc/rustc-dev-guide/src/ty-module/generic-arguments.md b/src/doc/rustc-dev-guide/src/ty-module/generic-arguments.md index 3339d31142512..295b654e0ce4b 100644 --- a/src/doc/rustc-dev-guide/src/ty-module/generic-arguments.md +++ b/src/doc/rustc-dev-guide/src/ty-module/generic-arguments.md @@ -24,12 +24,14 @@ Adt(&'tcx AdtDef, GenericArgs<'tcx>) There are two parts: - The [`AdtDef`][adtdef] references the struct/enum/union but without the values for its type - parameters. In our example, this is the `MyStruct` part *without* the argument `u32`. + parameters. + In our example, this is the `MyStruct` part *without* the argument `u32`. (Note that in the HIR, structs, enums and unions are represented differently, but in `ty::Ty`, they are all represented using `TyKind::Adt`.) - The [`GenericArgs`] is a list of values that are to be substituted -for the generic parameters. In our example of `MyStruct`, we would end up with a list like -`[u32]`. We’ll dig more into generics and substitutions in a little bit. +for the generic parameters. + In our example of `MyStruct`, we would end up with a list like `[u32]`. +We’ll dig more into generics and substitutions in a little bit. [adtdef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.AdtDef.html [`GenericArgs`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.GenericArgs.html @@ -37,25 +39,29 @@ for the generic parameters. In our example of `MyStruct`, we would end up ### **`AdtDef` and `DefId`** For every type defined in the source code, there is a unique `DefId` (see [this -chapter](../hir.md#identifiers-in-the-hir)). This includes ADTs and generics. In the `MyStruct` -definition we gave above, there are two `DefId`s: one for `MyStruct` and one for `T`. Notice that -the code above does not generate a new `DefId` for `u32` because it is not defined in that code (it -is only referenced). - -`AdtDef` is more or less a wrapper around `DefId` with lots of useful helper methods. There is -essentially a one-to-one relationship between `AdtDef` and `DefId`. You can get the `AdtDef` for a -`DefId` with the [`tcx.adt_def(def_id)` query][adtdefq]. `AdtDef`s are all interned, as shown -by the `'tcx` lifetime. +chapter](../hir.md#identifiers-in-the-hir)). +This includes ADTs and generics. +In the `MyStruct` definition we gave above, +there are two `DefId`s: one for `MyStruct` and one for `T`. +Notice that the code above does not generate a new `DefId` for `u32` +because it is not defined in that code (it is only referenced). + +`AdtDef` is more or less a wrapper around `DefId` with lots of useful helper methods. +There is essentially a one-to-one relationship between `AdtDef` and `DefId`. +You can get the `AdtDef` for a `DefId` with the [`tcx.adt_def(def_id)` query][adtdefq]. +`AdtDef`s are all interned, as shown by the `'tcx` lifetime. [adtdefq]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.adt_def ## Question: Why not substitute “inside” the `AdtDef`? -Recall that we represent a generic struct with `(AdtDef, args)`. So why bother with this scheme? +Recall that we represent a generic struct with `(AdtDef, args)`. +So why bother with this scheme? Well, the alternate way we could have chosen to represent types would be to always create a new, -fully-substituted form of the `AdtDef` where all the types are already substituted. This seems like -less of a hassle. However, the `(AdtDef, args)` scheme has some advantages over this. +fully-substituted form of the `AdtDef` where all the types are already substituted. +This seems like less of a hassle. +However, the `(AdtDef, args)` scheme has some advantages over this. First, `(AdtDef, args)` scheme has an efficiency win: @@ -68,7 +74,8 @@ struct MyStruct { ``` in an example like this, we can instantiate `MyStruct` as `MyStruct` (and so on) very cheaply, -by just replacing the one reference to `A` with `B`. But if we eagerly instantiated all the fields, +by just replacing the one reference to `A` with `B`. +But if we eagerly instantiated all the fields, that could be a lot more work because we might have to go through all of the fields in the `AdtDef` and update all of their types. @@ -83,7 +90,9 @@ definition of that name, and not carried along “within” the type itself). Given a generic type `MyType`, we have to store the list of generic arguments for `MyType`. -In rustc this is done using [`GenericArgs`]. `GenericArgs` is a thin pointer to a slice of [`GenericArg`] representing a list of generic arguments for a generic item. For example, given a `struct HashMap` with two type parameters, `K` and `V`, the `GenericArgs` used to represent the type `HashMap` would be represented by `&'tcx [tcx.types.i32, tcx.types.u32]`. +In rustc this is done using [`GenericArgs`]. +`GenericArgs` is a thin pointer to a slice of [`GenericArg`] representing a list of generic arguments for a generic item. +For example, given a `struct HashMap` with two type parameters, `K` and `V`, the `GenericArgs` used to represent the type `HashMap` would be represented by `&'tcx [tcx.types.i32, tcx.types.u32]`. `GenericArg` is conceptually an `enum` with three variants, one for type arguments, one for const arguments and one for lifetime arguments. In practice that is actually represented by [`GenericArgKind`] and [`GenericArg`] is a more space efficient version that has a method to @@ -126,3 +135,36 @@ For the `MyStruct` written in the `Foo` type alias, we would represent it in - There would be an `AdtDef` (and corresponding `DefId`) for `MyStruct`. - There would be a `GenericArgs` containing the list `[GenericArgKind::Type(Ty(u32))]` - And finally a `TyKind::Adt` with the `AdtDef` and `GenericArgs` listed above. + +## Nested generic args + +```rust +struct MyStruct(T); + +impl MyStruct { + fn func() {} +} + +fn main() { + MyStruct::::func::(); +} +``` + +The construct `MyStruct::::func::` is represented by a tuple: a DefId pointing at `func`, and then a +`GenericArgs` list that "walks" all containing generic parameters - in this case, the list would be `[u32, bool, char]`. + +The [`ty::Generics`] type (returned by the [`generics_of`] query) contains the information of how a nested hierarchy +gets flattened down to a list, and lets you figure out which index in the `GenericArgs` list corresponds to which +generic. +The general theme of how it works is outermost to innermost (`T` before `T2` in the example), left to right +(`T2` before `T3`), but there are several complications: + +- Traits have an implicit `Self` generic parameter which is the first (i.e. 0th) generic parameter. Note that `Self` doesn't mean a generic parameter in all situations, see [Res::SelfTyAlias](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.Res.html#variant.SelfTyAlias) and [Res::SelfCtor](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.Res.html#variant.SelfCtor). +- Only early-bound generic parameters are included, [late-bound generics] are not. +- ... and more... + +Check out [`ty::Generics`] for exact specifics on how the flattening works. + +[`ty::Generics`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Generics.html +[`generics_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.generics_of +[late-bound generics]: ../early-late-parameters.md diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md index 5f695c90e4f77..9e9de6e4daa72 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md @@ -12,16 +12,11 @@ This tracks support for additional registers in architectures where inline assem | Architecture | Register class | Registers | LLVM constraint code | | ------------ | -------------- | --------- | -------------------- | -| s390x | `vreg` | `v[0-31]` | `v` | - -> **Notes**: -> - s390x `vreg` is clobber-only in stable. ## Register class supported types | Architecture | Register class | Target feature | Allowed types | | ------------ | -------------- | -------------- | ------------- | -| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | | x86 | `xmm_reg` | `sse` | `i128` | | x86 | `ymm_reg` | `avx` | `i128` | | x86 | `zmm_reg` | `avx512f` | `i128` | @@ -40,4 +35,3 @@ This tracks support for additional registers in architectures where inline assem | Architecture | Register class | Modifier | Example output | LLVM modifier | | ------------ | -------------- | -------- | -------------- | ------------- | -| s390x | `vreg` | None | `%v0` | None | diff --git a/tests/assembly-llvm/asm/s390x-types.rs b/tests/assembly-llvm/asm/s390x-types.rs index dee7eb553cde8..75bcfd5b026f3 100644 --- a/tests/assembly-llvm/asm/s390x-types.rs +++ b/tests/assembly-llvm/asm/s390x-types.rs @@ -8,7 +8,6 @@ //@ compile-flags: -Zmerge-functions=disabled #![feature(no_core, repr_simd, f16, f128)] -#![cfg_attr(s390x_vector, feature(asm_experimental_reg))] #![crate_type = "rlib"] #![no_core] #![allow(asm_sub_register, non_camel_case_types)] @@ -19,27 +18,17 @@ use minicore::*; type ptr = *const i32; #[repr(simd)] -pub struct i8x16([i8; 16]); -#[repr(simd)] -pub struct i16x8([i16; 8]); -#[repr(simd)] -pub struct i32x4([i32; 4]); -#[repr(simd)] -pub struct i64x2([i64; 2]); -#[repr(simd)] -pub struct f16x8([f16; 8]); -#[repr(simd)] -pub struct f32x4([f32; 4]); -#[repr(simd)] -pub struct f64x2([f64; 2]); - -impl Copy for i8x16 {} -impl Copy for i16x8 {} -impl Copy for i32x4 {} -impl Copy for i64x2 {} -impl Copy for f16x8 {} -impl Copy for f32x4 {} -impl Copy for f64x2 {} +pub struct Simd([T; N]); + +impl Copy for Simd {} + +type i8x16 = Simd; +type i16x8 = Simd; +type i32x4 = Simd; +type i64x2 = Simd; +type f16x8 = Simd; +type f32x4 = Simd; +type f64x2 = Simd; extern "C" { fn extern_func(); diff --git a/tests/codegen-llvm/gpu-convergent.rs b/tests/codegen-llvm/gpu-convergent.rs new file mode 100644 index 0000000000000..bb9271ab69996 --- /dev/null +++ b/tests/codegen-llvm/gpu-convergent.rs @@ -0,0 +1,28 @@ +// Checks that when compiling for GPU targets, the convergent attribute +// is added to function declarations and definitions. + +//@ add-minicore +//@ revisions: amdgpu nvptx +//@ [amdgpu] compile-flags: --crate-type=rlib --target=amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [nvptx] compile-flags: --crate-type=rlib --target=nvptx64-nvidia-cuda +//@ [nvptx] needs-llvm-components: nvptx +#![feature(no_core, lang_items, abi_gpu_kernel)] +#![no_core] + +extern crate minicore; +use minicore::*; + +extern "C" { + fn ext(); +} + +// CHECK: define {{.*}}_kernel void @fun(i32{{.*}}) unnamed_addr #[[ATTR:[0-9]+]] { +// CHECK: declare void @ext() unnamed_addr #[[ATTR]] +// CHECK: attributes #[[ATTR]] = {{.*}} convergent +#[no_mangle] +pub extern "gpu-kernel" fn fun(_: i32) { + unsafe { + ext(); + } +} diff --git a/tests/ui/asm/s390x/bad-reg.rs b/tests/ui/asm/s390x/bad-reg.rs index 97b2b3d50b347..5c9edefd710ed 100644 --- a/tests/ui/asm/s390x/bad-reg.rs +++ b/tests/ui/asm/s390x/bad-reg.rs @@ -1,16 +1,13 @@ //@ add-minicore -//@ revisions: s390x s390x_vector s390x_vector_stable +//@ revisions: s390x s390x_vector //@[s390x] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=-vector //@[s390x] needs-llvm-components: systemz //@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector //@[s390x_vector] needs-llvm-components: systemz -//@[s390x_vector_stable] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector -//@[s390x_vector_stable] needs-llvm-components: systemz //@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(no_core, repr_simd)] -#![cfg_attr(not(s390x_vector_stable), feature(asm_experimental_reg))] #![no_core] #![allow(non_camel_case_types)] @@ -73,46 +70,27 @@ fn f() { asm!("", out("v0") _); // always ok asm!("", in("v0") v); // requires vector & asm_experimental_reg //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature - //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658] asm!("", out("v0") v); // requires vector & asm_experimental_reg //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature - //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658] asm!("", in("v0") x); // requires vector & asm_experimental_reg //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature - //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658] asm!("", out("v0") x); // requires vector & asm_experimental_reg //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature - //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658] asm!("", in("v0") b); //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class - //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class asm!("", out("v0") b); //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class - //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature - //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `i64x2` cannot be used with this register class in stable [E0658] asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature - //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `i32` cannot be used with this register class in stable [E0658] asm!("/* {} */", in(vreg) b); //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class - //[s390x_vector_stable]~^^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] - //[s390x_vector_stable]~| ERROR type `u8` cannot be used with this register class asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature - //[s390x_vector_stable]~^^ ERROR register class `vreg` can only be used as a clobber in stable [E0658] // Clobber-only registers // areg diff --git a/tests/ui/asm/s390x/bad-reg.s390x.stderr b/tests/ui/asm/s390x/bad-reg.s390x.stderr index 238419b376b7f..1fc9c08b1a23e 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x.stderr @@ -1,149 +1,149 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:28:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:30:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:60:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:64:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:66:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:101:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:107:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:112:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:114:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:116:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:118:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:120:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:122:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:124:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:126:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:128:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:130:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:132:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:134:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:136:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:138:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:140:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:142:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,73 +271,73 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:145:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:74:18 + --> $DIR/bad-reg.rs:71:18 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:78:18 + --> $DIR/bad-reg.rs:73:18 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:75:18 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:86:18 + --> $DIR/bad-reg.rs:77:18 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:90:18 + --> $DIR/bad-reg.rs:79:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:95:18 + --> $DIR/bad-reg.rs:82:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:85:26 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:104:26 + --> $DIR/bad-reg.rs:87:26 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:108:26 + --> $DIR/bad-reg.rs:89:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:113:26 + --> $DIR/bad-reg.rs:92:26 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:98:27 | LL | asm!("", in("a2") x); | ^ @@ -345,7 +345,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:101:28 | LL | asm!("", out("a2") x); | ^ @@ -353,7 +353,7 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:104:35 | LL | asm!("/* {} */", in(areg) x); | ^ diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr index 8e2da4dcc2a4d..4b02af95768a1 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -1,149 +1,149 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:28:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:30:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:60:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:64:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:66:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:101:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:107:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:112:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:114:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:116:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:118:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:120:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:122:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:124:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:126:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:128:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:130:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:132:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:134:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:136:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:138:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:140:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:142:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,13 +271,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:145:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:90:27 + --> $DIR/bad-reg.rs:79:27 | LL | asm!("", in("v0") b); | ^ @@ -285,7 +285,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:95:28 + --> $DIR/bad-reg.rs:82:28 | LL | asm!("", out("v0") b); | ^ @@ -293,7 +293,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:108:35 + --> $DIR/bad-reg.rs:89:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -301,7 +301,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:98:27 | LL | asm!("", in("a2") x); | ^ @@ -309,7 +309,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:101:28 | LL | asm!("", out("a2") x); | ^ @@ -317,7 +317,7 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:104:35 | LL | asm!("/* {} */", in(areg) x); | ^ diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr deleted file mode 100644 index e2b3eeef4e925..0000000000000 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr +++ /dev/null @@ -1,489 +0,0 @@ -error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 - | -LL | asm!("", out("r11") _); - | ^^^^^^^^^^^^ - -error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 - | -LL | asm!("", out("r15") _); - | ^^^^^^^^^^^^ - -error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 - | -LL | asm!("", out("c0") _); - | ^^^^^^^^^^^ - -error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 - | -LL | asm!("", out("c1") _); - | ^^^^^^^^^^^ - -error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 - | -LL | asm!("", out("c2") _); - | ^^^^^^^^^^^ - -error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 - | -LL | asm!("", out("c3") _); - | ^^^^^^^^^^^ - -error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 - | -LL | asm!("", out("c4") _); - | ^^^^^^^^^^^ - -error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 - | -LL | asm!("", out("c5") _); - | ^^^^^^^^^^^ - -error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 - | -LL | asm!("", out("c6") _); - | ^^^^^^^^^^^ - -error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 - | -LL | asm!("", out("c7") _); - | ^^^^^^^^^^^ - -error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 - | -LL | asm!("", out("c8") _); - | ^^^^^^^^^^^ - -error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 - | -LL | asm!("", out("c9") _); - | ^^^^^^^^^^^ - -error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 - | -LL | asm!("", out("c10") _); - | ^^^^^^^^^^^^ - -error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 - | -LL | asm!("", out("c11") _); - | ^^^^^^^^^^^^ - -error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 - | -LL | asm!("", out("c12") _); - | ^^^^^^^^^^^^ - -error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 - | -LL | asm!("", out("c13") _); - | ^^^^^^^^^^^^ - -error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 - | -LL | asm!("", out("c14") _); - | ^^^^^^^^^^^^ - -error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 - | -LL | asm!("", out("c15") _); - | ^^^^^^^^^^^^ - -error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 - | -LL | asm!("", out("a0") _); - | ^^^^^^^^^^^ - -error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 - | -LL | asm!("", out("a1") _); - | ^^^^^^^^^^^ - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:74:18 - | -LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg - | ^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:78:18 - | -LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg - | ^^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:18 - | -LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg - | ^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:86:18 - | -LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg - | ^^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:90:18 - | -LL | asm!("", in("v0") b); - | ^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:95:18 - | -LL | asm!("", out("v0") b); - | ^^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:100:26 - | -LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg - | ^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:104:26 - | -LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg - | ^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:108:26 - | -LL | asm!("/* {} */", in(vreg) b); - | ^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:113:26 - | -LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg - | ^^^^^^^^^^^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 - | -LL | asm!("", in("a2") x); - | ^^^^^^^^^^ - -error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 - | -LL | asm!("", out("a2") x); - | ^^^^^^^^^^^ - -error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 - | -LL | asm!("/* {} */", in(areg) x); - | ^^^^^^^^^^ - -error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 - | -LL | asm!("/* {} */", out(areg) _); - | ^^^^^^^^^^^ - -error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 - | -LL | asm!("", out("v0") _, out("f0") _); - | ----------- ^^^^^^^^^^^ register `f0` - | | - | register `v0` - -error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 - | -LL | asm!("", out("v1") _, out("f1") _); - | ----------- ^^^^^^^^^^^ register `f1` - | | - | register `v1` - -error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 - | -LL | asm!("", out("v2") _, out("f2") _); - | ----------- ^^^^^^^^^^^ register `f2` - | | - | register `v2` - -error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 - | -LL | asm!("", out("v3") _, out("f3") _); - | ----------- ^^^^^^^^^^^ register `f3` - | | - | register `v3` - -error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 - | -LL | asm!("", out("v4") _, out("f4") _); - | ----------- ^^^^^^^^^^^ register `f4` - | | - | register `v4` - -error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 - | -LL | asm!("", out("v5") _, out("f5") _); - | ----------- ^^^^^^^^^^^ register `f5` - | | - | register `v5` - -error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 - | -LL | asm!("", out("v6") _, out("f6") _); - | ----------- ^^^^^^^^^^^ register `f6` - | | - | register `v6` - -error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 - | -LL | asm!("", out("v7") _, out("f7") _); - | ----------- ^^^^^^^^^^^ register `f7` - | | - | register `v7` - -error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 - | -LL | asm!("", out("v8") _, out("f8") _); - | ----------- ^^^^^^^^^^^ register `f8` - | | - | register `v8` - -error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 - | -LL | asm!("", out("v9") _, out("f9") _); - | ----------- ^^^^^^^^^^^ register `f9` - | | - | register `v9` - -error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 - | -LL | asm!("", out("v10") _, out("f10") _); - | ------------ ^^^^^^^^^^^^ register `f10` - | | - | register `v10` - -error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 - | -LL | asm!("", out("v11") _, out("f11") _); - | ------------ ^^^^^^^^^^^^ register `f11` - | | - | register `v11` - -error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 - | -LL | asm!("", out("v12") _, out("f12") _); - | ------------ ^^^^^^^^^^^^ register `f12` - | | - | register `v12` - -error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 - | -LL | asm!("", out("v13") _, out("f13") _); - | ------------ ^^^^^^^^^^^^ register `f13` - | | - | register `v13` - -error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 - | -LL | asm!("", out("v14") _, out("f14") _); - | ------------ ^^^^^^^^^^^^ register `f14` - | | - | register `v14` - -error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 - | -LL | asm!("", out("v15") _, out("f15") _); - | ------------ ^^^^^^^^^^^^ register `f15` - | | - | register `v15` - -error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 - | -LL | asm!("", out("v16") _, out("f16") _); - | ^^^^^^^^^^^^ - -error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:74:27 - | -LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg - | ^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:78:28 - | -LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg - | ^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:27 - | -LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg - | ^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:86:28 - | -LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg - | ^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:90:27 - | -LL | asm!("", in("v0") b); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:95:28 - | -LL | asm!("", out("v0") b); - | ^ - | - = note: register class `vreg` supports these types: - -error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:100:35 - | -LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg - | ^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:104:35 - | -LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg - | ^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:108:35 - | -LL | asm!("/* {} */", in(vreg) b); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 - | -LL | asm!("", in("a2") x); - | ^ - | - = note: register class `areg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 - | -LL | asm!("", out("a2") x); - | ^ - | - = note: register class `areg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 - | -LL | asm!("/* {} */", in(areg) x); - | ^ - | - = note: register class `areg` supports these types: - -error: aborting due to 63 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/issues/issue-52126-assign-op-invariance.rs b/tests/ui/borrowck/assign-op-invariance-lifetime.rs similarity index 92% rename from tests/ui/issues/issue-52126-assign-op-invariance.rs rename to tests/ui/borrowck/assign-op-invariance-lifetime.rs index c96cfdf3cd164..682346d936cd5 100644 --- a/tests/ui/issues/issue-52126-assign-op-invariance.rs +++ b/tests/ui/borrowck/assign-op-invariance-lifetime.rs @@ -1,4 +1,5 @@ -// Issue 52126: With respect to variance, the assign-op's like += were +//! Test for https://github.com/rust-lang/rust/issues/52126 +// With respect to variance, the assign-op's like += were // accidentally lumped together with other binary op's. In both cases // we were coercing the LHS of the op to the expected supertype. // diff --git a/tests/ui/issues/issue-52126-assign-op-invariance.stderr b/tests/ui/borrowck/assign-op-invariance-lifetime.stderr similarity index 94% rename from tests/ui/issues/issue-52126-assign-op-invariance.stderr rename to tests/ui/borrowck/assign-op-invariance-lifetime.stderr index dd38a1061baaa..e60f67fb28e43 100644 --- a/tests/ui/issues/issue-52126-assign-op-invariance.stderr +++ b/tests/ui/borrowck/assign-op-invariance-lifetime.stderr @@ -1,5 +1,5 @@ error[E0597]: `line` does not live long enough - --> $DIR/issue-52126-assign-op-invariance.rs:34:28 + --> $DIR/assign-op-invariance-lifetime.rs:35:28 | LL | for line in vec!["123456789".to_string(), "12345678".to_string()] { | ---- binding `line` declared here diff --git a/tests/ui/issues/issue-21400.rs b/tests/ui/borrowck/borrow-in-match-with-format-string.rs similarity index 94% rename from tests/ui/issues/issue-21400.rs rename to tests/ui/borrowck/borrow-in-match-with-format-string.rs index 2c4bbe3d3175a..2810df99eb8cf 100644 --- a/tests/ui/issues/issue-21400.rs +++ b/tests/ui/borrowck/borrow-in-match-with-format-string.rs @@ -1,5 +1,5 @@ //@ run-pass -// Regression test for #21400 which itself was extracted from +// Test for https://github.com/rust-lang/rust/issues/21400 extracted from // stackoverflow.com/questions/28031155/is-my-borrow-checker-drunk/28031580 fn main() { diff --git a/tests/ui/issues/issue-45697.rs b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-off.rs similarity index 91% rename from tests/ui/issues/issue-45697.rs rename to tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-off.rs index 653924077684b..ef9012eaddd4b 100644 --- a/tests/ui/issues/issue-45697.rs +++ b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-off.rs @@ -1,3 +1,4 @@ +// Issue link https://github.com/rust-lang/rust/issues/45697 // Test that assignments to an `&mut` pointer which is found in a // borrowed (but otherwise non-aliasable) location is illegal. diff --git a/tests/ui/issues/issue-45697.stderr b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-off.stderr similarity index 88% rename from tests/ui/issues/issue-45697.stderr rename to tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-off.stderr index 7986fd5c9df2e..b265fc1f76150 100644 --- a/tests/ui/issues/issue-45697.stderr +++ b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-off.stderr @@ -1,5 +1,5 @@ error[E0503]: cannot use `*y.pointer` because it was mutably borrowed - --> $DIR/issue-45697.rs:20:9 + --> $DIR/borrowed-mut-pointer-assign-overflow-off.rs:21:9 | LL | let z = copy_borrowed_ptr(&mut y); | ------ `y` is borrowed here @@ -10,7 +10,7 @@ LL | *z.pointer += 1; | --------------- borrow later used here error[E0506]: cannot assign to `*y.pointer` because it is borrowed - --> $DIR/issue-45697.rs:20:9 + --> $DIR/borrowed-mut-pointer-assign-overflow-off.rs:21:9 | LL | let z = copy_borrowed_ptr(&mut y); | ------ `*y.pointer` is borrowed here diff --git a/tests/ui/issues/issue-45697-1.rs b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-on.rs similarity index 91% rename from tests/ui/issues/issue-45697-1.rs rename to tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-on.rs index 53e5559968969..2b117c56d3787 100644 --- a/tests/ui/issues/issue-45697-1.rs +++ b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-on.rs @@ -1,3 +1,4 @@ +// Issue link https://github.com/rust-lang/rust/issues/45697 // Test that assignments to an `&mut` pointer which is found in a // borrowed (but otherwise non-aliasable) location is illegal. diff --git a/tests/ui/issues/issue-45697-1.stderr b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-on.stderr similarity index 88% rename from tests/ui/issues/issue-45697-1.stderr rename to tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-on.stderr index 474313398e2bc..529023f98b1af 100644 --- a/tests/ui/issues/issue-45697-1.stderr +++ b/tests/ui/borrowck/borrowed-mut-pointer-assign-overflow-on.stderr @@ -1,5 +1,5 @@ error[E0503]: cannot use `*y.pointer` because it was mutably borrowed - --> $DIR/issue-45697-1.rs:20:9 + --> $DIR/borrowed-mut-pointer-assign-overflow-on.rs:21:9 | LL | let z = copy_borrowed_ptr(&mut y); | ------ `y` is borrowed here @@ -10,7 +10,7 @@ LL | *z.pointer += 1; | --------------- borrow later used here error[E0506]: cannot assign to `*y.pointer` because it is borrowed - --> $DIR/issue-45697-1.rs:20:9 + --> $DIR/borrowed-mut-pointer-assign-overflow-on.rs:21:9 | LL | let z = copy_borrowed_ptr(&mut y); | ------ `*y.pointer` is borrowed here diff --git a/tests/ui/issues/issue-41498.rs b/tests/ui/borrowck/call-and-ref-option-mutate.rs similarity index 78% rename from tests/ui/issues/issue-41498.rs rename to tests/ui/borrowck/call-and-ref-option-mutate.rs index 57f36b27d3c25..104699a2b3cfc 100644 --- a/tests/ui/issues/issue-41498.rs +++ b/tests/ui/borrowck/call-and-ref-option-mutate.rs @@ -1,6 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/41498 //@ run-pass -// regression test for issue #41498. - struct S; impl S { fn mutate(&mut self) {} diff --git a/tests/ui/issues/issue-40288.rs b/tests/ui/borrowck/cannot-assign-borrowed-ref-in-slice.rs similarity index 85% rename from tests/ui/issues/issue-40288.rs rename to tests/ui/borrowck/cannot-assign-borrowed-ref-in-slice.rs index 60204c1175476..97d2f690b6245 100644 --- a/tests/ui/issues/issue-40288.rs +++ b/tests/ui/borrowck/cannot-assign-borrowed-ref-in-slice.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/40288 fn save_ref<'a>(refr: &'a i32, to: &mut [&'a i32]) { for val in &mut *to { *val = refr; diff --git a/tests/ui/issues/issue-40288.stderr b/tests/ui/borrowck/cannot-assign-borrowed-ref-in-slice.stderr similarity index 89% rename from tests/ui/issues/issue-40288.stderr rename to tests/ui/borrowck/cannot-assign-borrowed-ref-in-slice.stderr index 180adcd6e99bc..c4371d9d9cc90 100644 --- a/tests/ui/issues/issue-40288.stderr +++ b/tests/ui/borrowck/cannot-assign-borrowed-ref-in-slice.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `*refr` because it is borrowed - --> $DIR/issue-40288.rs:16:5 + --> $DIR/cannot-assign-borrowed-ref-in-slice.rs:17:5 | LL | save_ref(&*refr, &mut out); | ------ `*refr` is borrowed here diff --git a/tests/ui/issues/issue-41726.rs b/tests/ui/borrowck/cannot-borrow-index-of-hashmap-in-for.rs similarity index 76% rename from tests/ui/issues/issue-41726.rs rename to tests/ui/borrowck/cannot-borrow-index-of-hashmap-in-for.rs index 39631912c00e7..cd403172704f8 100644 --- a/tests/ui/issues/issue-41726.rs +++ b/tests/ui/borrowck/cannot-borrow-index-of-hashmap-in-for.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/41726 use std::collections::HashMap; fn main() { let things: HashMap> = HashMap::new(); diff --git a/tests/ui/issues/issue-41726.stderr b/tests/ui/borrowck/cannot-borrow-index-of-hashmap-in-for.stderr similarity index 91% rename from tests/ui/issues/issue-41726.stderr rename to tests/ui/borrowck/cannot-borrow-index-of-hashmap-in-for.stderr index d5123ab679f8b..64dd3a752fd91 100644 --- a/tests/ui/issues/issue-41726.stderr +++ b/tests/ui/borrowck/cannot-borrow-index-of-hashmap-in-for.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow data in an index of `HashMap>` as mutable - --> $DIR/issue-41726.rs:5:9 + --> $DIR/cannot-borrow-index-of-hashmap-in-for.rs:6:9 | LL | things[src.as_str()].sort(); | ^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/issues/issue-44405.rs b/tests/ui/borrowck/cannot-borrow-index-output-mutably.rs similarity index 84% rename from tests/ui/issues/issue-44405.rs rename to tests/ui/borrowck/cannot-borrow-index-output-mutably.rs index d404b9044dd6f..e2391d37734ac 100644 --- a/tests/ui/issues/issue-44405.rs +++ b/tests/ui/borrowck/cannot-borrow-index-output-mutably.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/44405 use std::ops::Index; struct Test; diff --git a/tests/ui/issues/issue-44405.stderr b/tests/ui/borrowck/cannot-borrow-index-output-mutably.stderr similarity index 87% rename from tests/ui/issues/issue-44405.stderr rename to tests/ui/borrowck/cannot-borrow-index-output-mutably.stderr index 26d2b385efa28..174a1ad0be54c 100644 --- a/tests/ui/issues/issue-44405.stderr +++ b/tests/ui/borrowck/cannot-borrow-index-output-mutably.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow data in an index of `Container` as mutable - --> $DIR/issue-44405.rs:21:5 + --> $DIR/cannot-borrow-index-output-mutably.rs:22:5 | LL | container[&mut val].test(); | ^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/issues/issue-4335.rs b/tests/ui/borrowck/cannot-move-out-of-borrowed-ref-closure.rs similarity index 76% rename from tests/ui/issues/issue-4335.rs rename to tests/ui/borrowck/cannot-move-out-of-borrowed-ref-closure.rs index c5914a17cf924..337ffcfa360b2 100644 --- a/tests/ui/issues/issue-4335.rs +++ b/tests/ui/borrowck/cannot-move-out-of-borrowed-ref-closure.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/4335 #![feature(fn_traits)] fn id(t: T) -> T { t } diff --git a/tests/ui/issues/issue-4335.stderr b/tests/ui/borrowck/cannot-move-out-of-borrowed-ref-closure.stderr similarity index 89% rename from tests/ui/issues/issue-4335.stderr rename to tests/ui/borrowck/cannot-move-out-of-borrowed-ref-closure.stderr index d1a64e3dd4620..d2f1dd21794a8 100644 --- a/tests/ui/issues/issue-4335.stderr +++ b/tests/ui/borrowck/cannot-move-out-of-borrowed-ref-closure.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `*v`, as `v` is a captured variable in an `FnMut` closure - --> $DIR/issue-4335.rs:6:20 + --> $DIR/cannot-move-out-of-borrowed-ref-closure.rs:7:20 | LL | fn f<'r, T>(v: &'r T) -> Box T + 'r> { | - ----- move occurs because `*v` has type `T`, which does not implement the `Copy` trait @@ -12,7 +12,7 @@ LL | id(Box::new(|| *v)) | = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but `FnOnce` closures may consume them only once help: if `T` implemented `Clone`, you could clone the value - --> $DIR/issue-4335.rs:5:10 + --> $DIR/cannot-move-out-of-borrowed-ref-closure.rs:6:10 | LL | fn f<'r, T>(v: &'r T) -> Box T + 'r> { | ^ consider constraining this type parameter with `Clone` diff --git a/tests/ui/issues/issue-26619.rs b/tests/ui/borrowck/cannot-return-ref-to-fn-param-in-filter-map.rs similarity index 89% rename from tests/ui/issues/issue-26619.rs rename to tests/ui/borrowck/cannot-return-ref-to-fn-param-in-filter-map.rs index b9d34b0555aee..2553e120edcc7 100644 --- a/tests/ui/issues/issue-26619.rs +++ b/tests/ui/borrowck/cannot-return-ref-to-fn-param-in-filter-map.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/26619 pub struct History<'a> { pub _s: &'a str } impl<'a> History<'a> { diff --git a/tests/ui/issues/issue-26619.stderr b/tests/ui/borrowck/cannot-return-ref-to-fn-param-in-filter-map.stderr similarity index 90% rename from tests/ui/issues/issue-26619.stderr rename to tests/ui/borrowck/cannot-return-ref-to-fn-param-in-filter-map.stderr index 9175bd2a3032c..4b3df02d852c0 100644 --- a/tests/ui/issues/issue-26619.stderr +++ b/tests/ui/borrowck/cannot-return-ref-to-fn-param-in-filter-map.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing function parameter - --> $DIR/issue-26619.rs:5:76 + --> $DIR/cannot-return-ref-to-fn-param-in-filter-map.rs:6:76 | LL | for s in vec!["1|2".to_string()].into_iter().filter_map(|ref line| self.make_entry(line)) { | -------- ^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function diff --git a/tests/ui/issues/issue-27592.rs b/tests/ui/borrowck/cannot-return-ref-to-temporary-format-args.rs similarity index 100% rename from tests/ui/issues/issue-27592.rs rename to tests/ui/borrowck/cannot-return-ref-to-temporary-format-args.rs diff --git a/tests/ui/issues/issue-27592.stderr b/tests/ui/borrowck/cannot-return-ref-to-temporary-format-args.stderr similarity index 85% rename from tests/ui/issues/issue-27592.stderr rename to tests/ui/borrowck/cannot-return-ref-to-temporary-format-args.stderr index f1de7b9e569da..ec30560130dad 100644 --- a/tests/ui/issues/issue-27592.stderr +++ b/tests/ui/borrowck/cannot-return-ref-to-temporary-format-args.stderr @@ -1,11 +1,11 @@ error[E0515]: cannot return reference to temporary value - --> $DIR/issue-27592.rs:16:14 + --> $DIR/cannot-return-ref-to-temporary-format-args.rs:16:14 | LL | write(|| format_args!("{}", String::from("Hello world"))); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function error[E0515]: cannot return value referencing temporary value - --> $DIR/issue-27592.rs:16:14 + --> $DIR/cannot-return-ref-to-temporary-format-args.rs:16:14 | LL | write(|| format_args!("{}", String::from("Hello world"))); | ^^^^^^^^^^^^^^^^^^^---------------------------^ diff --git a/tests/ui/issues/issue-18566.rs b/tests/ui/borrowck/deref-and-mut-borrow-conflict.rs similarity index 85% rename from tests/ui/issues/issue-18566.rs rename to tests/ui/borrowck/deref-and-mut-borrow-conflict.rs index 9da904acf1f2b..387422986be78 100644 --- a/tests/ui/issues/issue-18566.rs +++ b/tests/ui/borrowck/deref-and-mut-borrow-conflict.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18566 use std::ops::Deref; struct MyPtr<'a>(&'a mut usize); diff --git a/tests/ui/issues/issue-18566.stderr b/tests/ui/borrowck/deref-and-mut-borrow-conflict.stderr similarity index 88% rename from tests/ui/issues/issue-18566.stderr rename to tests/ui/borrowck/deref-and-mut-borrow-conflict.stderr index e8ec48b0d2696..8dc6e2901b6e3 100644 --- a/tests/ui/issues/issue-18566.stderr +++ b/tests/ui/borrowck/deref-and-mut-borrow-conflict.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `*s` as mutable more than once at a time - --> $DIR/issue-18566.rs:23:19 + --> $DIR/deref-and-mut-borrow-conflict.rs:24:19 | LL | MyPtr(s).poke(s); | - ---- ^ second mutable borrow occurs here diff --git a/tests/ui/issues/issue-28971.rs b/tests/ui/borrowck/fnmut-borrow-error-in-closure-match.rs similarity index 81% rename from tests/ui/issues/issue-28971.rs rename to tests/ui/borrowck/fnmut-borrow-error-in-closure-match.rs index e6a504f52e0cd..4288155202dc3 100644 --- a/tests/ui/issues/issue-28971.rs +++ b/tests/ui/borrowck/fnmut-borrow-error-in-closure-match.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/28971 enum Foo { Bar(u8) } diff --git a/tests/ui/issues/issue-28971.stderr b/tests/ui/borrowck/fnmut-borrow-error-in-closure-match.stderr similarity index 89% rename from tests/ui/issues/issue-28971.stderr rename to tests/ui/borrowck/fnmut-borrow-error-in-closure-match.stderr index de3fff0a49e30..925d12fe90f04 100644 --- a/tests/ui/issues/issue-28971.stderr +++ b/tests/ui/borrowck/fnmut-borrow-error-in-closure-match.stderr @@ -1,5 +1,5 @@ error[E0599]: no variant, associated function, or constant named `Baz` found for enum `Foo` in the current scope - --> $DIR/issue-28971.rs:7:18 + --> $DIR/fnmut-borrow-error-in-closure-match.rs:8:18 | LL | enum Foo { | -------- variant, associated function, or constant `Baz` not found for this enum @@ -14,7 +14,7 @@ LL + Foo::Bar(..) => (), | error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable - --> $DIR/issue-28971.rs:15:5 + --> $DIR/fnmut-borrow-error-in-closure-match.rs:16:5 | LL | f(); | ^ cannot borrow as mutable diff --git a/tests/ui/issues/issue-42106.rs b/tests/ui/borrowck/immutable-borrow-prevents-mut-method.rs similarity index 78% rename from tests/ui/issues/issue-42106.rs rename to tests/ui/borrowck/immutable-borrow-prevents-mut-method.rs index 5e688693bf9ed..9803a72fb4b6a 100644 --- a/tests/ui/issues/issue-42106.rs +++ b/tests/ui/borrowck/immutable-borrow-prevents-mut-method.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/42106 fn do_something(collection: &mut Vec) { let _a = &collection; collection.swap(1, 2); //~ ERROR also borrowed as immutable diff --git a/tests/ui/issues/issue-42106.stderr b/tests/ui/borrowck/immutable-borrow-prevents-mut-method.stderr similarity index 89% rename from tests/ui/issues/issue-42106.stderr rename to tests/ui/borrowck/immutable-borrow-prevents-mut-method.stderr index d5919870d9be2..0d9a7a96ed8f4 100644 --- a/tests/ui/issues/issue-42106.stderr +++ b/tests/ui/borrowck/immutable-borrow-prevents-mut-method.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `*collection` as mutable because it is also borrowed as immutable - --> $DIR/issue-42106.rs:3:5 + --> $DIR/immutable-borrow-prevents-mut-method.rs:4:5 | LL | let _a = &collection; | ----------- immutable borrow occurs here diff --git a/tests/ui/issues/issue-18783.rs b/tests/ui/borrowck/mut-borrow-conflict-in-closures-vec.rs similarity index 90% rename from tests/ui/issues/issue-18783.rs rename to tests/ui/borrowck/mut-borrow-conflict-in-closures-vec.rs index d4851ac14187e..cccf1c4047794 100644 --- a/tests/ui/issues/issue-18783.rs +++ b/tests/ui/borrowck/mut-borrow-conflict-in-closures-vec.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18783 use std::cell::RefCell; fn main() { diff --git a/tests/ui/issues/issue-18783.stderr b/tests/ui/borrowck/mut-borrow-conflict-in-closures-vec.stderr similarity index 92% rename from tests/ui/issues/issue-18783.stderr rename to tests/ui/borrowck/mut-borrow-conflict-in-closures-vec.stderr index cc223ac464c8c..6c99692a79950 100644 --- a/tests/ui/issues/issue-18783.stderr +++ b/tests/ui/borrowck/mut-borrow-conflict-in-closures-vec.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `y` as mutable more than once at a time - --> $DIR/issue-18783.rs:7:21 + --> $DIR/mut-borrow-conflict-in-closures-vec.rs:8:21 | LL | c.push(Box::new(|| y = 0)); | -- - first borrow occurs due to use of `y` in closure @@ -14,7 +14,7 @@ LL | } | - first borrow might be used here, when `c` is dropped and runs the destructor for type `RefCell>>` error[E0499]: cannot borrow `y` as mutable more than once at a time - --> $DIR/issue-18783.rs:16:29 + --> $DIR/mut-borrow-conflict-in-closures-vec.rs:17:29 | LL | Push::push(&c, Box::new(|| y = 0)); | -- - first borrow occurs due to use of `y` in closure diff --git a/tests/ui/issues/issue-25579.rs b/tests/ui/borrowck/reborrow-in-loop-match-recursive-enum.rs similarity index 83% rename from tests/ui/issues/issue-25579.rs rename to tests/ui/borrowck/reborrow-in-loop-match-recursive-enum.rs index f4bbb41469e18..77c43ff01fa04 100644 --- a/tests/ui/issues/issue-25579.rs +++ b/tests/ui/borrowck/reborrow-in-loop-match-recursive-enum.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/25579 //@ check-pass enum Sexpression { diff --git a/tests/ui/issues/issue-28839.rs b/tests/ui/borrowck/reborrow-in-match-ref-mut-option.rs similarity index 80% rename from tests/ui/issues/issue-28839.rs rename to tests/ui/borrowck/reborrow-in-match-ref-mut-option.rs index 76b0fa2d6e089..001921228d994 100644 --- a/tests/ui/issues/issue-28839.rs +++ b/tests/ui/borrowck/reborrow-in-match-ref-mut-option.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/28839 //@ run-pass pub struct Foo; diff --git a/tests/ui/issues/issue-29053.rs b/tests/ui/borrowck/ref-mut-rebind-does-not-affect-outer.rs similarity index 71% rename from tests/ui/issues/issue-29053.rs rename to tests/ui/borrowck/ref-mut-rebind-does-not-affect-outer.rs index 3b61dc1152214..6748442be1306 100644 --- a/tests/ui/issues/issue-29053.rs +++ b/tests/ui/borrowck/ref-mut-rebind-does-not-affect-outer.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/29053 //@ run-pass fn main() { let x: &'static str = "x"; diff --git a/tests/ui/issues/issue-47703.rs b/tests/ui/borrowck/self-field-consume-with-drop-type.rs similarity index 77% rename from tests/ui/issues/issue-47703.rs rename to tests/ui/borrowck/self-field-consume-with-drop-type.rs index deece30098719..b21c676881229 100644 --- a/tests/ui/issues/issue-47703.rs +++ b/tests/ui/borrowck/self-field-consume-with-drop-type.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/47703 //@ check-pass struct MyStruct<'a> { diff --git a/tests/ui/issues/issue-47703-1.rs b/tests/ui/borrowck/struct-field-move-with-drop-borrow.rs similarity index 82% rename from tests/ui/issues/issue-47703-1.rs rename to tests/ui/borrowck/struct-field-move-with-drop-borrow.rs index 9913d1fefe080..3e40e382e5305 100644 --- a/tests/ui/issues/issue-47703-1.rs +++ b/tests/ui/borrowck/struct-field-move-with-drop-borrow.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/47703 //@ check-pass struct AtomicRefMut<'a> { diff --git a/tests/ui/issues/issue-47703-tuple.rs b/tests/ui/borrowck/tuple-field-move-with-drop-borrow.rs similarity index 68% rename from tests/ui/issues/issue-47703-tuple.rs rename to tests/ui/borrowck/tuple-field-move-with-drop-borrow.rs index 17a0da8c5f8e0..4b94c32bdd3aa 100644 --- a/tests/ui/issues/issue-47703-tuple.rs +++ b/tests/ui/borrowck/tuple-field-move-with-drop-borrow.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/47703 //@ check-pass struct WithDrop; diff --git a/tests/ui/issues/issue-29723.rs b/tests/ui/borrowck/use-moved-value-in-match-guard-drop.rs similarity index 100% rename from tests/ui/issues/issue-29723.rs rename to tests/ui/borrowck/use-moved-value-in-match-guard-drop.rs diff --git a/tests/ui/issues/issue-29723.stderr b/tests/ui/borrowck/use-moved-value-in-match-guard-drop.stderr similarity index 92% rename from tests/ui/issues/issue-29723.stderr rename to tests/ui/borrowck/use-moved-value-in-match-guard-drop.stderr index 6a4a8fc453eda..b7aafb07a0c4b 100644 --- a/tests/ui/issues/issue-29723.stderr +++ b/tests/ui/borrowck/use-moved-value-in-match-guard-drop.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `s` - --> $DIR/issue-29723.rs:10:13 + --> $DIR/use-moved-value-in-match-guard-drop.rs:10:13 | LL | let s = String::new(); | - move occurs because `s` has type `String`, which does not implement the `Copy` trait @@ -16,7 +16,7 @@ LL | 0 if { drop(s.clone()); false } => String::from("oops"), | ++++++++ error[E0382]: use of moved value: `s` - --> $DIR/issue-29723.rs:18:14 + --> $DIR/use-moved-value-in-match-guard-drop.rs:18:14 | LL | let s = String::new(); | - move occurs because `s` has type `String`, which does not implement the `Copy` trait diff --git a/tests/ui/dyn-compatibility/unsafe-binders-bare-trait-object-next-solver.rs b/tests/ui/dyn-compatibility/unsafe-binders-bare-trait-object-next-solver.rs new file mode 100644 index 0000000000000..27bf1d1494155 --- /dev/null +++ b/tests/ui/dyn-compatibility/unsafe-binders-bare-trait-object-next-solver.rs @@ -0,0 +1,23 @@ +//! Regression test for +//@ edition: 2024 +//@ compile-flags: -Znext-solver=globally + +#![feature(unsafe_binders)] + +use std::ops::Deref; + +trait Foo: Deref &'a dyn Bar> { + fn method(self: &unsafe<'ops> &'a Bar) {} + //~^ ERROR expected a type, found a trait + //~| ERROR use of undeclared lifetime name `'a` +} + +trait Bar {} + +fn test(x: &dyn Foo) { + //~^ ERROR the trait `Foo` is not dyn compatible + x.method(); + //~^ ERROR no method named `method` found for reference `&dyn Foo` +} + +fn main() {} diff --git a/tests/ui/dyn-compatibility/unsafe-binders-bare-trait-object-next-solver.stderr b/tests/ui/dyn-compatibility/unsafe-binders-bare-trait-object-next-solver.stderr new file mode 100644 index 0000000000000..6ca8ec6bd1a5a --- /dev/null +++ b/tests/ui/dyn-compatibility/unsafe-binders-bare-trait-object-next-solver.stderr @@ -0,0 +1,62 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/unsafe-binders-bare-trait-object-next-solver.rs:10:36 + | +LL | fn method(self: &unsafe<'ops> &'a Bar) {} + | ^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | fn method(self: &unsafe<'a, 'ops> &'a Bar) {} + | +++ +help: consider introducing lifetime `'a` here + | +LL | fn method<'a>(self: &unsafe<'ops> &'a Bar) {} + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait Foo<'a>: Deref &'a dyn Bar> { + | ++++ + +error[E0782]: expected a type, found a trait + --> $DIR/unsafe-binders-bare-trait-object-next-solver.rs:10:39 + | +LL | fn method(self: &unsafe<'ops> &'a Bar) {} + | ^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | fn method(self: &unsafe<'ops> &'a dyn Bar) {} + | +++ + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/unsafe-binders-bare-trait-object-next-solver.rs:17:13 + | +LL | fn method(self: &unsafe<'ops> &'a Bar) {} + | --------------------- help: consider changing method `method`'s `self` parameter to be `&self`: `&Self` +... +LL | fn test(x: &dyn Foo) { + | ^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/unsafe-binders-bare-trait-object-next-solver.rs:10:21 + | +LL | trait Foo: Deref &'a dyn Bar> { + | --- this trait is not dyn compatible... +LL | fn method(self: &unsafe<'ops> &'a Bar) {} + | ^^^^^^^^^^^^^^^^^^^^^ ...because method `method`'s `self` parameter cannot be dispatched on + +error[E0599]: no method named `method` found for reference `&dyn Foo` in the current scope + --> $DIR/unsafe-binders-bare-trait-object-next-solver.rs:19:7 + | +LL | fn method(self: &unsafe<'ops> &'a Bar) {} + | --------------------- the method might not be found because of this arbitrary self type +... +LL | x.method(); + | ^^^^^^ method not found in `&dyn Foo` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0038, E0261, E0599, E0782. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/error-codes/E0423-struct-literal-comment.rs b/tests/ui/error-codes/E0423-struct-literal-comment.rs new file mode 100644 index 0000000000000..f22d27ac37680 --- /dev/null +++ b/tests/ui/error-codes/E0423-struct-literal-comment.rs @@ -0,0 +1,18 @@ +#[derive(PartialEq)] +struct T { pub x: i32 } + +#[derive(PartialEq)] +struct U { } + +fn main() { + // Parser will report an error here + if T { x: 10 } == T {} {} + //~^ ERROR struct literals are not allowed here + //~| ERROR expected value, found struct `T` + + // Regression test for the `followed_by_brace` helper: + // comments inside the braces should not suppress the parenthesized struct literal suggestion. + if U { /* keep comment here */ } == U {} + //~^ ERROR E0423 + //~| ERROR expected expression, found `==` +} diff --git a/tests/ui/error-codes/E0423-struct-literal-comment.stderr b/tests/ui/error-codes/E0423-struct-literal-comment.stderr new file mode 100644 index 0000000000000..952200a753ebe --- /dev/null +++ b/tests/ui/error-codes/E0423-struct-literal-comment.stderr @@ -0,0 +1,42 @@ +error: struct literals are not allowed here + --> $DIR/E0423-struct-literal-comment.rs:9:8 + | +LL | if T { x: 10 } == T {} {} + | ^^^^^^^^^^^ + | +help: surround the struct literal with parentheses + | +LL | if (T { x: 10 }) == T {} {} + | + + + +error: expected expression, found `==` + --> $DIR/E0423-struct-literal-comment.rs:15:38 + | +LL | if U { /* keep comment here */ } == U {} + | ^^ expected expression + +error[E0423]: expected value, found struct `T` + --> $DIR/E0423-struct-literal-comment.rs:9:23 + | +LL | if T { x: 10 } == T {} {} + | ^ not a value + | +help: surround the struct literal with parentheses + | +LL | if T { x: 10 } == (T {}) {} + | + + + +error[E0423]: expected value, found struct `U` + --> $DIR/E0423-struct-literal-comment.rs:15:8 + | +LL | if U { /* keep comment here */ } == U {} + | ^ not a value + | +help: surround the struct literal with parentheses + | +LL | if (U { /* keep comment here */ }) == U {} + | + + + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs index 7794bdc30b347..bfc79ae8db663 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs @@ -1,6 +1,6 @@ //@ add-minicore -//@ compile-flags: --target s390x-unknown-linux-gnu -//@ needs-llvm-components: systemz +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 //@ ignore-backends: gcc #![feature(no_core, lang_items, rustc_attrs)] @@ -11,7 +11,6 @@ extern crate minicore; use minicore::*; unsafe fn main() { - asm!("", in("v0") 0); - //~^ ERROR register class `vreg` can only be used as a clobber in stable - //~| ERROR type `i32` cannot be used with this register class + asm!("{:x}", in(xmm_reg) 0u128); + //~^ ERROR type `u128` cannot be used with this register class in stable } diff --git a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr index 6f2ea0ddaec16..4042ee7029b53 100644 --- a/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr +++ b/tests/ui/feature-gates/feature-gate-asm_experimental_reg.stderr @@ -1,23 +1,13 @@ -error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/feature-gate-asm_experimental_reg.rs:14:14 +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/feature-gate-asm_experimental_reg.rs:14:30 | -LL | asm!("", in("v0") 0); - | ^^^^^^^^^^ +LL | asm!("{:x}", in(xmm_reg) 0u128); + | ^^^^^ | = note: see issue #133416 for more information = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/feature-gate-asm_experimental_reg.rs:14:23 - | -LL | asm!("", in("v0") 0); - | ^ - | - = note: see issue #133416 for more information - = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/field_representing_types/invariant.next.stderr b/tests/ui/field_representing_types/invariant.next.stderr new file mode 100644 index 0000000000000..6a622a8e5dd11 --- /dev/null +++ b/tests/ui/field_representing_types/invariant.next.stderr @@ -0,0 +1,34 @@ +error: lifetime may not live long enough + --> $DIR/invariant.rs:15:5 + | +LL | fn assert_invariant<'a, 'b>(x: field_of!(Struct<'a>, field), y: field_of!(Struct<'b>, field)) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | consume(x, y); + | ^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type `field_of!(Struct<'_>, field)`, which makes the generic argument `Struct<'_>` invariant + = note: the struct `FieldRepresentingType` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/invariant.rs:15:5 + | +LL | fn assert_invariant<'a, 'b>(x: field_of!(Struct<'a>, field), y: field_of!(Struct<'b>, field)) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | consume(x, y); + | ^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type `field_of!(Struct<'_>, field)`, which makes the generic argument `Struct<'_>` invariant + = note: the struct `FieldRepresentingType` is invariant over the parameter `T` + = help: see for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other + +error: aborting due to 2 previous errors + diff --git a/tests/ui/field_representing_types/invariant.old.stderr b/tests/ui/field_representing_types/invariant.old.stderr new file mode 100644 index 0000000000000..6a622a8e5dd11 --- /dev/null +++ b/tests/ui/field_representing_types/invariant.old.stderr @@ -0,0 +1,34 @@ +error: lifetime may not live long enough + --> $DIR/invariant.rs:15:5 + | +LL | fn assert_invariant<'a, 'b>(x: field_of!(Struct<'a>, field), y: field_of!(Struct<'b>, field)) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | consume(x, y); + | ^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type `field_of!(Struct<'_>, field)`, which makes the generic argument `Struct<'_>` invariant + = note: the struct `FieldRepresentingType` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/invariant.rs:15:5 + | +LL | fn assert_invariant<'a, 'b>(x: field_of!(Struct<'a>, field), y: field_of!(Struct<'b>, field)) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | consume(x, y); + | ^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type `field_of!(Struct<'_>, field)`, which makes the generic argument `Struct<'_>` invariant + = note: the struct `FieldRepresentingType` is invariant over the parameter `T` + = help: see for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other + +error: aborting due to 2 previous errors + diff --git a/tests/ui/field_representing_types/invariant.rs b/tests/ui/field_representing_types/invariant.rs new file mode 100644 index 0000000000000..16a45e63c79c5 --- /dev/null +++ b/tests/ui/field_representing_types/invariant.rs @@ -0,0 +1,20 @@ +//@ revisions: old next +//@ [next] compile-flags: -Znext-solver +#![expect(incomplete_features)] +#![feature(field_projections)] + +use std::field::field_of; + +pub struct Struct<'a> { + field: &'a (), +} + +fn consume<'a>(_: field_of!(Struct<'a>, field), _: field_of!(Struct<'a>, field)) {} + +fn assert_invariant<'a, 'b>(x: field_of!(Struct<'a>, field), y: field_of!(Struct<'b>, field)) { + consume(x, y); + //~^ ERROR: lifetime may not live long enough + //~^^ ERROR: lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/never_type/regress/builtin_derives_on_adts_with_never.rs b/tests/ui/never_type/regress/builtin_derives_on_adts_with_never.rs new file mode 100644 index 0000000000000..2a57c6023adce --- /dev/null +++ b/tests/ui/never_type/regress/builtin_derives_on_adts_with_never.rs @@ -0,0 +1,20 @@ +// Regression test for . +// +//@ check-pass +#![feature(never_type)] +#![crate_type = "lib"] +#![warn(unreachable_code)] + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub struct S(!); + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub struct S2 { + f: !, +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum E { + E2(!), + E3 { f: ! }, +} diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index 046c0d5f6588f..68a1bebf6b132 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr @@ -569,6 +569,7 @@ note: `Result` defined here = note: not covered = note: the matched value is of type `Result` = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ Err(_) => {}, diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index ba158c1176b35..320959534e522 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr @@ -569,6 +569,7 @@ note: `Result` defined here = note: not covered = note: the matched value is of type `Result` = note: `!` is uninhabited but is not being matched by value, so a wildcard `_` is required + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ Err(_) => {}, diff --git a/tests/ui/pattern/usefulness/guards.stderr b/tests/ui/pattern/usefulness/guards.stderr index 82ed2a93c55f5..8907fd155f5df 100644 --- a/tests/ui/pattern/usefulness/guards.stderr +++ b/tests/ui/pattern/usefulness/guards.stderr @@ -5,6 +5,7 @@ LL | match 0u8 { | ^^^ pattern `128_u8..=u8::MAX` not covered | = note: the matched value is of type `u8` + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ 128 ..= 255 if true => {}, diff --git a/tests/ui/pattern/usefulness/issue-30240.stderr b/tests/ui/pattern/usefulness/issue-30240.stderr index da8bbdffbf6d5..d592d3110adb5 100644 --- a/tests/ui/pattern/usefulness/issue-30240.stderr +++ b/tests/ui/pattern/usefulness/issue-30240.stderr @@ -20,6 +20,7 @@ LL | match "world" { | = note: the matched value is of type `&str` = note: `&str` cannot be matched exhaustively, so a wildcard `_` is necessary + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ "hello" => {}, diff --git a/tests/ui/pattern/usefulness/issue-72377.rs b/tests/ui/pattern/usefulness/issue-72377.rs index 782a9963f2e5d..61a74fa68f905 100644 --- a/tests/ui/pattern/usefulness/issue-72377.rs +++ b/tests/ui/pattern/usefulness/issue-72377.rs @@ -9,6 +9,7 @@ fn main() { //~^ ERROR non-exhaustive patterns: `(X::A, Some(X::A))`, `(X::A, Some(X::B))`, `(X::B, Some(X::B))` and 2 //~| NOTE more not covered //~| NOTE the matched value is of type `(X, Option)` + //~| NOTE match arms with guards don't count towards exhaustivity (_, None) => false, (v, Some(w)) if v == w => true, (X::B, Some(X::C)) => false, diff --git a/tests/ui/pattern/usefulness/issue-72377.stderr b/tests/ui/pattern/usefulness/issue-72377.stderr index 1eaee1bd35213..ec42caa49d3e7 100644 --- a/tests/ui/pattern/usefulness/issue-72377.stderr +++ b/tests/ui/pattern/usefulness/issue-72377.stderr @@ -5,6 +5,7 @@ LL | match (x, y) { | ^^^^^^ patterns `(X::A, Some(X::A))`, `(X::A, Some(X::B))`, `(X::B, Some(X::B))` and 2 more not covered | = note: the matched value is of type `(X, Option)` + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms | LL ~ (X::A, Some(X::C)) | (X::C, Some(X::A)) => false, diff --git a/tests/ui/pattern/usefulness/match-non-exhaustive.rs b/tests/ui/pattern/usefulness/match-non-exhaustive.rs index 62c185d04b35d..3b210a115d21a 100644 --- a/tests/ui/pattern/usefulness/match-non-exhaustive.rs +++ b/tests/ui/pattern/usefulness/match-non-exhaustive.rs @@ -1,5 +1,4 @@ fn main() { match 0 { 1 => () } //~ ERROR non-exhaustive patterns match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns - //-| NOTE match arms with guards don't count towards exhaustivity } diff --git a/tests/ui/pattern/usefulness/match-non-exhaustive.stderr b/tests/ui/pattern/usefulness/match-non-exhaustive.stderr index 1a0cc58f35df3..f226bdf80646e 100644 --- a/tests/ui/pattern/usefulness/match-non-exhaustive.stderr +++ b/tests/ui/pattern/usefulness/match-non-exhaustive.stderr @@ -17,7 +17,6 @@ LL | match 0 { 0 if false => () } | ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered | = note: the matched value is of type `i32` - = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL | match 0 { 0 if false => (), i32::MIN..=-1_i32 | 1_i32..=i32::MAX => todo!() } diff --git a/tests/ui/privacy/auxiliary/private-fields-diagnostic-aux-issue-151408.rs b/tests/ui/privacy/auxiliary/private-fields-diagnostic-aux-issue-151408.rs new file mode 100644 index 0000000000000..399d45205c6ab --- /dev/null +++ b/tests/ui/privacy/auxiliary/private-fields-diagnostic-aux-issue-151408.rs @@ -0,0 +1,24 @@ +pub struct Named { + hidden: u8, +} + +impl Named { + pub fn new() -> Self { + Self { hidden: 0 } + } +} + +pub struct NamedWithMultipleFields { + hidden: u8, + pub visible: u8, +} + +struct PrivateInner; + +pub struct PublicTuple(PrivateInner); + +impl PublicTuple { + pub fn new() -> Self { + Self(PrivateInner) + } +} diff --git a/tests/ui/privacy/private-fields-diagnostic-issue-151408.rs b/tests/ui/privacy/private-fields-diagnostic-issue-151408.rs new file mode 100644 index 0000000000000..456e2d418e2d1 --- /dev/null +++ b/tests/ui/privacy/private-fields-diagnostic-issue-151408.rs @@ -0,0 +1,20 @@ +//@ aux-build:private-fields-diagnostic-aux-issue-151408.rs + +extern crate private_fields_diagnostic_aux_issue_151408 as aux; + +use aux::{Named, NamedWithMultipleFields, PublicTuple}; + +fn main() { + let _ = Named {}; + //~^ ERROR cannot construct `aux::Named` with struct literal syntax due to private fields + + let _ = PublicTuple(); + //~^ ERROR cannot initialize a tuple struct which contains private fields [E0423] + + // Keep the private-field note when the user already wrote part of the struct literal. + let _ = NamedWithMultipleFields { visible: 1 }; + //~^ ERROR cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields + + let _ = NamedWithMultipleFields {}; + //~^ ERROR cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields +} diff --git a/tests/ui/privacy/private-fields-diagnostic-issue-151408.stderr b/tests/ui/privacy/private-fields-diagnostic-issue-151408.stderr new file mode 100644 index 0000000000000..1a49a21d6b793 --- /dev/null +++ b/tests/ui/privacy/private-fields-diagnostic-issue-151408.stderr @@ -0,0 +1,45 @@ +error: cannot construct `aux::Named` with struct literal syntax due to private fields + --> $DIR/private-fields-diagnostic-issue-151408.rs:8:13 + | +LL | let _ = Named {}; + | ^^^^^ + | +help: you might have meant to use the `new` associated function + | +LL - let _ = Named {}; +LL + let _ = Named::new(); + | + +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/private-fields-diagnostic-issue-151408.rs:11:13 + | +LL | let _ = PublicTuple(); + | ^^^^^^^^^^^ + | +note: constructor is not visible here due to private fields + --> $DIR/auxiliary/private-fields-diagnostic-aux-issue-151408.rs:18:24 + | +LL | pub struct PublicTuple(PrivateInner); + | ^^^^^^^^^^^^ private field +help: you might have meant to use the `new` associated function + | +LL | let _ = PublicTuple::new(); + | +++++ + +error: cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields + --> $DIR/private-fields-diagnostic-issue-151408.rs:15:13 + | +LL | let _ = NamedWithMultipleFields { visible: 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: ...and other private field `hidden` that was not provided + +error: cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields + --> $DIR/private-fields-diagnostic-issue-151408.rs:18:13 + | +LL | let _ = NamedWithMultipleFields {}; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index 7367672351d6c..0ba4ba97cd1a4 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -81,7 +81,6 @@ error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to LL | let _ = std::collections::HashMap {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: private field `base` that was not provided help: you might have meant to use an associated function to build this type | LL - let _ = std::collections::HashMap {}; @@ -109,7 +108,6 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi LL | let _ = Box {}; | ^^^ | - = note: private fields `0` and `1` that were not provided help: you might have meant to use an associated function to build this type | LL - let _ = Box {}; @@ -137,7 +135,6 @@ error: cannot construct `Box` with struct literal syntax due to private fie LL | let _ = Box:: {}; | ^^^^^^^^^^ | - = note: private fields `0` and `1` that were not provided help: you might have meant to use an associated function to build this type | LL - let _ = Box:: {}; diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr index 4622ea59b5471..81e0df15a6e1e 100644 --- a/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr +++ b/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr @@ -44,6 +44,7 @@ note: `Option` defined here = note: not covered = note: the matched value is of type `&Option` = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ None => {}, @@ -63,6 +64,7 @@ note: `Option` defined here = note: not covered = note: the matched value is of type `&Option` = note: `Void` is uninhabited but is not being matched by value, so a wildcard `_` is required + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ None => {}, diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr index ca92aa491d70f..4ff7194542bf8 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr @@ -10,6 +10,7 @@ note: `Option` defined here | = note: not covered = note: the matched value is of type `Option` + = note: match arms with guards don't count towards exhaustivity help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ None if let y = x => {}, diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr index 2da0f9bd12c22..9c3669a30939c 100644 --- a/tests/ui/suggestions/multi-suggestion.ascii.stderr +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -81,7 +81,6 @@ error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to LL | let _ = std::collections::HashMap {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: private field `base` that was not provided help: you might have meant to use an associated function to build this type | LL - let _ = std::collections::HashMap {}; @@ -109,7 +108,6 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi LL | let _ = Box {}; | ^^^ | - = note: private fields `0` and `1` that were not provided help: you might have meant to use an associated function to build this type | LL - let _ = Box {}; diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr index 69529b67b7757..50316f7e90b4a 100644 --- a/tests/ui/suggestions/multi-suggestion.unicode.stderr +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -80,8 +80,7 @@ error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to │ LL │ let _ = std::collections::HashMap {}; │ ━━━━━━━━━━━━━━━━━━━━━━━━━ - │ - ╰ note: private field `base` that was not provided + ╰╴ help: you might have meant to use an associated function to build this type ╭╴ LL - let _ = std::collections::HashMap {}; @@ -108,8 +107,7 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi │ LL │ let _ = Box {}; │ ━━━ - │ - ╰ note: private fields `0` and `1` that were not provided + ╰╴ help: you might have meant to use an associated function to build this type ╭╴ LL - let _ = Box {};