diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b7f227da73e..f076dca5cf5 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1076,16 +1076,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_assoc_ty_constraint( &mut self, constraint: &AssocTyConstraint, - itctx: ImplTraitContext<'_, 'hir>, + mut itctx: ImplTraitContext<'_, 'hir>, ) -> hir::TypeBinding<'hir> { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); - if let Some(ref gen_args) = constraint.gen_args { - self.sess.span_fatal( - gen_args.span(), - "generic associated types in trait paths are currently not implemented", - ); - } + // lower generic arguments of identifier in constraint + let gen_args = if let Some(ref gen_args) = constraint.gen_args { + let gen_args_ctor = match gen_args { + GenericArgs::AngleBracketed(ref data) => { + self.lower_angle_bracketed_parameter_data( + data, + ParamMode::Explicit, + itctx.reborrow(), + ) + .0 + } + GenericArgs::Parenthesized(ref data) => { + let mut err = self.sess.struct_span_err( + gen_args.span(), + "parenthesized generic arguments cannot be used in associated type constraints" + ); + // FIXME: try to write a suggestion here + err.emit(); + self.lower_angle_bracketed_parameter_data( + &data.as_angle_bracketed_args(), + ParamMode::Explicit, + itctx.reborrow(), + ) + .0 + } + }; + self.arena.alloc(gen_args_ctor.into_generic_args(&self.arena)) + } else { + self.arena.alloc(hir::GenericArgs::none()) + }; let kind = match constraint.kind { AssocTyConstraintKind::Equality { ref ty } => { @@ -1182,6 +1206,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBinding { hir_id: self.lower_node_id(constraint.id), ident: constraint.ident, + gen_args, kind, span: constraint.span, } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 9079e26eb50..cb4d5ea6ee6 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -362,7 +362,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_angle_bracketed_parameter_data( + pub(crate) fn lower_angle_bracketed_parameter_data( &mut self, data: &AngleBracketedArgs, param_mode: ParamMode, @@ -426,6 +426,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::TypeBinding<'hir> { let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME); let kind = hir::TypeBindingKind::Equality { ty }; - hir::TypeBinding { hir_id: self.next_id(), span, ident, kind } + let args = arena_vec![self;]; + let bindings = arena_vec![self;]; + let gen_args = self.arena.alloc(hir::GenericArgs { args, bindings, parenthesized: false }); + hir::TypeBinding { hir_id: self.next_id(), gen_args, span, ident, kind } } } diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 9a85b9d02c9..f0b413c795e 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -590,24 +590,21 @@ pub fn print_time_passes_entry( end_rss: Option, ) { let rss_to_mb = |rss| (rss as f64 / 1_000_000.0).round() as usize; + let rss_change_to_mb = |rss| (rss as f64 / 1_000_000.0).round() as i128; let mem_string = match (start_rss, end_rss) { (Some(start_rss), Some(end_rss)) => { - // It's tempting to add the change in RSS from start to end, but its somewhat confusing - // and misleading when looking at time-passes output. Consider two adjacent entries: - // - // time: 10.000; rss start: 1000MB, end: 1000MB, change: 0MB pass1 - // time: 5.000; rss start: 2000MB, end: 2000MB, change: 0MB pass2 - // - // If you're looking for jumps in RSS based on the change column, you miss the fact - // that a 1GB jump happened between pass1 and pass2 (supposing pass1 and pass2 actually - // occur sequentially and pass1 isn't just nested within pass2). It's easy to imagine - // someone missing this or being confused by the fact that the change is zero. + let change_rss = end_rss as i128 - start_rss as i128; - format!("; rss: {:>5}MB -> {:>5}MB", rss_to_mb(start_rss), rss_to_mb(end_rss)) + format!( + "; rss: {:>4}MB -> {:>4}MB ({:>+5}MB)", + rss_to_mb(start_rss), + rss_to_mb(end_rss), + rss_change_to_mb(change_rss), + ) } - (Some(start_rss), None) => format!("; rss start: {:>5}MB", rss_to_mb(start_rss)), - (None, Some(end_rss)) => format!("; rss end: {:5>}MB", rss_to_mb(end_rss)), + (Some(start_rss), None) => format!("; rss start: {:>4}MB", rss_to_mb(start_rss)), + (None, Some(end_rss)) => format!("; rss end: {:>4}MB", rss_to_mb(end_rss)), (None, None) => String::new(), }; diff --git a/compiler/rustc_error_codes/src/error_codes/E0463.md b/compiler/rustc_error_codes/src/error_codes/E0463.md index e46938c607d..d0cd1b1dcb7 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0463.md +++ b/compiler/rustc_error_codes/src/error_codes/E0463.md @@ -11,3 +11,24 @@ extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie` You need to link your code to the relevant crate in order to be able to use it (through Cargo or the `-L` option of rustc example). Plugins are crates as well, and you link to them the same way. + +## Common causes + +- The crate is not present at all. If using Cargo, add it to `[dependencies]` + in Cargo.toml. +- The crate is present, but under a different name. If using Cargo, look for + `package = ` under `[dependencies]` in Cargo.toml. + +## Common causes for missing `std` or `core` + +- You are cross-compiling for a target which doesn't have `std` prepackaged. + Consider one of the following: + + Adding a pre-compiled version of std with `rustup target add` + + Building std from source with `cargo build -Z build-std` + + Using `#![no_std]` at the crate root, so you won't need `std` in the first + place. +- You are developing the compiler itself and haven't built libstd from source. + You can usually build it with `x.py build library/std`. More information + about x.py is available in the [rustc-dev-guide]. + +[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#building-the-compiler diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 818f6c70de0..4f38e060023 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -631,6 +631,9 @@ declare_features! ( /// Allows `extern "C-cmse-nonsecure-call" fn()`. (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None), + + /// Lessens the requirements for structs to implement `Unsize`. + (active, relaxed_struct_unsize, "1.51.0", Some(1), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 6487b23a6a6..67a15418ea4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2015,6 +2015,7 @@ pub struct TypeBinding<'hir> { pub hir_id: HirId, #[stable_hasher(project(name))] pub ident: Ident, + pub gen_args: &'hir GenericArgs<'hir>, pub kind: TypeBindingKind<'hir>, pub span: Span, } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 6c1bee2335a..f8b3f0d9b6e 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -781,6 +781,7 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>( ) { visitor.visit_id(type_binding.hir_id); visitor.visit_ident(type_binding.ident); + visitor.visit_generic_args(type_binding.span, type_binding.gen_args); match type_binding.kind { TypeBindingKind::Equality { ref ty } => { visitor.visit_ty(ty); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index f1c2a6b7e6e..4595855309f 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1840,6 +1840,7 @@ impl<'a> State<'a> { for binding in generic_args.bindings.iter() { start_or_comma(self); self.print_ident(binding.ident); + self.print_generic_args(binding.gen_args, false, false); self.s.space(); match generic_args.bindings[0].kind { hir::TypeBindingKind::Equality { ref ty } => { diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 0b501da7cd9..100824f4b94 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -707,6 +707,18 @@ impl GrowableBitSet { self.bit_set.insert(elem) } + /// Returns `true` if the set has changed. + #[inline] + pub fn remove(&mut self, elem: T) -> bool { + self.ensure(elem.index() + 1); + self.bit_set.remove(elem) + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.bit_set.is_empty() + } + #[inline] pub fn contains(&self, elem: T) -> bool { let (word_index, mask) = word_index_and_mask(elem); diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 6cc3e9427d1..c11b98e77aa 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -1,6 +1,7 @@ use super::*; extern crate test; +use std::hint::black_box; use test::Bencher; #[test] @@ -364,3 +365,36 @@ fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { sparse.union(&dense); }) } + +#[bench] +fn bench_insert(b: &mut Bencher) { + let mut bs = BitSet::new_filled(99999usize); + b.iter(|| { + black_box(bs.insert(black_box(100u32))); + }); +} + +#[bench] +fn bench_remove(b: &mut Bencher) { + let mut bs = BitSet::new_filled(99999usize); + b.iter(|| { + black_box(bs.remove(black_box(100u32))); + }); +} + +#[bench] +fn bench_iter(b: &mut Bencher) { + let bs = BitSet::new_filled(99999usize); + b.iter(|| { + bs.iter().map(|b: usize| black_box(b)).for_each(drop); + }); +} + +#[bench] +fn bench_intersect(b: &mut Bencher) { + let mut ba: BitSet = BitSet::new_filled(99999usize); + let bb = BitSet::new_filled(99999usize); + b.iter(|| { + ba.intersect(black_box(&bb)); + }); +} diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 6b4f08d9f93..c1fa84dcb25 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1132,8 +1132,16 @@ impl<'tcx> ProjectionTy<'tcx> { /// For example, if this is a projection of `::Item`, /// then this function would return a `T: Iterator` trait reference. pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { + // FIXME: This method probably shouldn't exist at all, since it's not + // clear what this method really intends to do. Be careful when + // using this method since the resulting TraitRef additionally + // contains the substs for the assoc_item, which strictly speaking + // is not correct let def_id = tcx.associated_item(self.item_def_id).container.id(); - ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) } + // Include substitutions for generic arguments of associated types + let assoc_item = tcx.associated_item(self.item_def_id); + let substs_assoc_item = self.substs.truncate_to(tcx, tcx.generics_of(assoc_item.def_id)); + ty::TraitRef { def_id, substs: substs_assoc_item } } pub fn self_ty(&self) -> Ty<'tcx> { diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index b5b34c7338d..4a638ec3f80 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -14,7 +14,7 @@ mod tokentrees; mod unescape_error_reporting; mod unicode_chars; -use unescape_error_reporting::{emit_unescape_error, push_escaped_char}; +use unescape_error_reporting::{emit_unescape_error, escaped_char}; #[derive(Clone, Debug)] pub struct UnmatchedBrace { @@ -122,11 +122,9 @@ impl<'a> StringReader<'a> { m: &str, c: char, ) -> DiagnosticBuilder<'a> { - let mut m = m.to_string(); - m.push_str(": "); - push_escaped_char(&mut m, c); - - self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), &m[..]) + self.sess + .span_diagnostic + .struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c))) } /// Turns simple `rustc_lexer::TokenKind` enum into a rich @@ -421,7 +419,7 @@ impl<'a> StringReader<'a> { let content_start = start + BytePos(prefix_len); let content_end = suffix_start - BytePos(postfix_len); let id = self.symbol_from_to(content_start, content_end); - self.validate_literal_escape(mode, content_start, content_end); + self.validate_literal_escape(mode, content_start, content_end, prefix_len, postfix_len); (lit_kind, id) } @@ -525,17 +523,29 @@ impl<'a> StringReader<'a> { .raise(); } - fn validate_literal_escape(&self, mode: Mode, content_start: BytePos, content_end: BytePos) { + fn validate_literal_escape( + &self, + mode: Mode, + content_start: BytePos, + content_end: BytePos, + prefix_len: u32, + postfix_len: u32, + ) { let lit_content = self.str_from_to(content_start, content_end); unescape::unescape_literal(lit_content, mode, &mut |range, result| { // Here we only check for errors. The actual unescaping is done later. if let Err(err) = result { - let span_with_quotes = - self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)); + let span_with_quotes = self + .mk_sp(content_start - BytePos(prefix_len), content_end + BytePos(postfix_len)); + let (start, end) = (range.start as u32, range.end as u32); + let lo = content_start + BytePos(start); + let hi = lo + BytePos(end - start); + let span = self.mk_sp(lo, hi); emit_unescape_error( &self.sess.span_diagnostic, lit_content, span_with_quotes, + span, mode, range, err, diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 47d317f9188..a580f0c55d0 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -13,6 +13,8 @@ pub(crate) fn emit_unescape_error( lit: &str, // full span of the literal, including quotes span_with_quotes: Span, + // interior span of the literal, without quotes + span: Span, mode: Mode, // range of the error inside `lit` range: Range, @@ -26,13 +28,6 @@ pub(crate) fn emit_unescape_error( range, error ); - let span = { - let Range { start, end } = range; - let (start, end) = (start as u32, end as u32); - let lo = span_with_quotes.lo() + BytePos(start + 1); - let hi = lo + BytePos(end - start); - span_with_quotes.with_lo(lo).with_hi(hi) - }; let last_char = || { let c = lit[range.clone()].chars().rev().next().unwrap(); let span = span.with_lo(span.hi() - BytePos(c.len_utf8() as u32)); @@ -42,20 +37,22 @@ pub(crate) fn emit_unescape_error( EscapeError::LoneSurrogateUnicodeEscape => { handler .struct_span_err(span, "invalid unicode character escape") + .span_label(span, "invalid escape") .help("unicode escape must not be a surrogate") .emit(); } EscapeError::OutOfRangeUnicodeEscape => { handler .struct_span_err(span, "invalid unicode character escape") + .span_label(span, "invalid escape") .help("unicode escape must be at most 10FFFF") .emit(); } EscapeError::MoreThanOneChar => { - let msg = if mode.is_bytes() { - "if you meant to write a byte string literal, use double quotes" + let (prefix, msg) = if mode.is_bytes() { + ("b", "if you meant to write a byte string literal, use double quotes") } else { - "if you meant to write a `str` literal, use double quotes" + ("", "if you meant to write a `str` literal, use double quotes") }; handler @@ -66,31 +63,44 @@ pub(crate) fn emit_unescape_error( .span_suggestion( span_with_quotes, msg, - format!("\"{}\"", lit), + format!("{}\"{}\"", prefix, lit), Applicability::MachineApplicable, ) .emit(); } EscapeError::EscapeOnlyChar => { - let (c, _span) = last_char(); + let (c, char_span) = last_char(); - let mut msg = if mode.is_bytes() { - "byte constant must be escaped: " + let msg = if mode.is_bytes() { + "byte constant must be escaped" } else { - "character constant must be escaped: " - } - .to_string(); - push_escaped_char(&mut msg, c); - - handler.span_err(span, msg.as_str()) + "character constant must be escaped" + }; + handler + .struct_span_err(span, &format!("{}: `{}`", msg, escaped_char(c))) + .span_suggestion( + char_span, + "escape the character", + c.escape_default().to_string(), + Applicability::MachineApplicable, + ) + .emit() } EscapeError::BareCarriageReturn => { let msg = if mode.in_double_quotes() { - "bare CR not allowed in string, use \\r instead" + "bare CR not allowed in string, use `\\r` instead" } else { - "character constant must be escaped: \\r" + "character constant must be escaped: `\\r`" }; - handler.span_err(span, msg); + handler + .struct_span_err(span, msg) + .span_suggestion( + span, + "escape the character", + "\\r".to_string(), + Applicability::MachineApplicable, + ) + .emit(); } EscapeError::BareCarriageReturnInRawString => { assert!(mode.in_double_quotes()); @@ -102,21 +112,22 @@ pub(crate) fn emit_unescape_error( let label = if mode.is_bytes() { "unknown byte escape" } else { "unknown character escape" }; - let mut msg = label.to_string(); - msg.push_str(": "); - push_escaped_char(&mut msg, c); - - let mut diag = handler.struct_span_err(span, msg.as_str()); + let ec = escaped_char(c); + let mut diag = handler.struct_span_err(span, &format!("{}: `{}`", label, ec)); diag.span_label(span, label); if c == '{' || c == '}' && !mode.is_bytes() { diag.help( - "if used in a formatting string, \ - curly braces are escaped with `{{` and `}}`", + "if used in a formatting string, curly braces are escaped with `{{` and `}}`", ); } else if c == '\r' { diag.help( - "this is an isolated carriage return; \ - consider checking your editor and version control settings", + "this is an isolated carriage return; consider checking your editor and \ + version control settings", + ); + } else { + diag.help( + "for more information, visit \ + ", ); } diag.emit(); @@ -127,45 +138,70 @@ pub(crate) fn emit_unescape_error( EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => { let (c, span) = last_char(); - let mut msg = if error == EscapeError::InvalidCharInHexEscape { - "invalid character in numeric character escape: " + let msg = if error == EscapeError::InvalidCharInHexEscape { + "invalid character in numeric character escape" } else { - "invalid character in unicode escape: " - } - .to_string(); - push_escaped_char(&mut msg, c); + "invalid character in unicode escape" + }; + let c = escaped_char(c); - handler.span_err(span, msg.as_str()) + handler + .struct_span_err(span, &format!("{}: `{}`", msg, c)) + .span_label(span, msg) + .emit(); } EscapeError::NonAsciiCharInByte => { assert!(mode.is_bytes()); - let (_c, span) = last_char(); - handler.span_err( - span, - "byte constant must be ASCII. \ - Use a \\xHH escape for a non-ASCII byte", - ) + let (c, span) = last_char(); + handler + .struct_span_err(span, "non-ASCII character in byte constant") + .span_label(span, "byte constant must be ASCII") + .span_suggestion( + span, + "use a \\xHH escape for a non-ASCII byte", + format!("\\x{:X}", c as u32), + Applicability::MachineApplicable, + ) + .emit(); } EscapeError::NonAsciiCharInByteString => { assert!(mode.is_bytes()); let (_c, span) = last_char(); - handler.span_err(span, "raw byte string must be ASCII") + handler + .struct_span_err(span, "raw byte string must be ASCII") + .span_label(span, "must be ASCII") + .emit(); + } + EscapeError::OutOfRangeHexEscape => { + handler + .struct_span_err(span, "out of range hex escape") + .span_label(span, "must be a character in the range [\\x00-\\x7f]") + .emit(); } - EscapeError::OutOfRangeHexEscape => handler.span_err( - span, - "this form of character escape may only be used \ - with characters in the range [\\x00-\\x7f]", - ), EscapeError::LeadingUnderscoreUnicodeEscape => { - let (_c, span) = last_char(); - handler.span_err(span, "invalid start of unicode escape") + let (c, span) = last_char(); + let msg = "invalid start of unicode escape"; + handler + .struct_span_err(span, &format!("{}: `{}`", msg, c)) + .span_label(span, msg) + .emit(); } EscapeError::OverlongUnicodeEscape => { - handler.span_err(span, "overlong unicode escape (must have at most 6 hex digits)") - } - EscapeError::UnclosedUnicodeEscape => { - handler.span_err(span, "unterminated unicode escape (needed a `}`)") + handler + .struct_span_err(span, "overlong unicode escape") + .span_label(span, "must have at most 6 hex digits") + .emit(); } + EscapeError::UnclosedUnicodeEscape => handler + .struct_span_err(span, "unterminated unicode escape") + .span_label(span, "missing a closing `}`") + .span_suggestion_verbose( + span.shrink_to_hi(), + "terminate the unicode escape", + "}".to_string(), + Applicability::MaybeIncorrect, + ) + .emit(), EscapeError::NoBraceInUnicodeEscape => { let msg = "incorrect unicode escape sequence"; let mut diag = handler.struct_span_err(span, msg); @@ -195,28 +231,38 @@ pub(crate) fn emit_unescape_error( diag.emit(); } - EscapeError::UnicodeEscapeInByte => handler.span_err( - span, - "unicode escape sequences cannot be used \ - as a byte or in a byte string", - ), - EscapeError::EmptyUnicodeEscape => { - handler.span_err(span, "empty unicode escape (must have at least 1 hex digit)") + EscapeError::UnicodeEscapeInByte => { + let msg = "unicode escape in byte string"; + handler + .struct_span_err(span, msg) + .span_label(span, msg) + .help("unicode escape sequences cannot be used as a byte or in a byte string") + .emit(); + } + EscapeError::EmptyUnicodeEscape => { + handler + .struct_span_err(span, "empty unicode escape") + .span_label(span, "this escape must have at least 1 hex digit") + .emit(); + } + EscapeError::ZeroChars => { + let msg = "empty character literal"; + handler.struct_span_err(span, msg).span_label(span, msg).emit() + } + EscapeError::LoneSlash => { + let msg = "invalid trailing slash in literal"; + handler.struct_span_err(span, msg).span_label(span, msg).emit(); } - EscapeError::ZeroChars => handler.span_err(span, "empty character literal"), - EscapeError::LoneSlash => handler.span_err(span, "invalid trailing slash in literal"), } } /// Pushes a character to a message string for error reporting -pub(crate) fn push_escaped_char(msg: &mut String, c: char) { +pub(crate) fn escaped_char(c: char) -> String { match c { '\u{20}'..='\u{7e}' => { // Don't escape \, ' or " for user-facing messages - msg.push(c); - } - _ => { - msg.extend(c.escape_default()); + c.to_string() } + _ => c.escape_default().to_string(), } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index df23b4006b3..86f8061a24a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -907,6 +907,7 @@ symbols! { register_attr, register_tool, relaxed_adts, + relaxed_struct_unsize, rem, rem_assign, repr, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 3852005ee3f..e155f0366e1 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -257,13 +257,11 @@ fn predicates_reference_self( } fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> { - let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); tcx.associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) .flat_map(|item| tcx.explicit_item_bounds(item.def_id)) - .map(|&(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp)) - .filter_map(|predicate| predicate_references_self(tcx, predicate)) + .filter_map(|pred_span| predicate_references_self(tcx, *pred_span)) .collect() } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3015188fd44..ed3e117fcfa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -823,33 +823,59 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }, }; + // FIXME(eddyb) cache this (including computing `unsizing_params`) + // by putting it in a query; it would only need the `DefId` as it + // looks at declared field types, not anything substituted. + // The last field of the structure has to exist and contain type/const parameters. let (tail_field, prefix_fields) = def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?; let tail_field_ty = tcx.type_of(tail_field.did); let mut unsizing_params = GrowableBitSet::new_empty(); - let mut found = false; - for arg in tail_field_ty.walk() { - if let Some(i) = maybe_unsizing_param_idx(arg) { - unsizing_params.insert(i); - found = true; - } - } - if !found { - return Err(Unimplemented); - } - - // Ensure none of the other fields mention the parameters used - // in unsizing. - // FIXME(eddyb) cache this (including computing `unsizing_params`) - // by putting it in a query; it would only need the `DefId` as it - // looks at declared field types, not anything substituted. - for field in prefix_fields { - for arg in tcx.type_of(field.did).walk() { + if tcx.features().relaxed_struct_unsize { + for arg in tail_field_ty.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { - if unsizing_params.contains(i) { - return Err(Unimplemented); + unsizing_params.insert(i); + } + } + + // Ensure none of the other fields mention the parameters used + // in unsizing. + for field in prefix_fields { + for arg in tcx.type_of(field.did).walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + unsizing_params.remove(i); + } + } + } + + if unsizing_params.is_empty() { + return Err(Unimplemented); + } + } else { + let mut found = false; + for arg in tail_field_ty.walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + unsizing_params.insert(i); + found = true; + } + } + if !found { + return Err(Unimplemented); + } + + // Ensure none of the other fields mention the parameters used + // in unsizing. + // FIXME(eddyb) cache this (including computing `unsizing_params`) + // by putting it in a query; it would only need the `DefId` as it + // looks at declared field types, not anything substituted. + for field in prefix_fields { + for arg in tcx.type_of(field.did).walk() { + if let Some(i) = maybe_unsizing_param_idx(arg) { + if unsizing_params.contains(i) { + return Err(Unimplemented); + } } } } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 437813ea41b..5659345f0ff 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -112,12 +112,15 @@ pub enum SizedByDefault { No, } +#[derive(Debug)] struct ConvertedBinding<'a, 'tcx> { item_name: Ident, kind: ConvertedBindingKind<'a, 'tcx>, + gen_args: &'a GenericArgs<'a>, span: Span, } +#[derive(Debug)] enum ConvertedBindingKind<'a, 'tcx> { Equality(Ty<'tcx>), Constraint(&'a [hir::GenericBound<'a>]), @@ -323,6 +326,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); let generics = tcx.generics_of(def_id); + debug!("generics: {:?}", generics); if generics.has_self { if generics.parent.is_some() { @@ -557,7 +561,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ConvertedBindingKind::Constraint(bounds) } }; - ConvertedBinding { item_name: binding.ident, kind, span: binding.span } + ConvertedBinding { + item_name: binding.ident, + kind, + gen_args: binding.gen_args, + span: binding.span, + } }) .collect(); @@ -918,61 +927,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { dup_bindings: &mut FxHashMap, path_span: Span, ) -> Result<(), ErrorReported> { + // Given something like `U: SomeTrait`, we want to produce a + // predicate like `::T = X`. This is somewhat + // subtle in the event that `T` is defined in a supertrait of + // `SomeTrait`, because in that case we need to upcast. + // + // That is, consider this case: + // + // ``` + // trait SubTrait: SuperTrait { } + // trait SuperTrait { type T; } + // + // ... B: SubTrait ... + // ``` + // + // We want to produce `>::T == foo`. + + debug!( + "add_predicates_for_ast_type_binding(hir_ref_id {:?}, trait_ref {:?}, binding {:?}, bounds {:?}", + hir_ref_id, trait_ref, binding, bounds + ); let tcx = self.tcx(); - if !speculative { - // Given something like `U: SomeTrait`, we want to produce a - // predicate like `::T = X`. This is somewhat - // subtle in the event that `T` is defined in a supertrait of - // `SomeTrait`, because in that case we need to upcast. - // - // That is, consider this case: - // - // ``` - // trait SubTrait: SuperTrait { } - // trait SuperTrait { type T; } - // - // ... B: SubTrait ... - // ``` - // - // We want to produce `>::T == foo`. - - // Find any late-bound regions declared in `ty` that are not - // declared in the trait-ref. These are not well-formed. - // - // Example: - // - // for<'a> ::Item = &'a str // <-- 'a is bad - // for<'a> >::Output = &'a str // <-- 'a is ok - if let ConvertedBindingKind::Equality(ty) = binding.kind { - let late_bound_in_trait_ref = - tcx.collect_constrained_late_bound_regions(&trait_ref); - let late_bound_in_ty = - tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty)); - debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); - debug!("late_bound_in_ty = {:?}", late_bound_in_ty); - - // FIXME: point at the type params that don't have appropriate lifetimes: - // struct S1 Fn(&i32, &i32) -> &'a i32>(F); - // ---- ---- ^^^^^^^ - self.validate_late_bound_regions( - late_bound_in_trait_ref, - late_bound_in_ty, - |br_name| { - struct_span_err!( - tcx.sess, - binding.span, - E0582, - "binding for associated type `{}` references {}, \ - which does not appear in the trait input types", - binding.item_name, - br_name - ) - }, - ); - } - } - let candidate = if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) { // Simple case: X is defined in the current trait. @@ -1030,6 +1006,72 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .or_insert(binding.span); } + // Include substitutions for generic parameters of associated types + let projection_ty = candidate.map_bound(|trait_ref| { + let item_segment = hir::PathSegment { + ident: assoc_ty.ident, + hir_id: None, + res: None, + args: Some(binding.gen_args), + infer_args: false, + }; + + let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item( + tcx, + path_span, + assoc_ty.def_id, + &item_segment, + trait_ref.substs, + ); + + debug!( + "add_predicates_for_ast_type_binding: substs for trait-ref and assoc_item: {:?}", + substs_trait_ref_and_assoc_item + ); + + ty::ProjectionTy { + item_def_id: assoc_ty.def_id, + substs: substs_trait_ref_and_assoc_item, + } + }); + + if !speculative { + // Find any late-bound regions declared in `ty` that are not + // declared in the trait-ref or assoc_ty. These are not well-formed. + // + // Example: + // + // for<'a> ::Item = &'a str // <-- 'a is bad + // for<'a> >::Output = &'a str // <-- 'a is ok + if let ConvertedBindingKind::Equality(ty) = binding.kind { + let late_bound_in_trait_ref = + tcx.collect_constrained_late_bound_regions(&projection_ty); + let late_bound_in_ty = + tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty)); + debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); + debug!("late_bound_in_ty = {:?}", late_bound_in_ty); + + // FIXME: point at the type params that don't have appropriate lifetimes: + // struct S1 Fn(&i32, &i32) -> &'a i32>(F); + // ---- ---- ^^^^^^^ + self.validate_late_bound_regions( + late_bound_in_trait_ref, + late_bound_in_ty, + |br_name| { + struct_span_err!( + tcx.sess, + binding.span, + E0582, + "binding for associated type `{}` references {}, \ + which does not appear in the trait input types", + binding.item_name, + br_name + ) + }, + ); + } + } + match binding.kind { ConvertedBindingKind::Equality(ref ty) => { // "Desugar" a constraint like `T: Iterator` this to @@ -1037,13 +1079,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // // `::Item = u32` bounds.projection_bounds.push(( - candidate.map_bound(|trait_ref| ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy::from_ref_and_name( - tcx, - trait_ref, - binding.item_name, - ), - ty, + projection_ty.map_bound(|projection_ty| { + debug!( + "add_predicates_for_ast_type_binding: projection_ty {:?}, substs: {:?}", + projection_ty, projection_ty.substs + ); + ty::ProjectionPredicate { projection_ty, ty } }), binding.span, )); @@ -1055,7 +1096,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` // parameter to have a skipped binder. - let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs); + let param_ty = + tcx.mk_projection(assoc_ty.def_id, projection_ty.skip_binder().substs); self.add_bounds(param_ty, ast_bounds, bounds); } } diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index c572c66ce32..9dc3f05dae5 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -400,7 +400,7 @@ impl Layout { #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_deprecated( - since = "1.51.0", + since = "1.52.0", reason = "Name does not follow std convention, use LayoutError", suggestion = "LayoutError" )] @@ -409,7 +409,7 @@ pub type LayoutErr = LayoutError; /// The parameters given to `Layout::from_size_align` /// or some other `Layout` constructor /// do not satisfy its documented constraints. -#[stable(feature = "alloc_layout_error", since = "1.49.0")] +#[stable(feature = "alloc_layout_error", since = "1.50.0")] #[derive(Clone, PartialEq, Eq, Debug)] pub struct LayoutError { private: (), diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index 045eb58d013..06a761531b6 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -11,14 +11,14 @@ pub use self::global::GlobalAlloc; pub use self::layout::Layout; #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_deprecated( - since = "1.51.0", + since = "1.52.0", reason = "Name does not follow std convention, use LayoutError", suggestion = "LayoutError" )] #[allow(deprecated, deprecated_in_future)] pub use self::layout::LayoutErr; -#[stable(feature = "alloc_layout_error", since = "1.49.0")] +#[stable(feature = "alloc_layout_error", since = "1.50.0")] pub use self::layout::LayoutError; use crate::fmt; @@ -342,7 +342,10 @@ pub unsafe trait Allocator { /// /// The returned adaptor also implements `Allocator` and will simply borrow this. #[inline(always)] - fn by_ref(&self) -> &Self { + fn by_ref(&self) -> &Self + where + Self: Sized, + { self } } diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 4f7cf6018d9..a8da003d550 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -514,3 +514,11 @@ pub fn symlink, U: AsRef>( .fd() .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) } + +/// Create a symbolic link. +/// +/// This is a convenience API similar to [`std::os::unix::fs::symlink`] and +/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir). +pub fn symlink_path, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { + crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref()) +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f0e33be757d..d9132f20d85 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1880,8 +1880,7 @@ impl Step for RemoteCopyLibs { builder.info(&format!("REMOTE copy libs to emulator ({})", target)); t!(fs::create_dir_all(builder.out.join("tmp"))); - let server = - builder.ensure(tool::RemoteTestServer { compiler: compiler.with_stage(0), target }); + let server = builder.ensure(tool::RemoteTestServer { compiler, target }); // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); diff --git a/src/ci/scripts/install-awscli.sh b/src/ci/scripts/install-awscli.sh index f9b759fe343..3d8f0de7a39 100755 --- a/src/ci/scripts/install-awscli.sh +++ b/src/ci/scripts/install-awscli.sh @@ -27,7 +27,7 @@ if isLinux; then pip="pip3" pipflags="--user" - sudo apt-get install -y python3-setuptools + sudo apt-get install -y python3-setuptools python3-wheel ciCommandAddPath "${HOME}/.local/bin" fi diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index aa18684aea1..a20e9dec33b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -435,7 +435,7 @@ crate fn create_resolver<'a>( // Before we actually clone it, let's force all the extern'd crates to // actually be loaded, just in case they're only referred to inside - // intra-doc-links + // intra-doc links resolver.borrow_mut().access(|resolver| { sess.time("load_extern_crates", || { for extern_name in &extern_names { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 74b61f1555c..d7951961223 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1331,16 +1331,16 @@ impl clean::GenericArg { } crate fn display_fn(f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Display { + struct WithFormatter(Cell>); + + impl fmt::Display for WithFormatter + where + F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (self.0.take()).unwrap()(f) + } + } + WithFormatter(Cell::new(Some(f))) } - -struct WithFormatter(Cell>); - -impl fmt::Display for WithFormatter -where - F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (self.0.take()).unwrap()(f) - } -} diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b2e5c8834b8..026d8f96dee 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -154,7 +154,7 @@ impl From for ItemEnum { } ImportItem(i) => ItemEnum::ImportItem(i.into()), StructItem(s) => ItemEnum::StructItem(s.into()), - UnionItem(u) => ItemEnum::StructItem(u.into()), + UnionItem(u) => ItemEnum::UnionItem(u.into()), StructFieldItem(f) => ItemEnum::StructFieldItem(f.into()), EnumItem(e) => ItemEnum::EnumItem(e.into()), VariantItem(v) => ItemEnum::VariantItem(v.into()), @@ -162,8 +162,8 @@ impl From for ItemEnum { ForeignFunctionItem(f) => ItemEnum::FunctionItem(f.into()), TraitItem(t) => ItemEnum::TraitItem(t.into()), TraitAliasItem(t) => ItemEnum::TraitAliasItem(t.into()), - MethodItem(m, _) => ItemEnum::MethodItem(m.into()), - TyMethodItem(m) => ItemEnum::MethodItem(m.into()), + MethodItem(m, _) => ItemEnum::MethodItem(from_function_method(m, true)), + TyMethodItem(m) => ItemEnum::MethodItem(from_function_method(m, false)), ImplItem(i) => ItemEnum::ImplItem(i.into()), StaticItem(s) => ItemEnum::StaticItem(s.into()), ForeignStaticItem(s) => ItemEnum::StaticItem(s.into()), @@ -205,11 +205,10 @@ impl From for Struct { } } -impl From for Struct { +impl From for Union { fn from(struct_: clean::Union) -> Self { let clean::Union { generics, fields, fields_stripped } = struct_; - Struct { - struct_type: StructType::Union, + Union { generics: generics.into(), fields_stripped, fields: ids(fields), @@ -435,15 +434,13 @@ impl From for Impl { } } -impl From for Method { - fn from(function: clean::Function) -> Self { - let clean::Function { header, decl, generics, all_types: _, ret_types: _ } = function; - Method { - decl: decl.into(), - generics: generics.into(), - header: stringify_header(&header), - has_body: true, - } +crate fn from_function_method(function: clean::Function, has_body: bool) -> Method { + let clean::Function { header, decl, generics, all_types: _, ret_types: _ } = function; + Method { + decl: decl.into(), + generics: generics.into(), + header: stringify_header(&header), + has_body, } } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index a7c875fb748..876b1b56dee 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -243,7 +243,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), - format_version: 2, + format_version: 3, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 002d8938f69..532a0cf9329 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -44,7 +44,7 @@ use super::span_of_attrs; crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass { name: "collect-intra-doc-links", run: collect_intra_doc_links, - description: "reads a crate's documentation to resolve intra-doc-links", + description: "resolves intra-doc links", }; crate fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate { @@ -981,7 +981,7 @@ impl LinkCollector<'_, '_> { let link_text = disambiguator.map(|d| d.display_for(path_str)).unwrap_or_else(|| path_str.to_owned()); - // In order to correctly resolve intra-doc-links we need to + // In order to correctly resolve intra-doc links we need to // pick a base AST node to work from. If the documentation for // this module came from an inner comment (//!) then we anchor // our name resolution *inside* the module. If, on the other diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index a513c2abc87..11f572560d6 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -1,7 +1,7 @@ //! This pass is overloaded and runs two different lints. //! -//! - MISSING_DOC_CODE_EXAMPLES: this lint is **UNSTABLE** and looks for public items missing doc-tests -//! - PRIVATE_DOC_TESTS: this lint is **STABLE** and looks for private items with doc-tests. +//! - MISSING_DOC_CODE_EXAMPLES: this lint is **UNSTABLE** and looks for public items missing doctests +//! - PRIVATE_DOC_TESTS: this lint is **STABLE** and looks for private items with doctests. use super::{span_of_attrs, Pass}; use crate::clean; diff --git a/src/librustdoc/passes/non_autolinks.rs b/src/librustdoc/passes/non_autolinks.rs index 1f411b997f8..efb5df08caf 100644 --- a/src/librustdoc/passes/non_autolinks.rs +++ b/src/librustdoc/passes/non_autolinks.rs @@ -12,7 +12,7 @@ use rustc_session::lint; crate const CHECK_NON_AUTOLINKS: Pass = Pass { name: "check-non-autolinks", run: check_non_autolinks, - description: "detects URLS that could be written using angle brackets", + description: "detects URLs that could be linkified", }; const URL_REGEX: &str = concat!( diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index a276b7a6337..79f8562c472 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -11,7 +11,7 @@ use crate::passes::{ImplStripper, Pass}; crate const STRIP_HIDDEN: Pass = Pass { name: "strip-hidden", run: strip_hidden, - description: "strips all doc(hidden) items from the output", + description: "strips all `#[doc(hidden)]` items from the output", }; /// Strip items marked `#[doc(hidden)]` diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 3fb2a32d5a0..083f99e4a68 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -194,6 +194,7 @@ pub enum ItemEnum { }, ImportItem(Import), + UnionItem(Union), StructItem(Struct), StructFieldItem(Type), EnumItem(Enum), @@ -238,6 +239,14 @@ pub struct Module { pub items: Vec, } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct Union { + pub generics: Generics, + pub fields_stripped: bool, + pub fields: Vec, + pub impls: Vec, +} + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct Struct { pub struct_type: StructType, @@ -270,7 +279,6 @@ pub enum StructType { Plain, Tuple, Unit, - Union, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] diff --git a/src/test/rustdoc-json/traits/has_body.rs b/src/test/rustdoc-json/traits/has_body.rs new file mode 100644 index 00000000000..44dacb1ee75 --- /dev/null +++ b/src/test/rustdoc-json/traits/has_body.rs @@ -0,0 +1,21 @@ +// @has has_body.json "$.index[*][?(@.name=='Foo')]" +pub trait Foo { + // @has - "$.index[*][?(@.name=='no_self')].inner.has_body" false + fn no_self(); + // @has - "$.index[*][?(@.name=='move_self')].inner.has_body" false + fn move_self(self); + // @has - "$.index[*][?(@.name=='ref_self')].inner.has_body" false + fn ref_self(&self); + + // @has - "$.index[*][?(@.name=='no_self_def')].inner.has_body" true + fn no_self_def() {} + // @has - "$.index[*][?(@.name=='move_self_def')].inner.has_body" true + fn move_self_def(self) {} + // @has - "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true + fn ref_self_def(&self) {} +} + +pub trait Bar: Clone { + // @has - "$.index[*][?(@.name=='method')].inner.has_body" false + fn method(&self, param: usize); +} diff --git a/src/test/rustdoc-json/unions/union.rs b/src/test/rustdoc-json/unions/union.rs new file mode 100644 index 00000000000..ac2eb797791 --- /dev/null +++ b/src/test/rustdoc-json/unions/union.rs @@ -0,0 +1,7 @@ +// @has union.json "$.index[*][?(@.name=='Union')].visibility" \"public\" +// @has - "$.index[*][?(@.name=='Union')].kind" \"union\" +// @!has - "$.index[*][?(@.name=='Union')].inner.struct_type" +pub union Union { + int: i32, + float: f32, +} diff --git a/src/test/ui/allocator/object-safe.rs b/src/test/ui/allocator/object-safe.rs new file mode 100644 index 00000000000..fae7ab7fe33 --- /dev/null +++ b/src/test/ui/allocator/object-safe.rs @@ -0,0 +1,13 @@ +// run-pass + +// Check that `Allocator` is object safe, this allows for polymorphic allocators + +#![feature(allocator_api)] + +use std::alloc::{Allocator, System}; + +fn ensure_object_safe(_: &dyn Allocator) {} + +fn main() { + ensure_object_safe(&System); +} diff --git a/src/test/ui/attributes/key-value-non-ascii.rs b/src/test/ui/attributes/key-value-non-ascii.rs index 91c917e7db5..12942eabdf7 100644 --- a/src/test/ui/attributes/key-value-non-ascii.rs +++ b/src/test/ui/attributes/key-value-non-ascii.rs @@ -1,4 +1,4 @@ #![feature(rustc_attrs)] -#[rustc_dummy = b"ffi.rs"] //~ ERROR byte constant must be ASCII +#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte constant fn main() {} diff --git a/src/test/ui/attributes/key-value-non-ascii.stderr b/src/test/ui/attributes/key-value-non-ascii.stderr index 3e082139f89..1d4b0d5b2b1 100644 --- a/src/test/ui/attributes/key-value-non-ascii.stderr +++ b/src/test/ui/attributes/key-value-non-ascii.stderr @@ -1,8 +1,11 @@ -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/key-value-non-ascii.rs:3:19 | LL | #[rustc_dummy = b"ffi.rs"] | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xFB03` error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs new file mode 100644 index 00000000000..0cfd0a0b978 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.rs @@ -0,0 +1,10 @@ +// Test that we allow unsizing even if there is an unchanged param in the +// field getting unsized. +struct A(T, B); +struct B(T, U); + +fn main() { + let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1])); + let y: &A<[u32; 1], [u32]> = &x; //~ ERROR mismatched types + assert_eq!(y.1.1.len(), 1); +} diff --git a/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr new file mode 100644 index 00000000000..f62def47726 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-relaxed_struct_unsize.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/feature-gate-relaxed_struct_unsize.rs:8:34 + | +LL | let y: &A<[u32; 1], [u32]> = &x; + | ------------------- ^^ expected slice `[u32]`, found array `[u32; 1]` + | | + | expected due to this + | + = note: expected reference `&A<[u32; 1], [u32]>` + found reference `&A<[u32; 1], [u32; 1]>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs new file mode 100644 index 00000000000..2c543455b6e --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs @@ -0,0 +1,12 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'x>; +} + +fn main() { + fn _f(arg : Box X = &'a [u32]>>) {} + //~^ ERROR: use of undeclared lifetime name `'x` + //~| ERROR: binding for associated type `Y` references lifetime +} diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr new file mode 100644 index 00000000000..1c7c107d783 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr @@ -0,0 +1,29 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0261]: use of undeclared lifetime name `'x` + --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:9:35 + | +LL | fn _f(arg : Box X = &'a [u32]>>) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'x` here: `<'x>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes + +error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types + --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:9:33 + | +LL | fn _f(arg : Box X = &'a [u32]>>) {} + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0261, E0582. +For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.rs b/src/test/ui/generic-associated-types/gat-in-trait-path.rs new file mode 100644 index 00000000000..2dbd1840dec --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.rs @@ -0,0 +1,30 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a> where Self: 'a; +} + +struct Fooy; + +impl Foo for Fooy { + type A<'a> = &'a (); +} + +#[derive(Clone)] +struct Fooer(T); + +impl Foo for Fooer { + type A<'x> where T: 'x = &'x (); +} + +fn f(_arg : Box Foo = &'a ()>>) {} + + +fn main() { + let foo = Fooer(5); + f(Box::new(foo)); +} diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr new file mode 100644 index 00000000000..f3769827f04 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-in-trait-path.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs new file mode 100644 index 00000000000..cff5a21052f --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs @@ -0,0 +1,16 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Foo { + type F<'a>; + + fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t } +} + +impl Foo for T { + type F = &[u8]; + //~^ ERROR: the name `T1` is already used for + //~| ERROR: missing lifetime specifier +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr new file mode 100644 index 00000000000..e83af1d0c73 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr @@ -0,0 +1,32 @@ +error[E0403]: the name `T1` is already used for a generic parameter in this item's generic parameters + --> $DIR/gat-trait-path-generic-type-arg.rs:11:12 + | +LL | impl Foo for T { + | -- first use of `T1` +LL | type F = &[u8]; + | ^^ already used + +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-trait-path-generic-type-arg.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0106]: missing lifetime specifier + --> $DIR/gat-trait-path-generic-type-arg.rs:11:18 + | +LL | type F = &[u8]; + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type F<'a, T1> = &'a [u8]; + | ^^^ ^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0106, E0403. +For more information about an error, try `rustc --explain E0106`. diff --git a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs new file mode 100644 index 00000000000..e69e355ba48 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs @@ -0,0 +1,18 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; + //~^ ERROR missing generics for + //~| ERROR missing generics for + + fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t } +} + +impl X for T { + fn foo<'a, T1: X>(t : T1) -> T1::Y<'a> { + t + } +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr new file mode 100644 index 00000000000..9c6e2ce3e17 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -0,0 +1,44 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-trait-path-missing-lifetime.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0107]: missing generics for associated type `X::Y` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type Y<'a><'a>; + | ^^^^ + +error[E0107]: missing generics for associated type `X::Y` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/gat-trait-path-missing-lifetime.rs:5:8 + | +LL | type Y<'a>; + | ^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type Y<'a><'a>; + | ^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs new file mode 100644 index 00000000000..bb1f27a17ca --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -0,0 +1,15 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; + //~^ ERROR this associated type + //~| ERROR this associated type +} + +fn foo<'a>(arg: Box>) {} + //~^ ERROR: lifetime in trait object type must be followed by `+` + //~| ERROR: parenthesized generic arguments cannot be used + //~| WARNING: trait objects without an explicit `dyn` are deprecated + +fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr new file mode 100644 index 00000000000..20cb6d88287 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -0,0 +1,68 @@ +error: lifetime in trait object type must be followed by `+` + --> $DIR/gat-trait-path-parenthesised-args.rs:10:29 + | +LL | fn foo<'a>(arg: Box>) {} + | ^^ + +error: parenthesized generic arguments cannot be used in associated type constraints + --> $DIR/gat-trait-path-parenthesised-args.rs:10:27 + | +LL | fn foo<'a>(arg: Box>) {} + | ^^^^^ + +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gat-trait-path-parenthesised-args.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/gat-trait-path-parenthesised-args.rs:10:29 + | +LL | fn foo<'a>(arg: Box>) {} + | ^^ help: use `dyn`: `dyn 'a` + | + = note: `#[warn(bare_trait_objects)]` on by default + +error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | fn foo<'a>(arg: Box>) {} + | ^^ + +error[E0107]: this associated type takes 0 type arguments but 1 type argument was supplied + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ________^- + | | | + | | expected 0 type arguments +LL | | +LL | | +LL | | } +LL | | +LL | | fn foo<'a>(arg: Box>) {} + | |_________________________________________- help: remove these generics + | +note: associated type defined here, with 0 type parameters + --> $DIR/gat-trait-path-parenthesised-args.rs:5:8 + | +LL | type Y<'a>; + | ^ + +error: aborting due to 4 previous errors; 2 warnings emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.rs b/src/test/ui/generic-associated-types/issue-67510-pass.rs new file mode 100644 index 00000000000..ff38b3e93eb --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510-pass.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; +} + +fn _func1<'a>(_x: Box=&'a ()>>) {} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.stderr new file mode 100644 index 00000000000..0fbf704df76 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510-pass.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-67510-pass.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/issue-67510.rs b/src/test/ui/generic-associated-types/issue-67510.rs new file mode 100644 index 00000000000..62b22089f91 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510.rs @@ -0,0 +1,13 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait X { + type Y<'a>; +} + +fn f(x: Box=&'a ()>>) {} + //~^ ERROR: use of undeclared lifetime name `'a` + //~| ERROR: use of undeclared lifetime name `'a` + + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-67510.stderr b/src/test/ui/generic-associated-types/issue-67510.stderr new file mode 100644 index 00000000000..12755c56974 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-67510.stderr @@ -0,0 +1,32 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-67510.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/issue-67510.rs:8:21 + | +LL | fn f(x: Box=&'a ()>>) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/issue-67510.rs:8:26 + | +LL | fn f(x: Box=&'a ()>>) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + | + = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/generic-associated-types/issue-68648-1.rs b/src/test/ui/generic-associated-types/issue-68648-1.rs new file mode 100644 index 00000000000..f294b22f73c --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-1.rs @@ -0,0 +1,26 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + + +trait Fun { + type F<'a>; + + fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = Self; +} + +fn bug<'a, T: for<'b> Fun = T>>(t: T) -> T::F<'a> { + T::identity(t) +} + + +fn main() { + let x = 10; + + bug(x); +} diff --git a/src/test/ui/generic-associated-types/issue-68648-1.stderr b/src/test/ui/generic-associated-types/issue-68648-1.stderr new file mode 100644 index 00000000000..322a8f9e13f --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-1.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-68648-1.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/issue-68648-2.rs b/src/test/ui/generic-associated-types/issue-68648-2.rs new file mode 100644 index 00000000000..e55bfcd4ba2 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-2.rs @@ -0,0 +1,24 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>; + + fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = Self; +} + +fn bug<'a, T: Fun = T>>(t: T) -> T::F<'a> { + T::identity(()) + //~^ ERROR: mismatched types +} + + +fn main() { + let x = 10; + + bug(x); +} diff --git a/src/test/ui/generic-associated-types/issue-68648-2.stderr b/src/test/ui/generic-associated-types/issue-68648-2.stderr new file mode 100644 index 00000000000..b51e0bca9f7 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68648-2.stderr @@ -0,0 +1,23 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-68648-2.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0308]: mismatched types + --> $DIR/issue-68648-2.rs:15:17 + | +LL | fn bug<'a, T: Fun = T>>(t: T) -> T::F<'a> { + | - this type parameter +LL | T::identity(()) + | ^^ expected type parameter `T`, found `()` + | + = note: expected type parameter `T` + found unit type `()` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generic-associated-types/issue-68649-pass.rs b/src/test/ui/generic-associated-types/issue-68649-pass.rs new file mode 100644 index 00000000000..396315302f7 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68649-pass.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>; + + fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = Self; +} + +fn bug<'a, T: Fun = T>>(t: T) -> T::F<'a> { + T::identity(t) +} + + +fn main() { + let x = 10; + + bug(x); +} diff --git a/src/test/ui/generic-associated-types/issue-68649-pass.stderr b/src/test/ui/generic-associated-types/issue-68649-pass.stderr new file mode 100644 index 00000000000..e4a2f8d2a64 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-68649-pass.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-68649-pass.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/generic-associated-types/issue-74684-1.rs b/src/test/ui/generic-associated-types/issue-74684-1.rs new file mode 100644 index 00000000000..a483da863ff --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-1.rs @@ -0,0 +1,26 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>: ?Sized; + + fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = [u8]; +} + +fn bug<'a, T: ?Sized + Fun = [u8]>>(_ : Box) -> &'static T::F<'a> { + let a = [0; 1]; + let _x = T::identity(&a); + //~^ ERROR: `a` does not live long enough + todo!() +} + + +fn main() { + let x = 10; + + bug(Box::new(x)); +} diff --git a/src/test/ui/generic-associated-types/issue-74684-1.stderr b/src/test/ui/generic-associated-types/issue-74684-1.stderr new file mode 100644 index 00000000000..651da696827 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-1.stderr @@ -0,0 +1,27 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-74684-1.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0597]: `a` does not live long enough + --> $DIR/issue-74684-1.rs:16:26 + | +LL | fn bug<'a, T: ?Sized + Fun = [u8]>>(_ : Box) -> &'static T::F<'a> { + | -- lifetime `'a` defined here +LL | let a = [0; 1]; +LL | let _x = T::identity(&a); + | ------------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'a` +... +LL | } + | - `a` dropped here while still borrowed + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/generic-associated-types/issue-74684-2.rs b/src/test/ui/generic-associated-types/issue-74684-2.rs new file mode 100644 index 00000000000..0caf19cb030 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-2.rs @@ -0,0 +1,26 @@ +#![feature(generic_associated_types)] + //~^ WARNING: the feature `generic_associated_types` is incomplete + +trait Fun { + type F<'a>: ?Sized; + + fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t } +} + +impl Fun for T { + type F<'a> = i32; +} + +fn bug<'a, T: ?Sized + Fun = [u8]>>(t: Box) -> &'static T::F<'a> { + let a = [0; 1]; + let x = T::identity(&a); + todo!() +} + + +fn main() { + let x = 10; + + bug(Box::new(x)); + //~^ ERROR: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]` +} diff --git a/src/test/ui/generic-associated-types/issue-74684-2.stderr b/src/test/ui/generic-associated-types/issue-74684-2.stderr new file mode 100644 index 00000000000..8c3484f9a73 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-74684-2.stderr @@ -0,0 +1,21 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-74684-2.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]` + --> $DIR/issue-74684-2.rs:24:5 + | +LL | fn bug<'a, T: ?Sized + Fun = [u8]>>(t: Box) -> &'static T::F<'a> { + | ------------ required by this bound in `bug` +... +LL | bug(Box::new(x)); + | ^^^ expected slice `[u8]`, found `i32` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/generic-associated-types/issue-76535.rs b/src/test/ui/generic-associated-types/issue-76535.rs new file mode 100644 index 00000000000..2b4757d8d15 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-76535.rs @@ -0,0 +1,41 @@ +#![feature(generic_associated_types)] + //~^ WARNING the feature + +pub trait SubTrait {} + +pub trait SuperTrait { + type SubType<'a>: SubTrait; + //~^ ERROR missing generics for associated + + fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; +} + +pub struct SubStruct<'a> { + sup: &'a mut SuperStruct, +} + +impl<'a> SubTrait for SubStruct<'a> {} + +pub struct SuperStruct { + value: u8, +} + +impl SuperStruct { + pub fn new(value: u8) -> SuperStruct { + SuperStruct { value } + } +} + +impl SuperTrait for SuperStruct { + type SubType<'a> = SubStruct<'a>; + + fn get_sub<'a>(&'a mut self) -> Self::SubType<'a> { + SubStruct { sup: self } + } +} + +fn main() { + let sub: Box> = Box::new(SuperStruct::new(0)); + //~^ ERROR the trait + //~| ERROR the trait +} diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/src/test/ui/generic-associated-types/issue-76535.stderr new file mode 100644 index 00000000000..ce4875af9c0 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-76535.stderr @@ -0,0 +1,63 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-76535.rs:1:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information + +error[E0107]: missing generics for associated type `SuperTrait::SubType` + --> $DIR/issue-76535.rs:7:10 + | +LL | type SubType<'a>: SubTrait; + | ^^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-76535.rs:7:10 + | +LL | type SubType<'a>: SubTrait; + | ^^^^^^^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type SubType<'a><'a>: SubTrait; + | ^^^^ + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/issue-76535.rs:38:14 + | +LL | let sub: Box> = Box::new(SuperStruct::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object + | + = help: consider moving `get_sub` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-76535.rs:10:37 + | +LL | pub trait SuperTrait { + | ---------- this trait cannot be made into an object... +... +LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; + | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/issue-76535.rs:38:57 + | +LL | let sub: Box> = Box::new(SuperStruct::new(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object + | + = help: consider moving `get_sub` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-76535.rs:10:37 + | +LL | pub trait SuperTrait { + | ---------- this trait cannot be made into an object... +... +LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; + | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type + = note: required because of the requirements on the impl of `CoerceUnsized>>>` for `Box` + = note: required by cast to type `Box>>` + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/generic-associated-types/issue-79422.rs b/src/test/ui/generic-associated-types/issue-79422.rs new file mode 100644 index 00000000000..26b38430dd9 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-79422.rs @@ -0,0 +1,47 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait RefCont<'a, T> { + fn t(&'a self) -> &'a T; +} + +impl<'a, T> RefCont<'a, T> for &'a T { + fn t(&'a self) -> &'a T { + self + } +} + +impl<'a, T> RefCont<'a, T> for Box { + fn t(&'a self) -> &'a T { + self.as_ref() + } +} + +trait MapLike { + type VRefCont<'a>: RefCont<'a, V>; + //~^ ERROR missing generics + fn get<'a>(&'a self, key: &K) -> Option>; +} + +impl MapLike for std::collections::BTreeMap { + type VRefCont<'a> = &'a V; + fn get<'a>(&'a self, key: &K) -> Option<&'a V> { + std::collections::BTreeMap::get(self, key) + } +} + +struct Source; + +impl MapLike for Source { + type VRefCont<'a> = Box; + fn get<'a>(&self, _: &K) -> Option> { + Some(Box::new(V::default())) + } +} + +fn main() { + let m = Box::new(std::collections::BTreeMap::::new()) + as Box>>; + //~^ ERROR the trait + //~^^^ ERROR the trait +} diff --git a/src/test/ui/generic-associated-types/issue-79422.stderr b/src/test/ui/generic-associated-types/issue-79422.stderr new file mode 100644 index 00000000000..d2e12962715 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-79422.stderr @@ -0,0 +1,54 @@ +error[E0107]: missing generics for associated type `MapLike::VRefCont` + --> $DIR/issue-79422.rs:21:10 + | +LL | type VRefCont<'a>: RefCont<'a, V>; + | ^^^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-79422.rs:21:10 + | +LL | type VRefCont<'a>: RefCont<'a, V>; + | ^^^^^^^^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type VRefCont<'a><'a>: RefCont<'a, V>; + | ^^^^ + +error[E0038]: the trait `MapLike` cannot be made into an object + --> $DIR/issue-79422.rs:44:12 + | +LL | as Box>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object + | + = help: consider moving `get` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-79422.rs:23:38 + | +LL | trait MapLike { + | ------- this trait cannot be made into an object... +... +LL | fn get<'a>(&'a self, key: &K) -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type + +error[E0038]: the trait `MapLike` cannot be made into an object + --> $DIR/issue-79422.rs:43:13 + | +LL | let m = Box::new(std::collections::BTreeMap::::new()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object + | + = help: consider moving `get` to another trait +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-79422.rs:23:38 + | +LL | trait MapLike { + | ------- this trait cannot be made into an object... +... +LL | fn get<'a>(&'a self, key: &K) -> Option>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type + = note: required because of the requirements on the impl of `CoerceUnsized + 'static)>>>` for `Box>` + = note: required by cast to type `Box + 'static)>>` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/generic-associated-types/issue-80433-reduced.rs b/src/test/ui/generic-associated-types/issue-80433-reduced.rs new file mode 100644 index 00000000000..7c1673edc51 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-80433-reduced.rs @@ -0,0 +1,24 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +struct E {} + +trait TestMut { + type Output<'a>; + fn test_mut(&mut self) -> Self::Output<'static>; +} + +impl TestMut for E { + type Output<'a> = usize; + fn test_mut(&mut self) -> Self::Output<'static> { + todo!() + } +} + +fn test_simpler<'a>(_: impl TestMut = usize>) {} + +fn main() { + test_simpler(E {}); +} diff --git a/src/test/ui/generic-associated-types/issue-80433.rs b/src/test/ui/generic-associated-types/issue-80433.rs new file mode 100644 index 00000000000..ea65f05de23 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-80433.rs @@ -0,0 +1,35 @@ +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +#[derive(Default)] +struct E { + data: T, +} + +trait TestMut { + type Output<'a>; + //~^ ERROR missing generics + fn test_mut<'a>(&'a mut self) -> Self::Output<'a>; +} + +impl TestMut for E +where + T: 'static, +{ + type Output<'a> = &'a mut T; + fn test_mut<'a>(&'a mut self) -> Self::Output<'a> { + &mut self.data + } +} + +fn test_simpler<'a>(dst: &'a mut impl TestMut) +{ + for n in 0i16..100 { + *dst.test_mut() = n.into(); + } +} + +fn main() { + let mut t1: E = Default::default(); + test_simpler(&mut t1); +} diff --git a/src/test/ui/generic-associated-types/issue-80433.stderr b/src/test/ui/generic-associated-types/issue-80433.stderr new file mode 100644 index 00000000000..5398920fafd --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-80433.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for associated type `TestMut::Output` + --> $DIR/issue-80433.rs:10:10 + | +LL | type Output<'a>; + | ^^^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-80433.rs:10:10 + | +LL | type Output<'a>; + | ^^^^^^ -- +help: use angle brackets to add missing lifetime argument + | +LL | type Output<'a><'a>; + | ^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs index e203a5e0d2d..2d38770bcdf 100644 --- a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs +++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs @@ -1,10 +1,14 @@ #![feature(generic_associated_types)] + //~^ the feature `generic_associated_types` is incomplete trait X { type Y<'a>; + //~^ ERROR this associated type + //~| ERROR this associated type } const _: () = { fn f2<'a>(arg : Box = &'a ()>>) {} - //~^ ERROR: generic associated types in trait paths are currently not implemented }; + +fn main() {} diff --git a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr index e59a72a99ee..60b8fb9bcaa 100644 --- a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr +++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr @@ -1,8 +1,49 @@ -error: generic associated types in trait paths are currently not implemented - --> $DIR/trait-path-type-error-once-implemented.rs:8:30 +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/trait-path-type-error-once-implemented.rs:1:12 | -LL | fn f2<'a>(arg : Box = &'a ()>>) {} - | ^^^ +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 for more information -error: aborting due to previous error +error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | fn f2<'a>(arg : Box = &'a ()>>) {} + | ^^ +error[E0107]: this associated type takes 0 const arguments but 1 const argument was supplied + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | __________^- + | | | + | | expected 0 const arguments +LL | | +LL | | +LL | | } +LL | | +LL | | const _: () = { +LL | | fn f2<'a>(arg : Box = &'a ()>>) {} + | |________________________________- help: remove these generics + | +note: associated type defined here, with 0 const parameters + --> $DIR/trait-path-type-error-once-implemented.rs:5:10 + | +LL | type Y<'a>; + | ^ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.rs b/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.rs deleted file mode 100644 index 02d53d5faee..00000000000 --- a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(generic_associated_types)] - -trait X { - type Y<'a>; -} - -const _: () = { - fn f1<'a>(arg : Box = &'a ()>>) {} - //~^ ERROR: generic associated types in trait paths are currently not implemented -}; - -const _: () = { - fn f1<'a>(arg : Box>) {} - //~^ ERROR: lifetime in trait object type must be followed by `+` -}; - -fn main() {} diff --git a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.stderr b/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.stderr deleted file mode 100644 index 1fba9cebd24..00000000000 --- a/src/test/ui/generic-associated-types/parse/trait-path-unimplemented.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: lifetime in trait object type must be followed by `+` - --> $DIR/trait-path-unimplemented.rs:13:31 - | -LL | fn f1<'a>(arg : Box>) {} - | ^^ - -error: generic associated types in trait paths are currently not implemented - --> $DIR/trait-path-unimplemented.rs:8:30 - | -LL | fn f1<'a>(arg : Box = &'a ()>>) {} - | ^^^^ - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/parser/ascii-only-character-escape.rs b/src/test/ui/parser/ascii-only-character-escape.rs index 20d3edf1251..725c8ad2351 100644 --- a/src/test/ui/parser/ascii-only-character-escape.rs +++ b/src/test/ui/parser/ascii-only-character-escape.rs @@ -1,6 +1,6 @@ fn main() { - let x = "\x80"; //~ ERROR may only be used - let y = "\xff"; //~ ERROR may only be used - let z = "\xe2"; //~ ERROR may only be used + let x = "\x80"; //~ ERROR out of range hex escape + let y = "\xff"; //~ ERROR out of range hex escape + let z = "\xe2"; //~ ERROR out of range hex escape let a = b"\x00e2"; // ok because byte literal } diff --git a/src/test/ui/parser/ascii-only-character-escape.stderr b/src/test/ui/parser/ascii-only-character-escape.stderr index cf51b00cdc3..b599b35f4b3 100644 --- a/src/test/ui/parser/ascii-only-character-escape.stderr +++ b/src/test/ui/parser/ascii-only-character-escape.stderr @@ -1,20 +1,20 @@ -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:2:14 | LL | let x = "\x80"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:3:14 | LL | let y = "\xff"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:4:14 | LL | let z = "\xe2"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/bad-char-literals.rs b/src/test/ui/parser/bad-char-literals.rs index 11696b82bc9..748b4a22253 100644 --- a/src/test/ui/parser/bad-char-literals.rs +++ b/src/test/ui/parser/bad-char-literals.rs @@ -4,17 +4,17 @@ fn main() { // these literals are just silly. '''; - //~^ ERROR: character constant must be escaped: ' + //~^ ERROR: character constant must be escaped: `'` // note that this is a literal "\n" byte ' '; - //~^^ ERROR: character constant must be escaped: \n + //~^^ ERROR: character constant must be escaped: `\n` // note that this is a literal "\r" byte - ' '; //~ ERROR: character constant must be escaped: \r + ' '; //~ ERROR: character constant must be escaped: `\r` // note that this is a literal tab character here ' '; - //~^ ERROR: character constant must be escaped: \t + //~^ ERROR: character constant must be escaped: `\t` } diff --git a/src/test/ui/parser/bad-char-literals.stderr b/src/test/ui/parser/bad-char-literals.stderr index 093978fd84d..a22ddbac1b9 100644 --- a/src/test/ui/parser/bad-char-literals.stderr +++ b/src/test/ui/parser/bad-char-literals.stderr @@ -1,28 +1,28 @@ -error: character constant must be escaped: ' +error: character constant must be escaped: `'` --> $DIR/bad-char-literals.rs:6:6 | LL | '''; - | ^ + | ^ help: escape the character: `\'` -error: character constant must be escaped: \n +error: character constant must be escaped: `\n` --> $DIR/bad-char-literals.rs:10:6 | LL | ' | ______^ LL | | '; - | |_ + | |_ help: escape the character: `\n` -error: character constant must be escaped: \r +error: character constant must be escaped: `\r` --> $DIR/bad-char-literals.rs:15:6 | LL | ' '; - | ^ + | ^ help: escape the character: `\r` -error: character constant must be escaped: \t +error: character constant must be escaped: `\t` --> $DIR/bad-char-literals.rs:18:6 | LL | ' '; - | ^^^^ + | ^^^^ help: escape the character: `\t` error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/byte-literals.rs b/src/test/ui/parser/byte-literals.rs index 9683a83e720..05a510b24a7 100644 --- a/src/test/ui/parser/byte-literals.rs +++ b/src/test/ui/parser/byte-literals.rs @@ -4,9 +4,9 @@ static FOO: u8 = b'\f'; //~ ERROR unknown byte escape pub fn main() { b'\f'; //~ ERROR unknown byte escape - b'\x0Z'; //~ ERROR invalid character in numeric character escape: Z + b'\x0Z'; //~ ERROR invalid character in numeric character escape: `Z` b' '; //~ ERROR byte constant must be escaped b'''; //~ ERROR byte constant must be escaped - b'é'; //~ ERROR byte constant must be ASCII + b'é'; //~ ERROR non-ASCII character in byte constant b'a //~ ERROR unterminated byte constant [E0763] } diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr index 7bbdc07cd83..55be113e16b 100644 --- a/src/test/ui/parser/byte-literals.stderr +++ b/src/test/ui/parser/byte-literals.stderr @@ -1,38 +1,45 @@ -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-literals.rs:3:21 | LL | static FOO: u8 = b'\f'; | ^ unknown byte escape + | + = help: for more information, visit -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-literals.rs:6:8 | LL | b'\f'; | ^ unknown byte escape + | + = help: for more information, visit -error: invalid character in numeric character escape: Z +error: invalid character in numeric character escape: `Z` --> $DIR/byte-literals.rs:7:10 | LL | b'\x0Z'; - | ^ + | ^ invalid character in numeric character escape -error: byte constant must be escaped: \t +error: byte constant must be escaped: `\t` --> $DIR/byte-literals.rs:8:7 | LL | b' '; - | ^^^^ + | ^^^^ help: escape the character: `\t` -error: byte constant must be escaped: ' +error: byte constant must be escaped: `'` --> $DIR/byte-literals.rs:9:7 | LL | b'''; - | ^ + | ^ help: escape the character: `\'` -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/byte-literals.rs:10:7 | LL | b'é'; | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xE9` error[E0763]: unterminated byte constant --> $DIR/byte-literals.rs:11:6 diff --git a/src/test/ui/parser/byte-string-literals.rs b/src/test/ui/parser/byte-string-literals.rs index caffd9efbed..b1f11024a7b 100644 --- a/src/test/ui/parser/byte-string-literals.rs +++ b/src/test/ui/parser/byte-string-literals.rs @@ -2,7 +2,8 @@ static FOO: &'static [u8] = b"\f"; //~ ERROR unknown byte escape pub fn main() { b"\f"; //~ ERROR unknown byte escape - b"\x0Z"; //~ ERROR invalid character in numeric character escape: Z - b"é"; //~ ERROR byte constant must be ASCII + b"\x0Z"; //~ ERROR invalid character in numeric character escape: `Z` + b"é"; //~ ERROR non-ASCII character in byte constant + br##"é"##; //~ ERROR raw byte string must be ASCII b"a //~ ERROR unterminated double quote byte string } diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr index 9be90644147..3a5a8b331d3 100644 --- a/src/test/ui/parser/byte-string-literals.stderr +++ b/src/test/ui/parser/byte-string-literals.stderr @@ -1,35 +1,48 @@ -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:1:32 | LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape + | + = help: for more information, visit -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:4:8 | LL | b"\f"; | ^ unknown byte escape + | + = help: for more information, visit -error: invalid character in numeric character escape: Z +error: invalid character in numeric character escape: `Z` --> $DIR/byte-string-literals.rs:5:10 | LL | b"\x0Z"; - | ^ + | ^ invalid character in numeric character escape -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/byte-string-literals.rs:6:7 | LL | b"é"; | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xE9` + +error: raw byte string must be ASCII + --> $DIR/byte-string-literals.rs:7:10 + | +LL | br##"é"##; + | ^ must be ASCII error[E0766]: unterminated double quote byte string - --> $DIR/byte-string-literals.rs:7:6 + --> $DIR/byte-string-literals.rs:8:6 | LL | b"a | ______^ LL | | } | |__^ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0766`. diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.rs b/src/test/ui/parser/issue-23620-invalid-escapes.rs index ab445a93294..c1355f0d6fe 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.rs +++ b/src/test/ui/parser/issue-23620-invalid-escapes.rs @@ -1,9 +1,9 @@ fn main() { let _ = b"\u{a66e}"; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string + //~^ ERROR unicode escape in byte string let _ = b'\u{a66e}'; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string + //~^ ERROR unicode escape in byte string let _ = b'\u'; //~^ ERROR incorrect unicode escape sequence @@ -12,21 +12,21 @@ fn main() { //~^ ERROR numeric character escape is too short let _ = b'\xxy'; - //~^ ERROR invalid character in numeric character escape: x + //~^ ERROR invalid character in numeric character escape: `x` let _ = '\x5'; //~^ ERROR numeric character escape is too short let _ = '\xxy'; - //~^ ERROR invalid character in numeric character escape: x + //~^ ERROR invalid character in numeric character escape: `x` let _ = b"\u{a4a4} \xf \u"; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string - //~^^ ERROR invalid character in numeric character escape: + //~^ ERROR unicode escape in byte string + //~^^ ERROR invalid character in numeric character escape: ` ` //~^^^ ERROR incorrect unicode escape sequence let _ = "\xf \u"; - //~^ ERROR invalid character in numeric character escape: + //~^ ERROR invalid character in numeric character escape: ` ` //~^^ ERROR incorrect unicode escape sequence let _ = "\u8f"; diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issue-23620-invalid-escapes.stderr index 8c924ad0330..88d97c795fc 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.stderr +++ b/src/test/ui/parser/issue-23620-invalid-escapes.stderr @@ -1,14 +1,18 @@ -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:2:15 | LL | let _ = b"\u{a66e}"; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:5:15 | LL | let _ = b'\u{a66e}'; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:8:15 @@ -24,11 +28,11 @@ error: numeric character escape is too short LL | let _ = b'\x5'; | ^^^ -error: invalid character in numeric character escape: x +error: invalid character in numeric character escape: `x` --> $DIR/issue-23620-invalid-escapes.rs:14:17 | LL | let _ = b'\xxy'; - | ^ + | ^ invalid character in numeric character escape error: numeric character escape is too short --> $DIR/issue-23620-invalid-escapes.rs:17:14 @@ -36,23 +40,25 @@ error: numeric character escape is too short LL | let _ = '\x5'; | ^^^ -error: invalid character in numeric character escape: x +error: invalid character in numeric character escape: `x` --> $DIR/issue-23620-invalid-escapes.rs:20:16 | LL | let _ = '\xxy'; - | ^ + | ^ invalid character in numeric character escape -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:23:15 | LL | let _ = b"\u{a4a4} \xf \u"; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string -error: invalid character in numeric character escape: +error: invalid character in numeric character escape: ` ` --> $DIR/issue-23620-invalid-escapes.rs:23:27 | LL | let _ = b"\u{a4a4} \xf \u"; - | ^ + | ^ invalid character in numeric character escape error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:23:28 @@ -62,11 +68,11 @@ LL | let _ = b"\u{a4a4} \xf \u"; | = help: format of unicode escape sequences is `\u{...}` -error: invalid character in numeric character escape: +error: invalid character in numeric character escape: ` ` --> $DIR/issue-23620-invalid-escapes.rs:28:17 | LL | let _ = "\xf \u"; - | ^ + | ^ invalid character in numeric character escape error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:28:18 diff --git a/src/test/ui/parser/issue-43692.stderr b/src/test/ui/parser/issue-43692.stderr index 69a54af3d82..baf99803517 100644 --- a/src/test/ui/parser/issue-43692.stderr +++ b/src/test/ui/parser/issue-43692.stderr @@ -1,8 +1,8 @@ -error: invalid start of unicode escape +error: invalid start of unicode escape: `_` --> $DIR/issue-43692.rs:2:9 | LL | '\u{_10FFFF}'; - | ^ + | ^ invalid start of unicode escape error: aborting due to previous error diff --git a/src/test/ui/parser/issue-62913.stderr b/src/test/ui/parser/issue-62913.stderr index f72174f8929..6f385e8dc17 100644 --- a/src/test/ui/parser/issue-62913.stderr +++ b/src/test/ui/parser/issue-62913.stderr @@ -10,7 +10,7 @@ error: invalid trailing slash in literal --> $DIR/issue-62913.rs:1:5 | LL | "\u\" - | ^ + | ^ invalid trailing slash in literal error: expected item, found `"\u\"` --> $DIR/issue-62913.rs:1:1 diff --git a/src/test/ui/parser/issue-64732.stderr b/src/test/ui/parser/issue-64732.stderr index 3b00ffc8f6c..ac042580962 100644 --- a/src/test/ui/parser/issue-64732.stderr +++ b/src/test/ui/parser/issue-64732.stderr @@ -1,13 +1,13 @@ error: character literal may only contain one codepoint - --> $DIR/issue-64732.rs:3:17 + --> $DIR/issue-64732.rs:3:16 | LL | let _foo = b'hello\0'; - | ^^^^^^^^^ + | ^^^^^^^^^^ | help: if you meant to write a byte string literal, use double quotes | LL | let _foo = b"hello\0"; - | ^^^^^^^^^ + | ^^^^^^^^^^ error: character literal may only contain one codepoint --> $DIR/issue-64732.rs:6:16 diff --git a/src/test/ui/parser/lex-bad-char-literals-1.stderr b/src/test/ui/parser/lex-bad-char-literals-1.stderr index fcf4802f79b..ed129a1d133 100644 --- a/src/test/ui/parser/lex-bad-char-literals-1.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-1.stderr @@ -10,17 +10,21 @@ error: numeric character escape is too short LL | "\x1" | ^^^ -error: unknown character escape: \u{25cf} +error: unknown character escape: `\u{25cf}` --> $DIR/lex-bad-char-literals-1.rs:10:7 | LL | '\●' | ^ unknown character escape + | + = help: for more information, visit -error: unknown character escape: \u{25cf} +error: unknown character escape: `\u{25cf}` --> $DIR/lex-bad-char-literals-1.rs:14:7 | LL | "\●" | ^ unknown character escape + | + = help: for more information, visit error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/lex-bad-char-literals-7.rs b/src/test/ui/parser/lex-bad-char-literals-7.rs index 1580157210e..c675df2f3cc 100644 --- a/src/test/ui/parser/lex-bad-char-literals-7.rs +++ b/src/test/ui/parser/lex-bad-char-literals-7.rs @@ -2,7 +2,7 @@ fn main() { let _: char = ''; //~^ ERROR: empty character literal let _: char = '\u{}'; - //~^ ERROR: empty unicode escape (must have at least 1 hex digit) + //~^ ERROR: empty unicode escape // Next two are OK, but may befool error recovery let _ = '/'; diff --git a/src/test/ui/parser/lex-bad-char-literals-7.stderr b/src/test/ui/parser/lex-bad-char-literals-7.stderr index 70ee8087b51..255b9c68999 100644 --- a/src/test/ui/parser/lex-bad-char-literals-7.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-7.stderr @@ -2,13 +2,13 @@ error: empty character literal --> $DIR/lex-bad-char-literals-7.rs:2:20 | LL | let _: char = ''; - | ^ + | ^ empty character literal -error: empty unicode escape (must have at least 1 hex digit) +error: empty unicode escape --> $DIR/lex-bad-char-literals-7.rs:4:20 | LL | let _: char = '\u{}'; - | ^^^^ + | ^^^^ this escape must have at least 1 hex digit error[E0762]: unterminated character literal --> $DIR/lex-bad-char-literals-7.rs:11:13 diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs index 9a9f9c433e1..b7752e1f0c4 100644 --- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs +++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs @@ -22,5 +22,5 @@ fn main() { let _s = r"bar foo"; //~ ERROR: bare CR not allowed in raw string // the following string literal has a bare CR in it - let _s = "foo\ bar"; //~ ERROR: unknown character escape: \r + let _s = "foo\ bar"; //~ ERROR: unknown character escape: `\r` } diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr index 598da6b9307..1a21fed63bd 100644 --- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr +++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr @@ -22,11 +22,11 @@ error: bare CR not allowed in block doc-comment LL | /*! block doc comment with bare CR: ' ' */ | ^ -error: bare CR not allowed in string, use \r instead +error: bare CR not allowed in string, use `\r` instead --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:19:18 | LL | let _s = "foo bar"; - | ^ + | ^ help: escape the character: `\r` error: bare CR not allowed in raw string --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:22:19 @@ -34,7 +34,7 @@ error: bare CR not allowed in raw string LL | let _s = r"bar foo"; | ^ -error: unknown character escape: \r +error: unknown character escape: `\r` --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:25:19 | LL | let _s = "foo\ bar"; diff --git a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr index d20eb0fb30a..e874f62497e 100644 --- a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr +++ b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr @@ -2,7 +2,7 @@ error: invalid unicode character escape --> $DIR/literals-are-validated-before-expansion.rs:6:20 | LL | black_hole! { '\u{FFFFFF}' } - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid escape | = help: unicode escape must be at most 10FFFF @@ -10,7 +10,7 @@ error: invalid unicode character escape --> $DIR/literals-are-validated-before-expansion.rs:8:39 | LL | black_hole! { "this is surrogate: \u{DAAA}" } - | ^^^^^^^^ + | ^^^^^^^^ invalid escape | = help: unicode escape must not be a surrogate diff --git a/src/test/ui/parser/new-unicode-escapes-1.rs b/src/test/ui/parser/new-unicode-escapes-1.rs index 0e1421214d9..d6a54660ea6 100644 --- a/src/test/ui/parser/new-unicode-escapes-1.rs +++ b/src/test/ui/parser/new-unicode-escapes-1.rs @@ -1,3 +1,3 @@ pub fn main() { - let s = "\u{2603"; //~ ERROR unterminated unicode escape (needed a `}`) + let s = "\u{2603"; //~ ERROR unterminated unicode escape } diff --git a/src/test/ui/parser/new-unicode-escapes-1.stderr b/src/test/ui/parser/new-unicode-escapes-1.stderr index 22d6a0981ff..1ffdc0401e5 100644 --- a/src/test/ui/parser/new-unicode-escapes-1.stderr +++ b/src/test/ui/parser/new-unicode-escapes-1.stderr @@ -1,8 +1,13 @@ -error: unterminated unicode escape (needed a `}`) +error: unterminated unicode escape --> $DIR/new-unicode-escapes-1.rs:2:14 | LL | let s = "\u{2603"; - | ^^^^^^^ + | ^^^^^^^ missing a closing `}` + | +help: terminate the unicode escape + | +LL | let s = "\u{2603}"; + | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-2.rs b/src/test/ui/parser/new-unicode-escapes-2.rs index b30b3dbf903..cbb614c19c0 100644 --- a/src/test/ui/parser/new-unicode-escapes-2.rs +++ b/src/test/ui/parser/new-unicode-escapes-2.rs @@ -1,3 +1,3 @@ pub fn main() { - let s = "\u{260311111111}"; //~ ERROR overlong unicode escape (must have at most 6 hex digits) + let s = "\u{260311111111}"; //~ ERROR overlong unicode escape } diff --git a/src/test/ui/parser/new-unicode-escapes-2.stderr b/src/test/ui/parser/new-unicode-escapes-2.stderr index b5148279c74..2f3f8c0f9da 100644 --- a/src/test/ui/parser/new-unicode-escapes-2.stderr +++ b/src/test/ui/parser/new-unicode-escapes-2.stderr @@ -1,8 +1,8 @@ -error: overlong unicode escape (must have at most 6 hex digits) +error: overlong unicode escape --> $DIR/new-unicode-escapes-2.rs:2:14 | LL | let s = "\u{260311111111}"; - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ must have at most 6 hex digits error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-3.stderr b/src/test/ui/parser/new-unicode-escapes-3.stderr index 361698467f9..f5a0f8fc785 100644 --- a/src/test/ui/parser/new-unicode-escapes-3.stderr +++ b/src/test/ui/parser/new-unicode-escapes-3.stderr @@ -2,7 +2,7 @@ error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:2:15 | LL | let s1 = "\u{d805}"; - | ^^^^^^^^ + | ^^^^^^^^ invalid escape | = help: unicode escape must not be a surrogate @@ -10,7 +10,7 @@ error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:3:15 | LL | let s2 = "\u{ffffff}"; - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid escape | = help: unicode escape must be at most 10FFFF diff --git a/src/test/ui/parser/new-unicode-escapes-4.rs b/src/test/ui/parser/new-unicode-escapes-4.rs index 9ac03cedc3f..79882713e59 100644 --- a/src/test/ui/parser/new-unicode-escapes-4.rs +++ b/src/test/ui/parser/new-unicode-escapes-4.rs @@ -1,4 +1,4 @@ pub fn main() { let s = "\u{lol}"; - //~^ ERROR invalid character in unicode escape: l + //~^ ERROR invalid character in unicode escape: `l` } diff --git a/src/test/ui/parser/new-unicode-escapes-4.stderr b/src/test/ui/parser/new-unicode-escapes-4.stderr index a35c5f0f216..514591af17e 100644 --- a/src/test/ui/parser/new-unicode-escapes-4.stderr +++ b/src/test/ui/parser/new-unicode-escapes-4.stderr @@ -1,8 +1,8 @@ -error: invalid character in unicode escape: l +error: invalid character in unicode escape: `l` --> $DIR/new-unicode-escapes-4.rs:2:17 | LL | let s = "\u{lol}"; - | ^ + | ^ invalid character in unicode escape error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr index 4076fe334e6..cfc877104bd 100644 --- a/src/test/ui/parser/raw/raw-byte-string-literals.stderr +++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr @@ -8,7 +8,7 @@ error: raw byte string must be ASCII --> $DIR/raw-byte-string-literals.rs:5:8 | LL | br"é"; - | ^ + | ^ must be ASCII error: found invalid character; only `#` is allowed in raw string delimitation: ~ --> $DIR/raw-byte-string-literals.rs:6:5 diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.rs b/src/test/ui/parser/trailing-carriage-return-in-string.rs index 8abf2624e4f..5d3c3194406 100644 --- a/src/test/ui/parser/trailing-carriage-return-in-string.rs +++ b/src/test/ui/parser/trailing-carriage-return-in-string.rs @@ -8,7 +8,7 @@ fn main() { a test"; // \r only let bad = "This is \ a test"; - //~^ ERROR unknown character escape: \r - //~^^ HELP this is an isolated carriage return + //~^ ERROR unknown character escape: `\r` + //~| HELP this is an isolated carriage return } diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr index 3687b9dd282..8a44e02707c 100644 --- a/src/test/ui/parser/trailing-carriage-return-in-string.stderr +++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr @@ -1,4 +1,4 @@ -error: unknown character escape: \r +error: unknown character escape: `\r` --> $DIR/trailing-carriage-return-in-string.rs:10:25 | LL | let bad = "This is \ a test"; diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.rs b/src/test/ui/parser/wrong-escape-of-curly-braces.rs index 7a5c27afca5..8e5258acd49 100644 --- a/src/test/ui/parser/wrong-escape-of-curly-braces.rs +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.rs @@ -1,8 +1,8 @@ fn main() { let ok = "{{everything fine}}"; let bad = "\{it is wrong\}"; - //~^ ERROR unknown character escape: { - //~^^ HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` - //~^^^ ERROR unknown character escape: } - //~^^^^ HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` + //~^ ERROR unknown character escape: `{` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` + //~| ERROR unknown character escape: `}` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` } diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr index 1406b795ba8..ff1a2fb0f3c 100644 --- a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr @@ -1,4 +1,4 @@ -error: unknown character escape: { +error: unknown character escape: `{` --> $DIR/wrong-escape-of-curly-braces.rs:3:17 | LL | let bad = "\{it is wrong\}"; @@ -6,7 +6,7 @@ LL | let bad = "\{it is wrong\}"; | = help: if used in a formatting string, curly braces are escaped with `{{` and `}}` -error: unknown character escape: } +error: unknown character escape: `}` --> $DIR/wrong-escape-of-curly-braces.rs:3:30 | LL | let bad = "\{it is wrong\}"; diff --git a/src/test/ui/unsized/unchanged-param.rs b/src/test/ui/unsized/unchanged-param.rs new file mode 100644 index 00000000000..83199e8112e --- /dev/null +++ b/src/test/ui/unsized/unchanged-param.rs @@ -0,0 +1,12 @@ +#![feature(relaxed_struct_unsize)] +// run-pass +// Test that we allow unsizing even if there is an unchanged param in the +// field getting unsized. +struct A(T, B); +struct B(T, U); + +fn main() { + let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1])); + let y: &A<[u32; 1], [u32]> = &x; + assert_eq!(y.1.1.len(), 1); +} diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index d92758eb747..cd9d5300964 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -218,25 +218,19 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf cmd.args(args); cmd.envs(env); + // On windows, libraries are just searched in the executable directory, + // system directories, PWD, and PATH, in that order. PATH is the only one + // we can change for this. + let library_path = if cfg!(windows) { "PATH" } else { "LD_LIBRARY_PATH" }; + // Support libraries were uploaded to `work` earlier, so make sure that's // in `LD_LIBRARY_PATH`. Also include our own current dir which may have // had some libs uploaded. - if cfg!(windows) { - // On windows, libraries are just searched in the executable directory, - // system directories, PWD, and PATH, in that order. PATH is the only one - // we can change for this. - cmd.env( - "PATH", - env::join_paths( - std::iter::once(work.to_owned()) - .chain(std::iter::once(path.clone())) - .chain(env::split_paths(&env::var_os("PATH").unwrap())), - ) - .unwrap(), - ); - } else { - cmd.env("LD_LIBRARY_PATH", format!("{}:{}", work.display(), path.display())); + let mut paths = vec![work.to_owned(), path.clone()]; + if let Some(library_path) = env::var_os(library_path) { + paths.extend(env::split_paths(&library_path)); } + cmd.env(library_path, env::join_paths(paths).unwrap()); // Some tests assume RUST_TEST_TMPDIR exists cmd.env("RUST_TEST_TMPDIR", tmp.to_owned());