diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a9e8afe434e..1037a49acdf 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -26,10 +26,9 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_generics, Visitor as _}; use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin}; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; -use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; @@ -43,7 +42,10 @@ use rustc_trait_selection::traits::error_reporting::{ report_object_safety_error, suggestions::NextTypeParamName, }; use rustc_trait_selection::traits::wf::object_region_bounds; -use rustc_trait_selection::traits::{self, astconv_object_safety_violations, ObligationCtxt}; +use rustc_trait_selection::traits::{ + self, astconv_object_safety_violations, NormalizeExt, ObligationCtxt, +}; +use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use smallvec::{smallvec, SmallVec}; use std::collections::BTreeSet; @@ -2442,6 +2444,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return Ok(None); } + if !tcx.features().inherent_associated_types { + tcx.sess + .delay_span_bug(span, "found inherent assoc type without the feature being gated"); + } + // // Select applicable inherent associated type candidates modulo regions. // @@ -2465,23 +2472,53 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut fulfillment_errors = Vec::new(); let mut applicable_candidates: Vec<_> = infcx.probe(|_| { - let universe = infcx.create_next_universe(); - // Regions are not considered during selection. - // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes - // of type and const binders. Is that correct in the selection phase? See also #109505. - let self_ty = tcx.replace_escaping_bound_vars_uncached( - self_ty, - FnMutDelegate { - regions: &mut |_| tcx.lifetimes.re_erased, - types: &mut |bv| { - tcx.mk_placeholder(ty::PlaceholderType { universe, bound: bv }) - }, - consts: &mut |bv, ty| { - tcx.mk_const(ty::PlaceholderConst { universe, bound: bv }, ty) - }, - }, - ); + let self_ty = self_ty + .fold_with(&mut BoundVarEraser { tcx, universe: infcx.create_next_universe() }); + + struct BoundVarEraser<'tcx> { + tcx: TyCtxt<'tcx>, + universe: ty::UniverseIndex, + } + + // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder. + impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarEraser<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r } + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match *ty.kind() { + ty::Bound(_, bv) => self.tcx.mk_placeholder(ty::PlaceholderType { + universe: self.universe, + bound: bv, + }), + _ => ty.super_fold_with(self), + } + } + + fn fold_const( + &mut self, + ct: ty::Const<'tcx>, + ) -> <TyCtxt<'tcx> as rustc_type_ir::Interner>::Const { + assert!(!ct.ty().has_escaping_bound_vars()); + + match ct.kind() { + ty::ConstKind::Bound(_, bv) => self.tcx.mk_const( + ty::PlaceholderConst { universe: self.universe, bound: bv }, + ct.ty(), + ), + _ => ct.super_fold_with(self), + } + } + } + + let InferOk { value: self_ty, obligations } = + infcx.at(&cause, param_env).normalize(self_ty); candidates .iter() @@ -2489,6 +2526,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .filter(|&(impl_, _)| { infcx.probe(|_| { let ocx = ObligationCtxt::new_in_snapshot(&infcx); + ocx.register_obligations(obligations.clone()); let impl_substs = infcx.fresh_substs_for_item(span, impl_); let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs); diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 9263394508e..35eec2c8e1b 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -695,7 +695,7 @@ parse_struct_literal_body_without_path = parse_struct_literal_needing_parens = invalid struct literal - .suggestion = you might need to surround the struct literal in parentheses + .suggestion = you might need to surround the struct literal with parentheses parse_struct_literal_not_allowed_here = struct literals are not allowed here .suggestion = surround the struct literal with parentheses diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index eb9625f923a..461a34b67db 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -158,7 +158,7 @@ pub(crate) fn emit_unescape_error( diag.help( "for more information, visit \ - <https://static.rust-lang.org/doc/master/reference.html#literals>", + <https://doc.rust-lang.org/reference/tokens.html#literals>", ); } diag.emit(); diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c1454039685..228eff1269f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -751,13 +751,24 @@ impl<'a> Parser<'a> { tail.could_be_bare_literal = true; if maybe_struct_name.is_ident() && can_be_struct_literal { // Account for `if Example { a: one(), }.is_pos() {}`. - Err(self.sess.create_err(StructLiteralNeedingParens { - span: maybe_struct_name.span.to(expr.span), - sugg: StructLiteralNeedingParensSugg { - before: maybe_struct_name.span.shrink_to_lo(), - after: expr.span.shrink_to_hi(), - }, - })) + // expand `before` so that we take care of module path such as: + // `foo::Bar { ... } ` + // we expect to suggest `(foo::Bar { ... })` instead of `foo::(Bar { ... })` + let sm = self.sess.source_map(); + let before = maybe_struct_name.span.shrink_to_lo(); + if let Ok(extend_before) = sm.span_extend_prev_while(before, |t| { + t.is_alphanumeric() || t == ':' || t == '_' + }) { + Err(self.sess.create_err(StructLiteralNeedingParens { + span: maybe_struct_name.span.to(expr.span), + sugg: StructLiteralNeedingParensSugg { + before: extend_before.shrink_to_lo(), + after: expr.span.shrink_to_hi(), + }, + })) + } else { + return None; + } } else { self.sess.emit_err(StructLiteralBodyWithoutPath { span: expr.span, diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 1824510a974..c53fe084c4d 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -744,6 +744,21 @@ impl SourceMap { }) } + /// Extends the given `Span` to previous character while the previous character matches the predicate + pub fn span_extend_prev_while( + &self, + span: Span, + f: impl Fn(char) -> bool, + ) -> Result<Span, SpanSnippetError> { + self.span_to_source(span, |s, start, _end| { + let n = s[..start] + .char_indices() + .rfind(|&(_, c)| !f(c)) + .map_or(start, |(i, _)| start - i - 1); + Ok(span.with_lo(span.lo() - BytePos(n as u32))) + }) + } + /// Extends the given `Span` to just before the next occurrence of `c`. pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span { if let Ok(next_source) = self.span_to_next_source(sp) { diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 408244b2ce9..bed90418be1 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -528,7 +528,7 @@ impl f32 { /// The positive difference of two numbers. /// - /// * If `self <= other`: `0:0` + /// * If `self <= other`: `0.0` /// * Else: `self - other` /// /// # Examples diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 6782b861f11..e72de05ca41 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -530,7 +530,7 @@ impl f64 { /// The positive difference of two numbers. /// - /// * If `self <= other`: `0:0` + /// * If `self <= other`: `0.0` /// * Else: `self - other` /// /// # Examples diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 07b0610d463..5fc6136ba1f 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -19,6 +19,7 @@ pub use windows_sys::*; pub type DWORD = c_ulong; pub type NonZeroDWORD = NonZero_c_ulong; pub type LARGE_INTEGER = c_longlong; +#[cfg_attr(target_vendor = "uwp", allow(unused))] pub type LONG = c_long; pub type UINT = c_uint; pub type WCHAR = u16; @@ -267,6 +268,8 @@ pub unsafe fn getaddrinfo( windows_sys::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res) } +cfg_if::cfg_if! { +if #[cfg(not(target_vendor = "uwp"))] { pub unsafe fn NtReadFile( filehandle: BorrowedHandle<'_>, event: HANDLE, @@ -313,6 +316,8 @@ pub unsafe fn NtWriteFile( key.map(|k| k as *const u32).unwrap_or(ptr::null()), ) } +} +} // Functions that aren't available on every version of Windows that we support, // but we still use them and just provide some form of a fallback implementation. @@ -376,4 +381,54 @@ compat_fn_with_fallback! { ) -> NTSTATUS { panic!("keyed events not available") } + + // These functions are available on UWP when lazily loaded. They will fail WACK if loaded statically. + #[cfg(target_vendor = "uwp")] + pub fn NtCreateFile( + filehandle: *mut HANDLE, + desiredaccess: FILE_ACCESS_RIGHTS, + objectattributes: *const OBJECT_ATTRIBUTES, + iostatusblock: *mut IO_STATUS_BLOCK, + allocationsize: *const i64, + fileattributes: FILE_FLAGS_AND_ATTRIBUTES, + shareaccess: FILE_SHARE_MODE, + createdisposition: NTCREATEFILE_CREATE_DISPOSITION, + createoptions: NTCREATEFILE_CREATE_OPTIONS, + eabuffer: *const ::core::ffi::c_void, + ealength: u32 + ) -> NTSTATUS { + STATUS_NOT_IMPLEMENTED + } + #[cfg(target_vendor = "uwp")] + pub fn NtReadFile( + filehandle: BorrowedHandle<'_>, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *mut c_void, + iostatusblock: &mut IO_STATUS_BLOCK, + buffer: *mut crate::mem::MaybeUninit<u8>, + length: ULONG, + byteoffset: Option<&LARGE_INTEGER>, + key: Option<&ULONG> + ) -> NTSTATUS { + STATUS_NOT_IMPLEMENTED + } + #[cfg(target_vendor = "uwp")] + pub fn NtWriteFile( + filehandle: BorrowedHandle<'_>, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *mut c_void, + iostatusblock: &mut IO_STATUS_BLOCK, + buffer: *const u8, + length: ULONG, + byteoffset: Option<&LARGE_INTEGER>, + key: Option<&ULONG> + ) -> NTSTATUS { + STATUS_NOT_IMPLEMENTED + } + #[cfg(target_vendor = "uwp")] + pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 { + Status as u32 + } } diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index 3e454199f13..2cf1ade99ce 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -1930,6 +1930,7 @@ Windows.Win32.Foundation.SetLastError Windows.Win32.Foundation.STATUS_DELETE_PENDING Windows.Win32.Foundation.STATUS_END_OF_FILE Windows.Win32.Foundation.STATUS_INVALID_PARAMETER +Windows.Win32.Foundation.STATUS_NOT_IMPLEMENTED Windows.Win32.Foundation.STATUS_PENDING Windows.Win32.Foundation.STATUS_SUCCESS Windows.Win32.Foundation.TRUE diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index 36a30f6ba56..8c8b006a1d3 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -3888,6 +3888,7 @@ pub type STARTUPINFOW_FLAGS = u32; pub const STATUS_DELETE_PENDING: NTSTATUS = -1073741738i32; pub const STATUS_END_OF_FILE: NTSTATUS = -1073741807i32; pub const STATUS_INVALID_PARAMETER: NTSTATUS = -1073741811i32; +pub const STATUS_NOT_IMPLEMENTED: NTSTATUS = -1073741822i32; pub const STATUS_PENDING: NTSTATUS = 259i32; pub const STATUS_SUCCESS: NTSTATUS = 0i32; pub const STD_ERROR_HANDLE: STD_HANDLE = 4294967284u32; diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs index bca4e38d9f6..5d8fd13785a 100644 --- a/library/std/src/sys/windows/rand.rs +++ b/library/std/src/sys/windows/rand.rs @@ -1,5 +1,3 @@ -use crate::ffi::c_void; -use crate::io; use crate::mem; use crate::ptr; use crate::sys::c; @@ -25,6 +23,9 @@ pub fn hashmap_random_keys() -> (u64, u64) { #[cfg(not(target_vendor = "uwp"))] #[inline(never)] fn fallback_rng() -> (u64, u64) { + use crate::ffi::c_void; + use crate::io; + let mut v = (0, 0); let ret = unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut c_void, mem::size_of_val(&v) as c::ULONG) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 72d791b5434..c28fe9022ec 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1488,6 +1488,10 @@ impl Step for Assemble { // Ensure that `libLLVM.so` ends up in the newly created target directory, // so that tools using `rustc_private` can use it. dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot); + // Lower stages use `ci-rustc-sysroot`, not stageN + if target_compiler.stage == builder.top_stage { + builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=target_compiler.stage)); + } return target_compiler; } @@ -1525,11 +1529,18 @@ impl Step for Assemble { let stage = target_compiler.stage; let host = target_compiler.host; - let msg = if build_compiler.host == host { - format!("Assembling stage{} compiler", stage) + let (host_info, dir_name) = if build_compiler.host == host { + ("".into(), "host".into()) } else { - format!("Assembling stage{} compiler ({})", stage, host) + (format!(" ({host})"), host.to_string()) }; + // NOTE: "Creating a sysroot" is somewhat inconsistent with our internal terminology, since + // sysroots can temporarily be empty until we put the compiler inside. However, + // `ensure(Sysroot)` isn't really something that's user facing, so there shouldn't be any + // ambiguity. + let msg = format!( + "Creating a sysroot for stage{stage} compiler{host_info} (use `rustup toolchain link 'name' build/{dir_name}/stage{stage}`)" + ); builder.info(&msg); // Link in all dylibs to the libdir diff --git a/tests/rustdoc-gui/search-reexport.goml b/tests/rustdoc-gui/search-reexport.goml index fd817b58990..c5c386ce750 100644 --- a/tests/rustdoc-gui/search-reexport.goml +++ b/tests/rustdoc-gui/search-reexport.goml @@ -17,7 +17,7 @@ assert-attribute: ( assert-text: ("//a[@class='result-import']", "test_docs::TheStdReexport") click: "//a[@class='result-import']" // We check that it has the background modified thanks to the focus. -wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"}) +wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a3d"}) // We now check that the alias is working as well on the reexport. // To be SURE that the search will be run. @@ -30,4 +30,4 @@ assert-text: ( ) // Same thing again, we click on it to ensure the background is once again set as expected. click: "//a[@class='result-import']" -wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgb(73, 74, 61)"}) +wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a3d"}) diff --git a/tests/ui/associated-inherent-types/issue-111404-0.rs b/tests/ui/associated-inherent-types/issue-111404-0.rs new file mode 100644 index 00000000000..1180577bd54 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111404-0.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo<T>(T); + +impl<'a> Foo<fn(&'a ())> { + type Assoc = &'a (); +} + +fn bar(_: for<'a> fn(Foo<fn(Foo<fn(&'a ())>::Assoc)>::Assoc)) {} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-111404-1.rs b/tests/ui/associated-inherent-types/issue-111404-1.rs new file mode 100644 index 00000000000..f4ad5d7ff6c --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111404-1.rs @@ -0,0 +1,13 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo<T>(T); + +impl<'a> Foo<fn(&'a ())> { + type Assoc = &'a (); +} + +fn bar(_: fn(Foo<for<'b> fn(Foo<fn(&'b ())>::Assoc)>::Assoc)) {} +//~^ ERROR higher-ranked subtype error + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-111404-1.stderr b/tests/ui/associated-inherent-types/issue-111404-1.stderr new file mode 100644 index 00000000000..c55f1432389 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111404-1.stderr @@ -0,0 +1,8 @@ +error: higher-ranked subtype error + --> $DIR/issue-111404-1.rs:10:1 + | +LL | fn bar(_: fn(Foo<for<'b> fn(Foo<fn(&'b ())>::Assoc)>::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/lexer/lex-bad-char-literals-1.stderr b/tests/ui/lexer/lex-bad-char-literals-1.stderr index e6ff1f662bd..9dc0a338063 100644 --- a/tests/ui/lexer/lex-bad-char-literals-1.stderr +++ b/tests/ui/lexer/lex-bad-char-literals-1.stderr @@ -16,7 +16,7 @@ error: unknown character escape: `\u{25cf}` LL | '\●' | ^ unknown character escape | - = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal | LL | r"\●" @@ -28,7 +28,7 @@ error: unknown character escape: `\u{25cf}` LL | "\●" | ^ unknown character escape | - = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal | LL | r"\●" diff --git a/tests/ui/parser/bad-escape-suggest-raw-string.rs b/tests/ui/parser/bad-escape-suggest-raw-string.rs index 978b92cbcd2..06df82d288b 100644 --- a/tests/ui/parser/bad-escape-suggest-raw-string.rs +++ b/tests/ui/parser/bad-escape-suggest-raw-string.rs @@ -2,6 +2,6 @@ fn main() { let ok = r"ab\[c"; let bad = "ab\[c"; //~^ ERROR unknown character escape: `[` - //~| HELP for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + //~| HELP for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> //~| HELP if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal } diff --git a/tests/ui/parser/bad-escape-suggest-raw-string.stderr b/tests/ui/parser/bad-escape-suggest-raw-string.stderr index fc34bd3281a..45d24bc0fb3 100644 --- a/tests/ui/parser/bad-escape-suggest-raw-string.stderr +++ b/tests/ui/parser/bad-escape-suggest-raw-string.stderr @@ -4,7 +4,7 @@ error: unknown character escape: `[` LL | let bad = "ab\[c"; | ^ unknown character escape | - = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal | LL | let bad = r"ab\[c"; diff --git a/tests/ui/parser/byte-literals.stderr b/tests/ui/parser/byte-literals.stderr index efa55ae05bd..5b414c8927e 100644 --- a/tests/ui/parser/byte-literals.stderr +++ b/tests/ui/parser/byte-literals.stderr @@ -4,7 +4,7 @@ error: unknown byte escape: `f` LL | static FOO: u8 = b'\f'; | ^ unknown byte escape | - = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> error: unknown byte escape: `f` --> $DIR/byte-literals.rs:6:8 @@ -12,7 +12,7 @@ error: unknown byte escape: `f` LL | b'\f'; | ^ unknown byte escape | - = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> error: invalid character in numeric character escape: `Z` --> $DIR/byte-literals.rs:7:10 diff --git a/tests/ui/parser/byte-string-literals.stderr b/tests/ui/parser/byte-string-literals.stderr index 5b96cc3d18a..655b6998e85 100644 --- a/tests/ui/parser/byte-string-literals.stderr +++ b/tests/ui/parser/byte-string-literals.stderr @@ -4,7 +4,7 @@ error: unknown byte escape: `f` LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape | - = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:4:8 @@ -12,7 +12,7 @@ error: unknown byte escape: `f` LL | b"\f"; | ^ unknown byte escape | - = help: for more information, visit <https://static.rust-lang.org/doc/master/reference.html#literals> + = help: for more information, visit <https://doc.rust-lang.org/reference/tokens.html#literals> error: invalid character in numeric character escape: `Z` --> $DIR/byte-string-literals.rs:5:10 diff --git a/tests/ui/parser/issues/issue-111692.rs b/tests/ui/parser/issues/issue-111692.rs new file mode 100644 index 00000000000..56096f706a8 --- /dev/null +++ b/tests/ui/parser/issues/issue-111692.rs @@ -0,0 +1,32 @@ +mod module { + #[derive(Eq, PartialEq)] + pub struct Type { + pub x: u8, + pub y: u8, + } + + pub const C: u8 = 32u8; +} + +fn test(x: module::Type) { + if x == module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + +fn test2(x: module::Type) { + if x ==module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + + +fn test3(x: module::Type) { + if x == Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + +fn test4(x: module::Type) { + if x == demo_module::Type { x: module::C, y: 1 } { //~ ERROR invalid struct literal + } +} + +fn main() { } diff --git a/tests/ui/parser/issues/issue-111692.stderr b/tests/ui/parser/issues/issue-111692.stderr new file mode 100644 index 00000000000..068b0483b0f --- /dev/null +++ b/tests/ui/parser/issues/issue-111692.stderr @@ -0,0 +1,46 @@ +error: invalid struct literal + --> $DIR/issue-111692.rs:12:21 + | +LL | if x == module::Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x == (module::Type { x: module::C, y: 1 }) { + | + + + +error: invalid struct literal + --> $DIR/issue-111692.rs:17:20 + | +LL | if x ==module::Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x ==(module::Type { x: module::C, y: 1 }) { + | + + + +error: invalid struct literal + --> $DIR/issue-111692.rs:23:13 + | +LL | if x == Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x == (Type { x: module::C, y: 1 }) { + | + + + +error: invalid struct literal + --> $DIR/issue-111692.rs:28:26 + | +LL | if x == demo_module::Type { x: module::C, y: 1 } { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you might need to surround the struct literal with parentheses + | +LL | if x == (demo_module::Type { x: module::C, y: 1 }) { + | + + + +error: aborting due to 4 previous errors + diff --git a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr index 7fd7ffc94a5..dedbad90945 100644 --- a/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr +++ b/tests/ui/parser/method-call-on-struct-literal-in-if-condition.stderr @@ -4,7 +4,7 @@ error: invalid struct literal LL | if Example { a: one(), }.is_pos() { | ^^^^^^^^^^^^^^^^^^^^^ | -help: you might need to surround the struct literal in parentheses +help: you might need to surround the struct literal with parentheses | LL | if (Example { a: one(), }).is_pos() { | + +