diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index d41cebc98df3c..e1f43cb20dc38 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -146,6 +146,22 @@ pub enum Breaks { Inconsistent, } +#[derive(Clone, Copy)] +enum IndentStyle { + /// Vertically aligned under whatever column this block begins at. + /// + /// fn demo(arg1: usize, + /// arg2: usize); + Visual, + /// Indented relative to the indentation level of the previous line. + /// + /// fn demo( + /// arg1: usize, + /// arg2: usize, + /// ); + Block { offset: isize }, +} + #[derive(Clone, Copy)] pub struct BreakToken { offset: isize, @@ -154,7 +170,7 @@ pub struct BreakToken { #[derive(Clone, Copy)] pub struct BeginToken { - offset: isize, + indent: IndentStyle, breaks: Breaks, } @@ -178,7 +194,7 @@ impl Token { #[derive(Copy, Clone)] enum PrintFrame { Fits, - Broken { offset: isize, breaks: Breaks }, + Broken { indent: usize, breaks: Breaks }, } const SIZE_INFINITY: isize = 0xffff; @@ -204,6 +220,8 @@ pub struct Printer { scan_stack: VecDeque, /// Stack of blocks-in-progress being flushed by print print_stack: Vec, + /// Level of indentation of current line + indent: usize, /// Buffered indentation to avoid writing trailing whitespace pending_indentation: isize, /// The token most recently popped from the left boundary of the @@ -229,6 +247,7 @@ impl Printer { right_total: 0, scan_stack: VecDeque::new(), print_stack: Vec::new(), + indent: 0, pending_indentation: 0, last_printed: None, } @@ -368,38 +387,41 @@ impl Printer { *self .print_stack .last() - .unwrap_or(&PrintFrame::Broken { offset: 0, breaks: Breaks::Inconsistent }) + .unwrap_or(&PrintFrame::Broken { indent: 0, breaks: Breaks::Inconsistent }) } fn print_begin(&mut self, token: BeginToken, size: isize) { if size > self.space { - let col = self.margin - self.space + token.offset; - self.print_stack.push(PrintFrame::Broken { offset: col, breaks: token.breaks }); + self.print_stack.push(PrintFrame::Broken { indent: self.indent, breaks: token.breaks }); + self.indent = match token.indent { + IndentStyle::Block { offset } => (self.indent as isize + offset) as usize, + IndentStyle::Visual => (self.margin - self.space) as usize, + }; } else { self.print_stack.push(PrintFrame::Fits); } } fn print_end(&mut self) { - self.print_stack.pop().unwrap(); + if let PrintFrame::Broken { indent, .. } = self.print_stack.pop().unwrap() { + self.indent = indent; + } } fn print_break(&mut self, token: BreakToken, size: isize) { - let break_offset = - match self.get_top() { - PrintFrame::Fits => None, - PrintFrame::Broken { offset, breaks: Breaks::Consistent } => Some(offset), - PrintFrame::Broken { offset, breaks: Breaks::Inconsistent } => { - if size > self.space { Some(offset) } else { None } - } - }; - if let Some(offset) = break_offset { - self.out.push('\n'); - self.pending_indentation = offset + token.offset; - self.space = self.margin - (offset + token.offset); - } else { + let fits = match self.get_top() { + PrintFrame::Fits => true, + PrintFrame::Broken { breaks: Breaks::Consistent, .. } => false, + PrintFrame::Broken { breaks: Breaks::Inconsistent, .. } => size <= self.space, + }; + if fits { self.pending_indentation += token.blank_space; self.space -= token.blank_space; + } else { + self.out.push('\n'); + let indent = self.indent as isize + token.offset; + self.pending_indentation = indent; + self.space = self.margin - indent; } } @@ -422,7 +444,10 @@ impl Printer { /// "raw box" pub fn rbox(&mut self, indent: usize, breaks: Breaks) { - self.scan_begin(BeginToken { offset: indent as isize, breaks }) + self.scan_begin(BeginToken { + indent: IndentStyle::Block { offset: indent as isize }, + breaks, + }) } /// Inconsistent breaking box @@ -435,6 +460,10 @@ impl Printer { self.rbox(indent, Breaks::Consistent) } + pub fn visual_align(&mut self) { + self.scan_begin(BeginToken { indent: IndentStyle::Visual, breaks: Breaks::Consistent }); + } + pub fn break_offset(&mut self, n: usize, off: isize) { self.scan_break(BreakToken { offset: off, blank_space: n as isize }) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 96dbd3dca156e..b575dc2196133 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -315,7 +315,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.word(cmnt.lines[0].clone()); self.hardbreak() } else { - self.ibox(0); + self.visual_align(); for line in &cmnt.lines { if !line.is_empty() { self.word(line.clone()); @@ -655,7 +655,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere // Outer-box is consistent. self.cbox(INDENT_UNIT); // Head-box is inconsistent. - self.ibox(w.len() + 1); + self.ibox(0); // Keyword that starts the head. if !w.is_empty() { self.word_nbsp(w); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 956200d60f507..6a5bba30b8bca 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -320,7 +320,9 @@ impl<'a> State<'a> { self.print_ident(label.ident); self.word_space(":"); } - self.head("while"); + self.cbox(0); + self.ibox(0); + self.word_nbsp("while"); self.print_expr_as_cond(test); self.space(); self.print_block_with_attrs(blk, attrs); @@ -330,7 +332,9 @@ impl<'a> State<'a> { self.print_ident(label.ident); self.word_space(":"); } - self.head("for"); + self.cbox(0); + self.ibox(0); + self.word_nbsp("for"); self.print_pat(pat); self.space(); self.word_space("in"); @@ -343,12 +347,14 @@ impl<'a> State<'a> { self.print_ident(label.ident); self.word_space(":"); } - self.head("loop"); + self.cbox(0); + self.ibox(0); + self.word_nbsp("loop"); self.print_block_with_attrs(blk, attrs); } ast::ExprKind::Match(ref expr, ref arms) => { - self.cbox(INDENT_UNIT); - self.ibox(INDENT_UNIT); + self.cbox(0); + self.ibox(0); self.word_nbsp("match"); self.print_expr_as_cond(expr); self.space(); @@ -388,7 +394,7 @@ impl<'a> State<'a> { self.word_space(":"); } // containing cbox, will be closed by print-block at } - self.cbox(INDENT_UNIT); + self.cbox(0); // head-box, will be closed by print-block after { self.ibox(0); self.print_block_with_attrs(blk, attrs); @@ -397,7 +403,7 @@ impl<'a> State<'a> { self.word_nbsp("async"); self.print_capture_clause(capture_clause); // cbox/ibox in analogy to the `ExprKind::Block` arm above - self.cbox(INDENT_UNIT); + self.cbox(0); self.ibox(0); self.print_block_with_attrs(blk, attrs); } @@ -500,7 +506,9 @@ impl<'a> State<'a> { self.word("?") } ast::ExprKind::TryBlock(ref blk) => { - self.head("try"); + self.cbox(0); + self.ibox(0); + self.word_nbsp("try"); self.print_block_with_attrs(blk, attrs) } ast::ExprKind::Err => { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index e575d6aa7e2fc..dac84ae9d5fc8 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -1,5 +1,5 @@ use crate::pp::Breaks::Inconsistent; -use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT}; +use crate::pprust::state::{AnnNode, PrintState, State}; use rustc_ast as ast; use rustc_ast::GenericBound; @@ -377,7 +377,7 @@ impl<'a> State<'a> { self.space_if_not_bol(); self.maybe_print_comment(v.span.lo()); self.print_outer_attributes(&v.attrs); - self.ibox(INDENT_UNIT); + self.ibox(0); self.print_variant(v); self.word(","); self.end(); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 266eec08cebf5..d1b24b332bdcc 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -195,7 +195,7 @@ pub struct InferCtxtInner<'tcx> { // Opaque types found in explicit return types and their // associated fresh inference variable. Writeback resolves these // variables to get the concrete type, which can be used to - // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions. + // 'de-opaque' OpaqueTypeDecl outside of type inference. pub opaque_types: OpaqueTypeMap<'tcx>, /// A map from inference variables created from opaque diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 21c25a2fd989d..cb08e95258678 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -524,7 +524,7 @@ impl LintStore { } } -/// Context for lint checking after type checking. +/// Context for lint checking outside of type inference. pub struct LateContext<'tcx> { /// Type context we're checking in. pub tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c7b1e25b99382..b1ab0f5b533dd 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -894,7 +894,7 @@ pub struct LocalDecl<'tcx> { /// across a suspension point against the type components of the generator /// which type checking knows are live across a suspension point. We need to /// flag drop flags to avoid triggering this check as they are introduced - /// after typeck. + /// outside of type inference. /// /// This should be sound because the drop flags are fully algebraic, and /// therefore don't affect the auto-trait or outlives properties of the diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6c8573805cb94..d063494f2bcb7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -220,7 +220,7 @@ pub struct CommonLifetimes<'tcx> { /// `ReStatic` pub re_static: Region<'tcx>, - /// Erased region, used after type-checking + /// Erased region, used outside of type inference. pub re_erased: Region<'tcx>, } @@ -360,7 +360,7 @@ pub struct TypeckResults<'tcx> { field_indices: ItemLocalMap, /// Stores the types for various nodes in the AST. Note that this table - /// is not guaranteed to be populated until after typeck. See + /// is not guaranteed to be populated outside inference. See /// typeck::check::fn_ctxt for details. node_types: ItemLocalMap>, diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 84ab42a760b93..b3b2bb4459f7d 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -34,8 +34,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Erase the regions in `value` and then fully normalize all the /// types found within. The result will also have regions erased. /// - /// This is appropriate to use only after type-check: it assumes - /// that normalization will succeed, for example. + /// This should only be used outside of type inference. For example, + /// it assumes that normalization will succeed. pub fn normalize_erasing_regions(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T where T: TypeFoldable<'tcx>, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f70fde2a040a1..7d4af6cfa4052 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1464,11 +1464,11 @@ pub enum RegionKind { /// Static data that has an "infinite" lifetime. Top in the region lattice. ReStatic, - /// A region variable. Should not exist after typeck. + /// A region variable. Should not exist outside of type inference. ReVar(RegionVid), /// A placeholder region -- basically, the higher-ranked version of `ReFree`. - /// Should not exist after typeck. + /// Should not exist outside of type inference. RePlaceholder(ty::PlaceholderRegion), /// Empty lifetime is for data that is never accessed. We tag the diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index c7edcb077b917..1f657218a64a9 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -453,28 +453,28 @@ impl<'a> Resolver<'a> { // edit: // only do this if the const and usage of the non-constant value are on the same line // the further the two are apart, the higher the chance of the suggestion being wrong - // also make sure that the pos for the suggestion is not 0 (ICE #90878) - let sp = - self.session.source_map().span_extend_to_prev_str(ident.span, current, true); - - let pos_for_suggestion = sp.lo().0.saturating_sub(current.len() as u32); + let sp = self + .session + .source_map() + .span_extend_to_prev_str(ident.span, current, true, false); - if sp.lo().0 == 0 - || pos_for_suggestion == 0 - || self.session.source_map().is_multiline(sp) - { - err.span_label(ident.span, &format!("this would need to be a `{}`", sugg)); - } else { - let sp = sp.with_lo(BytePos(pos_for_suggestion)); - err.span_suggestion( - sp, - &format!("consider using `{}` instead of `{}`", sugg, current), - format!("{} {}", sugg, ident), - Applicability::MaybeIncorrect, - ); - err.span_label(span, "non-constant value"); + match sp { + Some(sp) if !self.session.source_map().is_multiline(sp) => { + let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32))); + err.span_suggestion( + sp, + &format!("consider using `{}` instead of `{}`", sugg, current), + format!("{} {}", sugg, ident), + Applicability::MaybeIncorrect, + ); + err.span_label(span, "non-constant value"); + } + _ => { + err.span_label(ident.span, &format!("this would need to be a `{}`", sugg)); + } } + err } ResolutionError::BindingShadowsSomethingUnacceptable { diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index b95fe1b0549bd..570fa873a23da 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -984,7 +984,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( tcx.dep_graph.with_ignore(|| { info!("Dumping crate {}", cratename); - // Privacy checking requires and is done after type checking; use a + // Privacy checking must be done outside of type inference; use a // fallback in case the access levels couldn't have been correctly computed. let access_levels = match tcx.sess.compile_status() { Ok(..) => tcx.privacy_access_levels(()), diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 7414d201f511d..95177102dcf86 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -629,26 +629,41 @@ impl SourceMap { } /// Extends the given `Span` to just after the previous occurrence of `pat` when surrounded by - /// whitespace. Returns the same span if no character could be found or if an error occurred - /// while retrieving the code snippet. - pub fn span_extend_to_prev_str(&self, sp: Span, pat: &str, accept_newlines: bool) -> Span { + /// whitespace. Returns None if the pattern could not be found or if an error occurred while + /// retrieving the code snippet. + pub fn span_extend_to_prev_str( + &self, + sp: Span, + pat: &str, + accept_newlines: bool, + include_whitespace: bool, + ) -> Option { // assure that the pattern is delimited, to avoid the following // fn my_fn() // ^^^^ returned span without the check // ---------- correct span + let prev_source = self.span_to_prev_source(sp).ok()?; for ws in &[" ", "\t", "\n"] { let pat = pat.to_owned() + ws; - if let Ok(prev_source) = self.span_to_prev_source(sp) { - let prev_source = prev_source.rsplit(&pat).next().unwrap_or("").trim_start(); - if prev_source.is_empty() && sp.lo().0 != 0 { - return sp.with_lo(BytePos(sp.lo().0 - 1)); - } else if accept_newlines || !prev_source.contains('\n') { - return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32)); + if let Some(pat_pos) = prev_source.rfind(&pat) { + let just_after_pat_pos = pat_pos + pat.len() - 1; + let just_after_pat_plus_ws = if include_whitespace { + just_after_pat_pos + + prev_source[just_after_pat_pos..] + .find(|c: char| !c.is_whitespace()) + .unwrap_or(0) + } else { + just_after_pat_pos + }; + let len = prev_source.len() - just_after_pat_plus_ws; + let prev_source = &prev_source[just_after_pat_plus_ws..]; + if accept_newlines || !prev_source.trim_start().contains('\n') { + return Some(sp.with_lo(BytePos(sp.lo().0 - len as u32))); } } } - sp + None } /// Returns the source snippet as `String` after the given `Span`. @@ -927,7 +942,7 @@ impl SourceMap { } pub fn generate_fn_name_span(&self, span: Span) -> Option { - let prev_span = self.span_extend_to_prev_str(span, "fn", true); + let prev_span = self.span_extend_to_prev_str(span, "fn", true, true).unwrap_or(span); if let Ok(snippet) = self.span_to_snippet(prev_span) { debug!( "generate_fn_name_span: span={:?}, prev_span={:?}, snippet={:?}", @@ -968,8 +983,7 @@ impl SourceMap { pub fn generate_local_type_param_snippet(&self, span: Span) -> Option<(Span, String)> { // Try to extend the span to the previous "fn" keyword to retrieve the function // signature. - let sugg_span = self.span_extend_to_prev_str(span, "fn", false); - if sugg_span != span { + if let Some(sugg_span) = self.span_extend_to_prev_str(span, "fn", false, true) { if let Ok(snippet) = self.span_to_snippet(sugg_span) { // Consume the function name. let mut offset = snippet diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 8046267a59da6..a84410d0f3c46 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -444,7 +444,7 @@ impl InlineAsmRegClass { } /// Returns a suggested register class to use for this type. This is called - /// after type checking via `supported_types` fails to give a better error + /// when `supported_types` fails to give a better error /// message to the user. pub fn suggest_class(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option { match self { diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 848aba7c91289..759bc69698167 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -18,7 +18,6 @@ use rustc_middle::ty::{self, TyCtxt}; /// that type check should guarantee to us that all nested /// obligations *could be* resolved if we wanted to. /// -/// Assumes that this is run after the entire crate has been successfully type-checked. /// This also expects that `trait_ref` is fully normalized. pub fn codegen_fulfill_obligation<'tcx>( tcx: TyCtxt<'tcx>, @@ -101,7 +100,7 @@ pub fn codegen_fulfill_obligation<'tcx>( /// Finishes processes any obligations that remain in the /// fulfillment context, and then returns the result with all type /// variables removed and regions erased. Because this is intended -/// for use after type-check has completed, if any errors occur, +/// for use outside of type inference, if any errors occur, /// it will panic. It is used during normalization and other cases /// where processing the obligations in `fulfill_cx` may cause /// type inference variables that appear in `result` to be @@ -124,7 +123,10 @@ where if !errors.is_empty() { infcx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, - &format!("Encountered errors `{:?}` resolving bounds after type-checking", errors), + &format!( + "Encountered errors `{:?}` resolving bounds outside of type inference", + errors + ), ); } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 23f534858b82a..2927e64f705fe 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -291,7 +291,7 @@ pub fn normalize_param_env_or_error<'tcx>( // // In any case, in practice, typeck constructs all the // parameter environments once for every fn as it goes, - // and errors will get reported then; so after typeck we + // and errors will get reported then; so outside of type inference we // can be sure that no errors should occur. debug!( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e8b46e88a4228..087fc6034d98f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -391,7 +391,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { // severe performance implications for large opaque types with // late-bound regions. See `issue-88862` benchmark. ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { - // Only normalize `impl Trait` after type-checking, usually in codegen. + // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty.super_fold_with(self), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 81ee22c1de4d9..3c9e1bbcef26d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -200,7 +200,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // severe performance implications for large opaque types with // late-bound regions. See `issue-88862` benchmark. ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { - // Only normalize `impl Trait` after type-checking, usually in codegen. + // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty.try_super_fold_with(self), diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index fef8319046819..b882a940d40c3 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -149,7 +149,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // kind of an "idempotent" action, but I'm not sure where would be // a better place. In practice, we construct environments for // every fn once during type checking, and we'll abort if there - // are any errors at that point, so after type checking you can be + // are any errors at that point, so outside of type inference you can be // sure that this will succeed without errors anyway. if tcx.sess.opts.debugging_opts.chalk { diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 956696546da8e..05ff7f818c75f 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -445,7 +445,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let named_type_param_count = param_counts.types - has_self as usize - synth_type_param_count; let infer_lifetimes = - gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params(); + (gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params(); if gen_pos != GenericArgPosition::Type && !gen_args.bindings.is_empty() { Self::prohibit_assoc_ty_binding(tcx, gen_args.bindings[0].span); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 4cf8ddcb8f01c..16fc9a01a2707 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -482,7 +482,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) -> subst::GenericArg<'tcx> { let tcx = self.astconv.tcx(); match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(), + GenericParamDefKind::Lifetime => self + .astconv + .re_infer(Some(param), self.span) + .unwrap_or_else(|| { + debug!(?param, "unelided lifetime in signature"); + + // This indicates an illegal lifetime in a non-assoc-trait position + tcx.sess.delay_span_bug(self.span, "unelided lifetime in signature"); + + // Supply some dummy value. We don't have an + // `re_error`, annoyingly, so use `'static`. + tcx.lifetimes.re_static + }) + .into(), GenericParamDefKind::Type { has_default, .. } => { if !infer_args && has_default { // No type parameter provided, but a default exists. diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 23cc4b0ffc814..02ded82140694 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -31,7 +31,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_hir::{ExprKind, QPath}; +use rustc_hir::{ExprKind, HirId, QPath}; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::InferOk; @@ -1948,7 +1948,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, expr_ty={:?}", field, base, expr, expr_t ); - let mut err = self.no_such_field_err(field, expr_t); + let mut err = self.no_such_field_err(field, expr_t, base.hir_id); match *expr_t.peel_refs().kind() { ty::Array(_, len) => { @@ -2186,6 +2186,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, field: Ident, expr_t: &'tcx ty::TyS<'tcx>, + id: HirId, ) -> DiagnosticBuilder<'_> { let span = field.span; debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t); @@ -2203,9 +2204,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // try to add a suggestion in case the field is a nested field of a field of the Adt if let Some((fields, substs)) = self.get_field_candidates(span, &expr_t) { for candidate_field in fields.iter() { - if let Some(field_path) = - self.check_for_nested_field(span, field, candidate_field, substs, vec![]) - { + if let Some(field_path) = self.check_for_nested_field( + span, + field, + candidate_field, + substs, + vec![], + self.tcx.parent_module(id).to_def_id(), + ) { let field_path_str = field_path .iter() .map(|id| id.name.to_ident_string()) @@ -2257,6 +2263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { candidate_field: &ty::FieldDef, subst: SubstsRef<'tcx>, mut field_path: Vec, + id: DefId, ) -> Option> { debug!( "check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}", @@ -2276,10 +2283,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_ty = candidate_field.ty(self.tcx, subst); if let Some((nested_fields, subst)) = self.get_field_candidates(span, &field_ty) { for field in nested_fields.iter() { - let ident = field.ident(self.tcx).normalize_to_macros_2_0(); - if ident == target_field { - return Some(field_path); - } else { + let accessible = field.vis.is_accessible_from(id, self.tcx); + if accessible { + let ident = field.ident(self.tcx).normalize_to_macros_2_0(); + if ident == target_field { + return Some(field_path); + } let field_path = field_path.clone(); if let Some(path) = self.check_for_nested_field( span, @@ -2287,6 +2296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field, subst, field_path, + id, ) { return Some(path); } diff --git a/library/core/src/char/decode.rs b/library/core/src/char/decode.rs index 5dd8c5ef78941..8b9f979b573f7 100644 --- a/library/core/src/char/decode.rs +++ b/library/core/src/char/decode.rs @@ -120,9 +120,34 @@ impl> Iterator for DecodeUtf16 { #[inline] fn size_hint(&self) -> (usize, Option) { let (low, high) = self.iter.size_hint(); - // we could be entirely valid surrogates (2 elements per - // char), or entirely non-surrogates (1 element per char) - (low / 2, high) + + let (low_buf, high_buf) = match self.buf { + // buf is empty, no additional elements from it. + None => (0, 0), + // `u` is a non surrogate, so it's always an additional character. + Some(u) if u < 0xD800 || 0xDFFF < u => (1, 1), + // `u` is a leading surrogate (it can never be a trailing surrogate and + // it's a surrogate due to the previous branch) and `self.iter` is empty. + // + // `u` can't be paired, since the `self.iter` is empty, + // so it will always become an additional element (error). + Some(_u) if high == Some(0) => (1, 1), + // `u` is a leading surrogate and `iter` may be non-empty. + // + // `u` can either pair with a trailing surrogate, in which case no additional elements + // are produced, or it can become an error, in which case it's an additional character (error). + Some(_u) => (0, 1), + }; + + // `self.iter` could contain entirely valid surrogates (2 elements per + // char), or entirely non-surrogates (1 element per char). + // + // On odd lower bound, at least one element must stay unpaired + // (with other elements from `self.iter`), so we round up. + let low = low.div_ceil(2) + low_buf; + let high = high.and_then(|h| h.checked_add(high_buf)); + + (low, high) } } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 0b8ed0cc174b4..d8dcfdafa8df9 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1008,29 +1008,37 @@ impl f32 { Self::from_bits(u32::from_ne_bytes(bytes)) } - /// Returns an ordering between self and other values. + /// Return the ordering between `self` and `other`. + /// /// Unlike the standard partial comparison between floating point numbers, /// this comparison always produces an ordering in accordance to - /// the totalOrder predicate as defined in IEEE 754 (2008 revision) - /// floating point standard. The values are ordered in following order: - /// - Negative quiet NaN - /// - Negative signaling NaN - /// - Negative infinity - /// - Negative numbers - /// - Negative subnormal numbers - /// - Negative zero - /// - Positive zero - /// - Positive subnormal numbers - /// - Positive numbers - /// - Positive infinity - /// - Positive signaling NaN - /// - Positive quiet NaN - /// - /// Note that this function does not always agree with the [`PartialOrd`] - /// and [`PartialEq`] implementations of `f32`. In particular, they regard - /// negative and positive zero as equal, while `total_cmp` doesn't. + /// the `totalOrder` predicate as defined in the IEEE 754 (2008 revision) + /// floating point standard. The values are ordered in the following sequence: + /// + /// - negative quiet NaN + /// - negative signaling NaN + /// - negative infinity + /// - negative numbers + /// - negative subnormal numbers + /// - negative zero + /// - positive zero + /// - positive subnormal numbers + /// - positive numbers + /// - positive infinity + /// - positive signaling NaN + /// - positive quiet NaN. + /// + /// The ordering established by this function does not always agree with the + /// [`PartialOrd`] and [`PartialEq`] implementations of `f32`. For example, + /// they consider negative and positive zero equal, while `total_cmp` + /// doesn't. + /// + /// The interpretation of the signaling NaN bit follows the definition in + /// the IEEE 754 standard, which may not match the interpretation by some of + /// the older, non-conformant (e.g. MIPS) hardware implementations. /// /// # Example + /// /// ``` /// #![feature(total_cmp)] /// struct GoodBoy { diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 5a3cd2a4b9260..7c2f51ff64639 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1024,29 +1024,37 @@ impl f64 { Self::from_bits(u64::from_ne_bytes(bytes)) } - /// Returns an ordering between self and other values. + /// Return the ordering between `self` and `other`. + /// /// Unlike the standard partial comparison between floating point numbers, /// this comparison always produces an ordering in accordance to - /// the totalOrder predicate as defined in IEEE 754 (2008 revision) - /// floating point standard. The values are ordered in following order: - /// - Negative quiet NaN - /// - Negative signaling NaN - /// - Negative infinity - /// - Negative numbers - /// - Negative subnormal numbers - /// - Negative zero - /// - Positive zero - /// - Positive subnormal numbers - /// - Positive numbers - /// - Positive infinity - /// - Positive signaling NaN - /// - Positive quiet NaN - /// - /// Note that this function does not always agree with the [`PartialOrd`] - /// and [`PartialEq`] implementations of `f64`. In particular, they regard - /// negative and positive zero as equal, while `total_cmp` doesn't. + /// the `totalOrder` predicate as defined in the IEEE 754 (2008 revision) + /// floating point standard. The values are ordered in the following sequence: + /// + /// - negative quiet NaN + /// - negative signaling NaN + /// - negative infinity + /// - negative numbers + /// - negative subnormal numbers + /// - negative zero + /// - positive zero + /// - positive subnormal numbers + /// - positive numbers + /// - positive infinity + /// - positive signaling NaN + /// - positive quiet NaN. + /// + /// The ordering established by this function does not always agree with the + /// [`PartialOrd`] and [`PartialEq`] implementations of `f64`. For example, + /// they consider negative and positive zero equal, while `total_cmp` + /// doesn't. + /// + /// The interpretation of the signaling NaN bit follows the definition in + /// the IEEE 754 standard, which may not match the interpretation by some of + /// the older, non-conformant (e.g. MIPS) hardware implementations. /// /// # Example + /// /// ``` /// #![feature(total_cmp)] /// struct GoodBoy { diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 8f58e8897b34b..2ba0e5320d7b9 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -773,7 +773,7 @@ where let mid = partition_equal(v, pivot, is_less); // Continue sorting elements greater than the pivot. - v = &mut { v }[mid..]; + v = &mut v[mid..]; continue; } } @@ -784,7 +784,7 @@ where was_partitioned = was_p; // Split the slice into `left`, `pivot`, and `right`. - let (left, right) = { v }.split_at_mut(mid); + let (left, right) = v.split_at_mut(mid); let (pivot, right) = right.split_at_mut(1); let pivot = &pivot[0]; @@ -860,7 +860,7 @@ fn partition_at_index_loop<'a, T, F>( let (mid, _) = partition(v, pivot, is_less); // Split the slice into `left`, `pivot`, and `right`. - let (left, right) = { v }.split_at_mut(mid); + let (left, right) = v.split_at_mut(mid); let (pivot, right) = right.split_at_mut(1); let pivot = &pivot[0]; diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs index 2b857a6591929..4c899b6eb43d0 100644 --- a/library/core/tests/char.rs +++ b/library/core/tests/char.rs @@ -308,6 +308,33 @@ fn test_decode_utf16() { check(&[0xD800, 0], &[Err(0xD800), Ok('\0')]); } +#[test] +fn test_decode_utf16_size_hint() { + fn check(s: &[u16]) { + let mut iter = char::decode_utf16(s.iter().cloned()); + + loop { + let count = iter.clone().count(); + let (lower, upper) = iter.size_hint(); + + assert!( + lower <= count && count <= upper.unwrap(), + "lower = {lower}, count = {count}, upper = {upper:?}" + ); + + if let None = iter.next() { + break; + } + } + } + + check(&[0xD800, 0xD800, 0xDC00]); + check(&[0xD800, 0xD800, 0x0]); + check(&[0xD800, 0x41, 0x42]); + check(&[0xD800, 0]); + check(&[0xD834, 0x006d]); +} + #[test] fn ed_iterator_specializations() { // Check counting diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 65e000d9215a5..878796065c8f1 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -598,7 +598,7 @@ impl DirEntry { target_os = "vxworks" ))] pub fn file_type(&self) -> io::Result { - lstat(&self.path()).map(|m| m.file_type()) + self.metadata().map(|m| m.file_type()) } #[cfg(not(any( @@ -616,7 +616,7 @@ impl DirEntry { libc::DT_SOCK => Ok(FileType { mode: libc::S_IFSOCK }), libc::DT_DIR => Ok(FileType { mode: libc::S_IFDIR }), libc::DT_BLK => Ok(FileType { mode: libc::S_IFBLK }), - _ => lstat(&self.path()).map(|m| m.file_type()), + _ => self.metadata().map(|m| m.file_type()), } } diff --git a/library/std/src/time.rs b/library/std/src/time.rs index b4f9d8ea28d7b..2d2b96c8bcec7 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -176,7 +176,12 @@ pub struct Instant(time::Instant); /// } /// ``` /// -/// # Underlying System calls +/// # Platform-specific behavior +/// +/// The precision of `SystemTime` can depend on the underlying OS-specific time format. +/// For example, on Windows the time is represented in 100 nanosecond intervals whereas Linux +/// can represent nanosecond intervals. +/// /// Currently, the following system calls are being used to get the current time using `now()`: /// /// | Platform | System call | diff --git a/src/test/pretty/ast-stmt-expr-attr.rs b/src/test/pretty/ast-stmt-expr-attr.rs index e32f5ca24ea0f..2404b32194289 100644 --- a/src/test/pretty/ast-stmt-expr-attr.rs +++ b/src/test/pretty/ast-stmt-expr-attr.rs @@ -28,67 +28,67 @@ fn syntax() { let _ = #[attr] (x as Y); let _ = #[attr] while true { - #![attr] - }; + #![attr] + }; let _ = #[attr] while let Some(false) = true { - #![attr] - }; + #![attr] + }; let _ = #[attr] for x in y { - #![attr] - }; + #![attr] + }; let _ = #[attr] loop { - #![attr] - }; + #![attr] + }; let _ = #[attr] match true { - #![attr] - #[attr] - _ => false, - }; + #![attr] + #[attr] + _ => false, + }; let _ = #[attr] || #[attr] foo; let _ = #[attr] move || #[attr] foo; let _ = #[attr] || - #[attr] { - #![attr] - foo - }; + #[attr] { + #![attr] + foo + }; let _ = #[attr] move || - #[attr] { - #![attr] - foo - }; + #[attr] { + #![attr] + foo + }; let _ = #[attr] || - { - #![attr] - foo - }; + { + #![attr] + foo + }; let _ = #[attr] move || - { - #![attr] - foo - }; + { + #![attr] + foo + }; let _ = #[attr] { - #![attr] - }; + #![attr] + }; let _ = #[attr] { - #![attr] - let _ = (); - }; + #![attr] + let _ = (); + }; let _ = #[attr] { - #![attr] - let _ = (); - foo - }; + #![attr] + let _ = (); + foo + }; let _ = #[attr] x = y; let _ = #[attr] (x = y); let _ = #[attr] x += y; diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index 385afa4f33ec1..8c8580b07c218 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -93,9 +93,9 @@ // Taken from https://www.unicode.org/Public/UNIDATA/PropList.txt let chars = ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u{85}', '\u{A0}', - '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}', - '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}', - '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}', - '\u{205F}', '\u{3000}']; + '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}', + '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}', + '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}', + '\u{205F}', '\u{3000}']; for c in &chars { let ws = c.is_whitespace(); println!("{} {}", c, ws); } } diff --git a/src/test/pretty/delimited-token-groups.rs b/src/test/pretty/delimited-token-groups.rs index 1137d80456489..c7c9277faf69e 100644 --- a/src/test/pretty/delimited-token-groups.rs +++ b/src/test/pretty/delimited-token-groups.rs @@ -17,9 +17,9 @@ mac! { mac! { a(aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa - aaaaaaaa aaaaaaaa) a + aaaaaaaa aaaaaaaa) a [aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa - aaaaaaaa aaaaaaaa] a + aaaaaaaa aaaaaaaa] a { aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa @@ -27,22 +27,22 @@ mac! { } mac!(aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa - aaaaaaaa aaaaaaaa); +aaaaaaaa aaaaaaaa); mac![aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa - aaaaaaaa aaaaaaaa]; +aaaaaaaa aaaaaaaa]; mac! { aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa } #[rustc_dummy(aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa - aaaaaaaa aaaaaaaa aaaaaaaa)] +aaaaaaaa aaaaaaaa aaaaaaaa)] #[rustc_dummy[aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa - aaaaaaaa aaaaaaaa aaaaaaaa]] +aaaaaaaa aaaaaaaa aaaaaaaa]] #[rustc_dummy { - aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa - aaaaaaaa aaaaaaaa - }] + aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa + aaaaaaaa aaaaaaaa +}] #[rustc_dummy = - "aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa"] +"aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa"] fn main() {} diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index 93967e720c1b0..3830c3aa6c9f1 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -11,15 +11,15 @@ pub fn foo(_: [i32; (3 as usize)]) ({ } as ()) pub fn bar() ({ - const FOO: usize = ((5 as usize) - (4 as usize) as usize); - let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]); + const FOO: usize = ((5 as usize) - (4 as usize) as usize); + let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]); - let _: [(); (1 as usize)] = ([(() as ())] as [(); 1]); + let _: [(); (1 as usize)] = ([(() as ())] as [(); 1]); - let _ = - (((&([(1 as i32), (2 as i32), (3 as i32)] as [i32; 3]) - as &[i32; 3]) as *const _ as *const [i32; 3]) as - *const [i32; (3 as usize)] as *const [i32; 3]); + let _ = + (((&([(1 as i32), (2 as i32), (3 as i32)] as [i32; 3]) as + &[i32; 3]) as *const _ as *const [i32; 3]) as + *const [i32; (3 as usize)] as *const [i32; 3]); @@ -29,29 +29,19 @@ - ({ - let res = - ((::alloc::fmt::format as - for<'r> fn(Arguments<'r>) -> String {format})(((::core::fmt::Arguments::new_v1 - as - fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test" - as - &str)] - as - [&str; 1]) - as - &[&str; 1]), - (&([] - as - [ArgumentV1; 0]) - as - &[ArgumentV1; 0])) - as - Arguments)) - as String); - (res as String) - } as String); - } as ()) + ({ + let res = + ((::alloc::fmt::format as + for<'r> fn(Arguments<'r>) -> String {format})(((::core::fmt::Arguments::new_v1 + as + fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1})((&([("test" + as &str)] as [&str; 1]) as + &[&str; 1]), + (&([] as [ArgumentV1; 0]) as &[ArgumentV1; 0])) as + Arguments)) as String); + (res as String) + } as String); + } as ()) pub type Foo = [i32; (3 as usize)]; pub struct Bar { pub x: [i32; (3 as usize)], @@ -60,19 +50,9 @@ pub enum Baz { BazVariant([i32; (5 as usize)]), } pub fn id(x: T) -> T ({ (x as T) } as T) pub fn use_id() ({ - let _ = - ((id::<[i32; (3 as usize)]> as - fn([i32; 3]) -> [i32; 3] {id::<[i32; 3]>})(([(1 - as - i32), - (2 - as - i32), - (3 - as - i32)] - as - [i32; 3])) - as [i32; 3]); - } as ()) + let _ = + ((id::<[i32; (3 as usize)]> as + fn([i32; 3]) -> [i32; 3] {id::<[i32; 3]>})(([(1 as i32), + (2 as i32), (3 as i32)] as [i32; 3])) as [i32; 3]); + } as ()) fn main() ({ } as ()) diff --git a/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs b/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs index ed7879001d559..87f525a6178e6 100644 --- a/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs +++ b/src/test/pretty/issue-68710-field-attr-proc-mac-lost.rs @@ -9,8 +9,8 @@ struct C { #[allow()] const C: C = C{ - #[cfg(debug_assertions)] - field: 0, + #[cfg(debug_assertions)] + field: 0, - #[cfg(not(debug_assertions))] - field: 1,}; + #[cfg(not(debug_assertions))] + field: 1,}; diff --git a/src/test/pretty/macro_rules.rs b/src/test/pretty/macro_rules.rs index fb66e4a775842..01adb14133b35 100644 --- a/src/test/pretty/macro_rules.rs +++ b/src/test/pretty/macro_rules.rs @@ -12,8 +12,8 @@ macro_rules! matcher_brackets { macro_rules! all_fragments { ($b : block, $e : expr, $i : ident, $it : item, $l : lifetime, $lit : - literal, $m : meta, $p : pat, $pth : path, $s : stmt, $tt : tt, $ty : ty, - $vis : vis) => {} ; + literal, $m : meta, $p : pat, $pth : path, $s : stmt, $tt : tt, $ty : ty, + $vis : vis) => {} ; } fn main() {} diff --git a/src/test/pretty/match-naked-expr-medium.rs b/src/test/pretty/match-naked-expr-medium.rs index a124fdff3900d..836af99002d65 100644 --- a/src/test/pretty/match-naked-expr-medium.rs +++ b/src/test/pretty/match-naked-expr-medium.rs @@ -5,10 +5,10 @@ fn main() { let _y = match x { Some(_) => - ["some(_)".to_string(), "not".to_string(), "SO".to_string(), - "long".to_string(), "string".to_string()], + ["some(_)".to_string(), "not".to_string(), "SO".to_string(), + "long".to_string(), "string".to_string()], None => - ["none".to_string(), "a".to_string(), "a".to_string(), - "a".to_string(), "a".to_string()], + ["none".to_string(), "a".to_string(), "a".to_string(), + "a".to_string(), "a".to_string()], }; } diff --git a/src/test/pretty/stmt_expr_attributes.rs b/src/test/pretty/stmt_expr_attributes.rs index 01533cd8107b0..96bde96200af9 100644 --- a/src/test/pretty/stmt_expr_attributes.rs +++ b/src/test/pretty/stmt_expr_attributes.rs @@ -48,9 +48,9 @@ fn _4() { let _ = #[rustc_dummy] match () { - #![rustc_dummy] - () => (), - }; + #![rustc_dummy] + () => (), + }; } fn _5() { @@ -156,56 +156,56 @@ fn _11() { let _ = #[rustc_dummy] 0 as usize; let _ = #[rustc_dummy] while false { - #![rustc_dummy] - }; + #![rustc_dummy] + }; let _ = #[rustc_dummy] while let None = Some(()) { - #![rustc_dummy] - }; + #![rustc_dummy] + }; let _ = #[rustc_dummy] for _ in 0..0 { - #![rustc_dummy] - }; + #![rustc_dummy] + }; let _ = #[rustc_dummy] loop { - #![rustc_dummy] - }; + #![rustc_dummy] + }; let _ = #[rustc_dummy] match false { - #![rustc_dummy] - _ => (), - }; + #![rustc_dummy] + _ => (), + }; let _ = #[rustc_dummy] || #[rustc_dummy] (); let _ = #[rustc_dummy] move || #[rustc_dummy] (); let _ = #[rustc_dummy] || - { - #![rustc_dummy] - #[rustc_dummy] - () - }; + { + #![rustc_dummy] + #[rustc_dummy] + () + }; let _ = #[rustc_dummy] move || - { - #![rustc_dummy] - #[rustc_dummy] - () - }; + { + #![rustc_dummy] + #[rustc_dummy] + () + }; let _ = #[rustc_dummy] { - #![rustc_dummy] - }; + #![rustc_dummy] + }; let _ = #[rustc_dummy] { - #![rustc_dummy] - let _ = (); - }; + #![rustc_dummy] + let _ = (); + }; let _ = #[rustc_dummy] { - #![rustc_dummy] - let _ = (); - () - }; + #![rustc_dummy] + let _ = (); + () + }; let mut x = 0; let _ = #[rustc_dummy] x = 15; let _ = #[rustc_dummy] x += 15; diff --git a/src/test/pretty/vec-comments.pp b/src/test/pretty/vec-comments.pp index a150cf0b8ea8a..f2f807c59de99 100644 --- a/src/test/pretty/vec-comments.pp +++ b/src/test/pretty/vec-comments.pp @@ -4,26 +4,26 @@ fn main() { let _v1 = [ - // Comment - 0, - // Comment - 1, - // Comment - 2]; + // Comment + 0, + // Comment + 1, + // Comment + 2]; let _v2 = [0, // Comment - 1, // Comment - 2]; // Comment + 1, // Comment + 2]; // Comment let _v3 = [ - /* Comment */ - 0, - /* Comment */ - 1, - /* Comment */ - 2]; + /* Comment */ + 0, + /* Comment */ + 1, + /* Comment */ + 2]; let _v4 = [0, /* Comment */ - 1, /* Comment */ - 2]; /* Comment */ + 1, /* Comment */ + 2]; /* Comment */ } diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr index 2d0a7a94d5676..194cd66a66e96 100644 --- a/src/test/ui/asm/x86_64/parse-error.stderr +++ b/src/test/ui/asm/x86_64/parse-error.stderr @@ -394,7 +394,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:39:37 | LL | let mut foo = 0; - | ---------- help: consider using `const` instead of `let`: `const foo` + | ----------- help: consider using `const` instead of `let`: `const foo` ... LL | asm!("{}", options(), const foo); | ^^^ non-constant value @@ -403,7 +403,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:50:44 | LL | let mut foo = 0; - | ---------- help: consider using `const` instead of `let`: `const foo` + | ----------- help: consider using `const` instead of `let`: `const foo` ... LL | asm!("{}", clobber_abi("C"), const foo); | ^^^ non-constant value @@ -412,7 +412,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:57:31 | LL | let mut foo = 0; - | ---------- help: consider using `const` instead of `let`: `const foo` + | ----------- help: consider using `const` instead of `let`: `const foo` ... LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value @@ -421,7 +421,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:57:46 | LL | let mut bar = 0; - | ---------- help: consider using `const` instead of `let`: `const bar` + | ----------- help: consider using `const` instead of `let`: `const bar` ... LL | asm!("{a}", a = const foo, a = const bar); | ^^^ non-constant value @@ -430,7 +430,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:64:46 | LL | let mut bar = 0; - | ---------- help: consider using `const` instead of `let`: `const bar` + | ----------- help: consider using `const` instead of `let`: `const bar` ... LL | asm!("{a}", in("eax") foo, a = const bar); | ^^^ non-constant value @@ -439,7 +439,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:67:46 | LL | let mut bar = 0; - | ---------- help: consider using `const` instead of `let`: `const bar` + | ----------- help: consider using `const` instead of `let`: `const bar` ... LL | asm!("{a}", in("eax") foo, a = const bar); | ^^^ non-constant value @@ -448,7 +448,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/parse-error.rs:70:42 | LL | let mut bar = 0; - | ---------- help: consider using `const` instead of `let`: `const bar` + | ----------- help: consider using `const` instead of `let`: `const bar` ... LL | asm!("{1}", in("eax") foo, const bar); | ^^^ non-constant value diff --git a/src/test/ui/attributes/key-value-expansion.stderr b/src/test/ui/attributes/key-value-expansion.stderr index 268e382327e1d..4786a0c03e253 100644 --- a/src/test/ui/attributes/key-value-expansion.stderr +++ b/src/test/ui/attributes/key-value-expansion.stderr @@ -16,12 +16,12 @@ LL | bug!(); = note: this error originates in the macro `bug` (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected token: `{ - let res = - ::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""], - &[::core::fmt::ArgumentV1::new(&"u8", - ::core::fmt::Display::fmt)])); - res - }.as_str()` + let res = + ::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""], + &[::core::fmt::ArgumentV1::new(&"u8", + ::core::fmt::Display::fmt)])); + res + }.as_str()` --> $DIR/key-value-expansion.rs:48:23 | LL | doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()} diff --git a/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout index 99fe9d2e4b3c3..121138605f1a2 100644 --- a/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout +++ b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout @@ -15,4 +15,4 @@ trait Foo {} fn foo() {} struct Range; + FROM>; diff --git a/src/test/ui/consts/issue-91560.fixed b/src/test/ui/consts/issue-91560.fixed new file mode 100644 index 0000000000000..41b9d95734a8d --- /dev/null +++ b/src/test/ui/consts/issue-91560.fixed @@ -0,0 +1,21 @@ +// Regression test for issue #91560. + +// run-rustfix + +#![allow(unused,non_upper_case_globals)] + +fn foo() { + const length: usize = 2; + //~^ HELP: consider using `const` + let arr = [0; length]; + //~^ ERROR: attempt to use a non-constant value in a constant [E0435] +} + +fn bar() { + const length: usize = 2; + //~^ HELP: consider using `const` + let arr = [0; length]; + //~^ ERROR: attempt to use a non-constant value in a constant [E0435] +} + +fn main() {} diff --git a/src/test/ui/consts/issue-91560.rs b/src/test/ui/consts/issue-91560.rs new file mode 100644 index 0000000000000..04592feb50541 --- /dev/null +++ b/src/test/ui/consts/issue-91560.rs @@ -0,0 +1,21 @@ +// Regression test for issue #91560. + +// run-rustfix + +#![allow(unused,non_upper_case_globals)] + +fn foo() { + let mut length: usize = 2; + //~^ HELP: consider using `const` + let arr = [0; length]; + //~^ ERROR: attempt to use a non-constant value in a constant [E0435] +} + +fn bar() { + let length: usize = 2; + //~^ HELP: consider using `const` + let arr = [0; length]; + //~^ ERROR: attempt to use a non-constant value in a constant [E0435] +} + +fn main() {} diff --git a/src/test/ui/consts/issue-91560.stderr b/src/test/ui/consts/issue-91560.stderr new file mode 100644 index 0000000000000..e1b5d4cacf8e3 --- /dev/null +++ b/src/test/ui/consts/issue-91560.stderr @@ -0,0 +1,21 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/issue-91560.rs:10:19 + | +LL | let mut length: usize = 2; + | -------------- help: consider using `const` instead of `let`: `const length` +LL | +LL | let arr = [0; length]; + | ^^^^^^ non-constant value + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/issue-91560.rs:17:19 + | +LL | let length: usize = 2; + | ------------ help: consider using `const` instead of `let`: `const length` +LL | +LL | let arr = [0; length]; + | ^^^^^^ non-constant value + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.rs b/src/test/ui/generic-associated-types/elided-in-expr-position.rs new file mode 100644 index 0000000000000..482d0d5c00a63 --- /dev/null +++ b/src/test/ui/generic-associated-types/elided-in-expr-position.rs @@ -0,0 +1,38 @@ +#![feature(generic_associated_types)] +#![allow(unused)] + +pub trait Trait { + type Assoc<'a> where Self: 'a; + + fn f(&self) -> Self::Assoc<'_>; + + // Disallow elision in return position, for now + fn g(&self) -> Self::Assoc; + //~^ ERROR missing generics for associated type `Trait::Assoc` +} + +pub struct Struct { + item: f32 +} + +pub struct GenericStruct<'a> { + ref_item: &'a f32 +} + +impl Trait for Struct { + type Assoc<'a> = GenericStruct<'a>; + + fn f(&self) -> Self::Assoc<'_> { + Self::Assoc { + ref_item: &self.item + } + } + + // Disallow elision in return position, for now + fn g(&self) -> Self::Assoc { + //~^ ERROR missing generics for associated type `Trait::Assoc` + todo!() + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr new file mode 100644 index 0000000000000..9263f3d67e3d2 --- /dev/null +++ b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr @@ -0,0 +1,35 @@ +error[E0107]: missing generics for associated type `Trait::Assoc` + --> $DIR/elided-in-expr-position.rs:10:26 + | +LL | fn g(&self) -> Self::Assoc; + | ^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/elided-in-expr-position.rs:5:10 + | +LL | type Assoc<'a> where Self: 'a; + | ^^^^^ -- +help: add missing lifetime argument + | +LL | fn g(&self) -> Self::Assoc<'_>; + | ~~~~~~~~~ + +error[E0107]: missing generics for associated type `Trait::Assoc` + --> $DIR/elided-in-expr-position.rs:32:26 + | +LL | fn g(&self) -> Self::Assoc { + | ^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/elided-in-expr-position.rs:5:10 + | +LL | type Assoc<'a> where Self: 'a; + | ^^^^^ -- +help: add missing lifetime argument + | +LL | fn g(&self) -> Self::Assoc<'_> { + | ~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/match/issue-82392.stdout b/src/test/ui/match/issue-82392.stdout index 4f46e32dc3070..2054d43c40957 100644 --- a/src/test/ui/match/issue-82392.stdout +++ b/src/test/ui/match/issue-82392.stdout @@ -7,13 +7,11 @@ extern crate std; // check-pass pub fn main() ({ - (if (true as bool) - ({ } as - ()) else if (let Some(a) = - ((Some as - fn(i32) -> Option {Option::::Some})((3 - as - i32)) - as Option) as bool) - ({ } as ()) as ()) - } as ()) + (if (true as bool) + ({ } as + ()) else if (let Some(a) = + ((Some as + fn(i32) -> Option {Option::::Some})((3 + as i32)) as Option) as bool) ({ } as ()) + as ()) + } as ()) diff --git a/src/test/ui/proc-macro/cfg-eval-inner.stdout b/src/test/ui/proc-macro/cfg-eval-inner.stdout index debbad57a8699..9d25def587cd6 100644 --- a/src/test/ui/proc-macro/cfg-eval-inner.stdout +++ b/src/test/ui/proc-macro/cfg-eval-inner.stdout @@ -1,9 +1,9 @@ PRINT-ATTR INPUT (DISPLAY): impl Foo < [u8 ; - { - #! [rustc_dummy(cursed_inner)] #! [allow(unused)] struct Inner - { field : [u8 ; { #! [rustc_dummy(another_cursed_inner)] 1 }] } 0 - }] > { #! [rustc_dummy(evaluated_attr)] fn bar() {} } +{ + #! [rustc_dummy(cursed_inner)] #! [allow(unused)] struct Inner + { field : [u8 ; { #! [rustc_dummy(another_cursed_inner)] 1 }] } 0 +}] > { #! [rustc_dummy(evaluated_attr)] fn bar() {} } PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "impl", diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout index fdd178a52292f..c81fa201cbcf5 100644 --- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout @@ -4,23 +4,23 @@ struct Foo < #[cfg(FALSE)] A, B > #[cfg(FALSE)] first : String, #[cfg_attr(FALSE, deny(warnings))] second : bool, third : [u8 ; - { - #[cfg(FALSE)] struct Bar ; #[cfg(not(FALSE))] struct Inner ; - #[cfg(FALSE)] let a = 25 ; match true - { - #[cfg(FALSE)] true => {}, - #[cfg_attr(not(FALSE), allow(warnings))] false => {}, _ => {} - } ; #[print_helper(should_be_removed)] fn removed_fn() - { #! [cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn - kept_fn() { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum - { - Foo(#[cfg(FALSE)] u8, #[cfg(FALSE)] bool, #[cfg(not(FALSE))] i32, - #[cfg(FALSE)] String, u8) - } struct - TupleStruct(#[cfg(FALSE)] String, #[cfg(not(FALSE))] i32, - #[cfg(FALSE)] bool, u8) ; fn plain_removed_fn() - { #! [cfg_attr(not(FALSE), cfg(FALSE))] } 0 - }], #[print_helper(d)] fourth : B + { + #[cfg(FALSE)] struct Bar ; #[cfg(not(FALSE))] struct Inner ; + #[cfg(FALSE)] let a = 25 ; match true + { + #[cfg(FALSE)] true => {}, #[cfg_attr(not(FALSE), allow(warnings))] + false => {}, _ => {} + } ; #[print_helper(should_be_removed)] fn removed_fn() + { #! [cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn kept_fn() + { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum + { + Foo(#[cfg(FALSE)] u8, #[cfg(FALSE)] bool, #[cfg(not(FALSE))] i32, + #[cfg(FALSE)] String, u8) + } struct + TupleStruct(#[cfg(FALSE)] String, #[cfg(not(FALSE))] i32, + #[cfg(FALSE)] bool, u8) ; fn plain_removed_fn() + { #! [cfg_attr(not(FALSE), cfg(FALSE))] } 0 + }], #[print_helper(d)] fourth : B } PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { @@ -1276,14 +1276,14 @@ PRINT-DERIVE INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_hel { second : bool, third : [u8 ; - { - #[cfg(not(FALSE))] struct Inner ; match true - { #[allow(warnings)] false => {}, _ => {} } ; #[print_helper(c)] - #[cfg(not(FALSE))] fn kept_fn() - { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum - { Foo(#[cfg(not(FALSE))] i32, u8) } struct - TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0 - }], #[print_helper(d)] fourth : B + { + #[cfg(not(FALSE))] struct Inner ; match true + { #[allow(warnings)] false => {}, _ => {} } ; #[print_helper(c)] + #[cfg(not(FALSE))] fn kept_fn() + { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum + { Foo(#[cfg(not(FALSE))] i32, u8) } struct + TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0 + }], #[print_helper(d)] fourth : B } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { diff --git a/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout b/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout index 6e2b6a2e5bdf6..74641058ef3d2 100644 --- a/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout +++ b/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout @@ -2,10 +2,10 @@ PRINT-DERIVE INPUT (DISPLAY): struct Foo { val : [bool ; - { - let a = #[rustc_dummy(first)] #[rustc_dummy(second)] - { #! [allow(unused)] 30 } ; 0 - }] + { + let a = #[rustc_dummy(first)] #[rustc_dummy(second)] + { #! [allow(unused)] 30 } ; 0 + }] } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { diff --git a/src/test/ui/proc-macro/quote-debug.stdout b/src/test/ui/proc-macro/quote-debug.stdout index 4bdc04b9ac430..79651f01b9534 100644 --- a/src/test/ui/proc-macro/quote-debug.stdout +++ b/src/test/ui/proc-macro/quote-debug.stdout @@ -19,29 +19,27 @@ extern crate proc_macro; fn main() { [crate::TokenStream::from(crate::TokenTree::Ident(crate::Ident::new("let", - crate::Span::recover_proc_macro_span(0)))), - crate::TokenStream::from(crate::TokenTree::Ident(crate::Ident::new("hello", - crate::Span::recover_proc_macro_span(1)))), - crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3d}', - crate::Spacing::Alone))), - crate::TokenStream::from(crate::TokenTree::Literal({ - let mut iter = - "\"world\"".parse::().unwrap().into_iter(); - if let (Some(crate::TokenTree::Literal(mut lit)), - None) = - (iter.next(), - iter.next()) - { - lit.set_span(crate::Span::recover_proc_macro_span(2)); - lit - } else { - { - ::core::panicking::panic("internal error: entered unreachable code") - } - } - })), - crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3b}', - crate::Spacing::Alone)))].iter().cloned().collect::() + crate::Span::recover_proc_macro_span(0)))), + crate::TokenStream::from(crate::TokenTree::Ident(crate::Ident::new("hello", + crate::Span::recover_proc_macro_span(1)))), + crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3d}', + crate::Spacing::Alone))), + crate::TokenStream::from(crate::TokenTree::Literal({ + let mut iter = + "\"world\"".parse::().unwrap().into_iter(); + if let (Some(crate::TokenTree::Literal(mut lit)), + None) = + (iter.next(), iter.next()) { + lit.set_span(crate::Span::recover_proc_macro_span(2)); + lit + } else { + { + ::core::panicking::panic("internal error: entered unreachable code") + } + } + })), + crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3b}', + crate::Spacing::Alone)))].iter().cloned().collect::() } const _: () = { diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs index 8800d3e66f9e4..82c4120b4c789 100644 --- a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs +++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs @@ -37,7 +37,7 @@ checker!(rename_params, r#"impl Foo fn hello(#[angery(true)] a : i32, #[a2] b : i32, #[what = "how"] c : u32) {} fn hello2(#[a1] #[a2] a : i32, #[what = "how"] b : i32, #[angery(true)] c : - u32) {} fn + u32) {} fn hello_self(#[a1] #[a2] & self, #[a1] #[a2] a : i32, #[what = "how"] b : - i32, #[angery(true)] c : u32) {} + i32, #[angery(true)] c : u32) {} }"#); diff --git a/src/test/ui/suggestions/private-field.rs b/src/test/ui/suggestions/private-field.rs new file mode 100644 index 0000000000000..1cc4d2a4d066e --- /dev/null +++ b/src/test/ui/suggestions/private-field.rs @@ -0,0 +1,19 @@ +// compile-flags: --crate-type lib +pub struct S { + pub val: string::MyString, +} + +pub fn test(s: S) { + dbg!(s.cap) //~ ERROR: no field `cap` on type `S` [E0609] +} + +pub(crate) mod string { + + pub struct MyString { + buf: MyVec, + } + + struct MyVec { + cap: usize, + } +} diff --git a/src/test/ui/suggestions/private-field.stderr b/src/test/ui/suggestions/private-field.stderr new file mode 100644 index 0000000000000..c38c795e07ae8 --- /dev/null +++ b/src/test/ui/suggestions/private-field.stderr @@ -0,0 +1,11 @@ +error[E0609]: no field `cap` on type `S` + --> $DIR/private-field.rs:7:12 + | +LL | dbg!(s.cap) + | ^^^ unknown field + | + = note: available fields are: `val` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.stdout b/src/test/ui/type-alias-impl-trait/issue-60662.stdout index 14a49f20e6b22..a46047d91743d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60662.stdout +++ b/src/test/ui/type-alias-impl-trait/issue-60662.stdout @@ -10,5 +10,5 @@ extern crate std; trait Animal { } fn main() { - pub type ServeFut = /*impl Trait*/; - } + pub type ServeFut = /*impl Trait*/; + }