From 30d4f1b78d997fb555388cb8ebea474ffb85794c Mon Sep 17 00:00:00 2001 From: spunit262 <45582704+spunit262@users.noreply.github.com> Date: Wed, 12 Feb 2020 17:46:15 -0700 Subject: [PATCH 01/11] Don't give invalid suggestion on desugared span. --- .../diagnostics/mutability_errors.rs | 88 ++++++++++--------- .../dont-print-desugared-async.stderr | 5 +- src/test/ui/nll/dont-print-desugared.stderr | 5 +- 3 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index d91f6edc9800c..b0a82bc2ba5fb 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -329,40 +329,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if self.body.local_decls[local].is_user_variable() => { let local_decl = &self.body.local_decls[local]; - let suggestion = match local_decl.local_info { - LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf(_))) => { - Some(suggest_ampmut_self(self.infcx.tcx, local_decl)) - } - - LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var( - mir::VarBindingForm { - binding_mode: ty::BindingMode::BindByValue(_), - opt_ty_info, - .. - }, - ))) => Some(suggest_ampmut( - self.infcx.tcx, - self.body, - local, - local_decl, - opt_ty_info, - )), - - LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var( - mir::VarBindingForm { - binding_mode: ty::BindingMode::BindByReference(_), - .. - }, - ))) => { - let pattern_span = local_decl.source_info.span; - suggest_ref_mut(self.infcx.tcx, pattern_span) - .map(|replacement| (pattern_span, replacement)) - } - - LocalInfo::User(ClearCrossCrate::Clear) => bug!("saw cleared local state"), - - _ => unreachable!(), - }; let (pointer_sigil, pointer_desc) = if local_decl.ty.is_region_ptr() { ("&", "reference") @@ -370,17 +336,53 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ("*const", "pointer") }; - if let Some((err_help_span, suggested_code)) = suggestion { - err.span_suggestion( - err_help_span, - &format!("consider changing this to be a mutable {}", pointer_desc), - suggested_code, - Applicability::MachineApplicable, - ); - } - match self.local_names[local] { Some(name) if !local_decl.from_compiler_desugaring() => { + let suggestion = match local_decl.local_info { + LocalInfo::User(ClearCrossCrate::Set( + mir::BindingForm::ImplicitSelf(_), + )) => Some(suggest_ampmut_self(self.infcx.tcx, local_decl)), + + LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var( + mir::VarBindingForm { + binding_mode: ty::BindingMode::BindByValue(_), + opt_ty_info, + .. + }, + ))) => Some(suggest_ampmut( + self.infcx.tcx, + self.body, + local, + local_decl, + opt_ty_info, + )), + + LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var( + mir::VarBindingForm { + binding_mode: ty::BindingMode::BindByReference(_), + .. + }, + ))) => { + let pattern_span = local_decl.source_info.span; + suggest_ref_mut(self.infcx.tcx, pattern_span) + .map(|replacement| (pattern_span, replacement)) + } + + LocalInfo::User(ClearCrossCrate::Clear) => { + bug!("saw cleared local state") + } + + _ => unreachable!(), + }; + + if let Some((err_help_span, suggested_code)) = suggestion { + err.span_suggestion( + err_help_span, + &format!("consider changing this to be a mutable {}", pointer_desc), + suggested_code, + Applicability::MachineApplicable, + ); + } err.span_label( span, format!( diff --git a/src/test/ui/async-await/dont-print-desugared-async.stderr b/src/test/ui/async-await/dont-print-desugared-async.stderr index 2bf1e77f09b3f..d80467c7fa887 100644 --- a/src/test/ui/async-await/dont-print-desugared-async.stderr +++ b/src/test/ui/async-await/dont-print-desugared-async.stderr @@ -2,10 +2,7 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/dont-print-desugared-async.rs:5:20 | LL | async fn async_fn(&ref mut s: &[i32]) {} - | -^^^^^^^^^ - | || - | |cannot borrow as mutable through `&` reference - | help: consider changing this to be a mutable reference: `&mut ref mut s` + | ^^^^^^^^^ cannot borrow as mutable through `&` reference error: aborting due to previous error diff --git a/src/test/ui/nll/dont-print-desugared.stderr b/src/test/ui/nll/dont-print-desugared.stderr index 45d7cbcdfbe7f..88773def8b7c8 100644 --- a/src/test/ui/nll/dont-print-desugared.stderr +++ b/src/test/ui/nll/dont-print-desugared.stderr @@ -2,10 +2,7 @@ error[E0596]: cannot borrow data in a `&` reference as mutable --> $DIR/dont-print-desugared.rs:4:10 | LL | for &ref mut x in s {} - | -^^^^^^^^^ - | || - | |cannot borrow as mutable through `&` reference - | help: consider changing this to be a mutable reference: `&mut ref mut x` + | ^^^^^^^^^ cannot borrow as mutable through `&` reference error[E0597]: `y` does not live long enough --> $DIR/dont-print-desugared.rs:17:16 From 4023e5df7ebc2e50289c9828e374b0bf901a219d Mon Sep 17 00:00:00 2001 From: O01eg Date: Sun, 1 Mar 2020 14:33:52 +0300 Subject: [PATCH 02/11] Expose target libdir information via print command. With custom libdir it is required to have an access to library placement. --- src/librustc_driver/lib.rs | 4 ++++ src/librustc_session/config.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 9a94349e5fde4..5089a14a34c1b 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -676,6 +676,10 @@ impl RustcDefaultCalls { println!("{}", targets.join("\n")); } Sysroot => println!("{}", sess.sysroot.display()), + TargetLibdir => println!( + "{}", + sess.target_tlib_path.as_ref().unwrap_or(&sess.host_tlib_path).dir.display() + ), TargetSpec => println!("{}", sess.target.target.to_json().pretty()), FileNames | CrateName => { let input = input.unwrap_or_else(|| { diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index db4412a18a35b..60f25871dd9dd 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -391,6 +391,7 @@ impl ExternEntry { pub enum PrintRequest { FileNames, Sysroot, + TargetLibdir, CrateName, Cfg, TargetList, @@ -1344,6 +1345,7 @@ fn collect_print_requests( "crate-name" => PrintRequest::CrateName, "file-names" => PrintRequest::FileNames, "sysroot" => PrintRequest::Sysroot, + "target-libdir" => PrintRequest::TargetLibdir, "cfg" => PrintRequest::Cfg, "target-list" => PrintRequest::TargetList, "target-cpus" => PrintRequest::TargetCPUs, From 7694a6d6d9a3505a2b0b7b5cc21d501f88b867c3 Mon Sep 17 00:00:00 2001 From: O01eg Date: Sun, 1 Mar 2020 16:14:26 +0300 Subject: [PATCH 03/11] Print new --print option in help. --- src/librustc_session/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 60f25871dd9dd..c273e7fdbf916 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -913,7 +913,7 @@ pub fn rustc_short_optgroups() -> Vec { "", "print", "Compiler information to print on stdout", - "[crate-name|file-names|sysroot|cfg|target-list|\ + "[crate-name|file-names|sysroot|target-libdir|cfg|target-list|\ target-cpus|target-features|relocation-models|\ code-models|tls-models|target-spec-json|native-static-libs]", ), From e54a16cffce0ecea2954b5af51247f7b4179900b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 5 Mar 2020 00:00:00 +0000 Subject: [PATCH 04/11] Change DIBuilderCreateEnumerator signature to match LLVM 9 No functional changes intended. --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 16 ++++++++++------ src/librustc_codegen_llvm/llvm/ffi.rs | 4 +++- src/rustllvm/RustWrapper.cpp | 8 ++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 3916653eb1d76..7beaf134e6ba1 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1779,13 +1779,15 @@ fn prepare_enum_metadata( .discriminants(cx.tcx) .zip(&def.variants) .map(|((_, discr), v)| { - let name = SmallCStr::new(&v.ident.as_str()); + let name = v.ident.as_str(); unsafe { Some(llvm::LLVMRustDIBuilderCreateEnumerator( DIB(cx), - name.as_ptr(), + name.as_ptr().cast(), + name.len(), // FIXME: what if enumeration has i128 discriminant? - discr.val as u64, + discr.val as i64, + false, // FIXME: IsUnsigned. )) } }) @@ -1794,13 +1796,15 @@ fn prepare_enum_metadata( .as_generator() .variant_range(enum_def_id, cx.tcx) .map(|variant_index| { - let name = SmallCStr::new(&substs.as_generator().variant_name(variant_index)); + let name = substs.as_generator().variant_name(variant_index); unsafe { Some(llvm::LLVMRustDIBuilderCreateEnumerator( DIB(cx), - name.as_ptr(), + name.as_ptr().cast(), + name.len(), // FIXME: what if enumeration has i128 discriminant? - variant_index.as_usize() as u64, + variant_index.as_usize() as i64, + false, // FIXME: IsUnsigned. )) } }) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index f56647044e08b..8b796e0423b13 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1776,7 +1776,9 @@ extern "C" { pub fn LLVMRustDIBuilderCreateEnumerator( Builder: &DIBuilder<'a>, Name: *const c_char, - Val: u64, + NameLen: size_t, + Value: i64, + IsUnsigned: bool, ) -> &'a DIEnumerator; pub fn LLVMRustDIBuilderCreateEnumerationType( diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 49b6e1bfec38d..0e430d3881e60 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -891,10 +891,10 @@ extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd( unwrap(InsertAtEnd))); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder, - const char *Name, uint64_t Val) { - return wrap(Builder->createEnumerator(Name, Val)); +extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator( + LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, + int64_t Value, bool IsUnsigned) { + return wrap(Builder->createEnumerator({Name, NameLen}, Value, IsUnsigned)); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( From ebd941b890e4731aed0ea1f76f056c8a6394f251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 5 Mar 2020 00:00:00 +0000 Subject: [PATCH 05/11] debuginfo: Generators use u32 as discriminant type repr --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 7beaf134e6ba1..095330a2e4b55 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1802,9 +1802,9 @@ fn prepare_enum_metadata( DIB(cx), name.as_ptr().cast(), name.len(), - // FIXME: what if enumeration has i128 discriminant? - variant_index.as_usize() as i64, - false, // FIXME: IsUnsigned. + // Generators use u32 as discriminant type. + variant_index.as_u32().into(), + true, // IsUnsigned )) } }) From 30650f867bb0a94b3378942487e78f3eb7eb868f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 5 Mar 2020 00:00:00 +0000 Subject: [PATCH 06/11] debuginfo: Use is unsigned flag when emitting enumerators --- .../debuginfo/metadata.rs | 7 ++++- src/test/codegen/enum-discriminant-value.rs | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/test/codegen/enum-discriminant-value.rs diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 095330a2e4b55..67529a82532ce 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1780,6 +1780,11 @@ fn prepare_enum_metadata( .zip(&def.variants) .map(|((_, discr), v)| { let name = v.ident.as_str(); + let is_unsigned = match discr.ty.kind { + ty::Int(_) => false, + ty::Uint(_) => true, + _ => bug!("non integer discriminant"), + }; unsafe { Some(llvm::LLVMRustDIBuilderCreateEnumerator( DIB(cx), @@ -1787,7 +1792,7 @@ fn prepare_enum_metadata( name.len(), // FIXME: what if enumeration has i128 discriminant? discr.val as i64, - false, // FIXME: IsUnsigned. + is_unsigned, )) } }) diff --git a/src/test/codegen/enum-discriminant-value.rs b/src/test/codegen/enum-discriminant-value.rs new file mode 100644 index 0000000000000..f9da987765f9c --- /dev/null +++ b/src/test/codegen/enum-discriminant-value.rs @@ -0,0 +1,27 @@ +// Verify that DIEnumerator uses isUnsigned flag when appropriate. +// +// compile-flags: -g -C no-prepopulate-passes + +#[repr(i64)] +pub enum I64 { + I64Min = std::i64::MIN, + I64Max = std::i64::MAX, +} + +#[repr(u64)] +pub enum U64 { + U64Min = std::u64::MIN, + U64Max = std::u64::MAX, +} + +fn main() { + let _a = I64::I64Min; + let _b = I64::I64Max; + let _c = U64::U64Min; + let _d = U64::U64Max; +} + +// CHECK: !DIEnumerator(name: "I64Min", value: -9223372036854775808) +// CHECK: !DIEnumerator(name: "I64Max", value: 9223372036854775807) +// CHECK: !DIEnumerator(name: "U64Min", value: 0, isUnsigned: true) +// CHECK: !DIEnumerator(name: "U64Max", value: 18446744073709551615, isUnsigned: true) From 05f6482f435c498b19f3af56d1017c84323683f5 Mon Sep 17 00:00:00 2001 From: JOE1994 Date: Thu, 20 Feb 2020 14:29:40 -0500 Subject: [PATCH 07/11] mir-interpret: add method Memory::read wide_string --- src/librustc/mir/interpret/value.rs | 10 ++++++++++ src/librustc_mir/interpret/memory.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 2be36ad418a5b..8a02f47accb5d 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -590,6 +590,11 @@ impl<'tcx, Tag> ScalarMaybeUndef { self.not_undef()?.to_u8() } + #[inline(always)] + pub fn to_u16(self) -> InterpResult<'tcx, u16> { + self.not_undef()?.to_u16() + } + #[inline(always)] pub fn to_u32(self) -> InterpResult<'tcx, u32> { self.not_undef()?.to_u32() @@ -610,6 +615,11 @@ impl<'tcx, Tag> ScalarMaybeUndef { self.not_undef()?.to_i8() } + #[inline(always)] + pub fn to_i16(self) -> InterpResult<'tcx, i16> { + self.not_undef()?.to_i16() + } + #[inline(always)] pub fn to_i32(self) -> InterpResult<'tcx, i32> { self.not_undef()?.to_i32() diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 0bcdf9ae3c1f2..4b668500e7c93 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -791,6 +791,33 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { self.get_raw(ptr.alloc_id)?.read_c_str(self, ptr) } + /// Reads a 0x0000-terminated u16-sequence from memory. Returns them as a Vec. + /// Terminator 0x0000 is not included in the returned Vec. + /// + /// Performs appropriate bounds checks. + pub fn read_wide_str(&self, ptr: Scalar) -> InterpResult<'tcx, Vec> { + let size_2bytes = Size::from_bytes(2); + let align_2bytes = Align::from_bytes(2).unwrap(); + // We need to read at least 2 bytes, so we *need* a ptr. + let mut ptr = self.force_ptr(ptr)?; + let allocation = self.get_raw(ptr.alloc_id)?; + let mut u16_seq = Vec::new(); + + loop { + ptr = self + .check_ptr_access(ptr.into(), size_2bytes, align_2bytes)? + .expect("cannot be a ZST"); + let single_u16 = allocation.read_scalar(self, ptr, size_2bytes)?.to_u16()?; + if single_u16 != 0x0000 { + u16_seq.push(single_u16); + ptr = ptr.offset(size_2bytes, self)?; + } else { + break; + } + } + Ok(u16_seq) + } + /// Writes the given stream of bytes into memory. /// /// Performs appropriate bounds checks. From dbd1514353a5aa38d08fbb08e05aa478ae926de0 Mon Sep 17 00:00:00 2001 From: O01eg Date: Sat, 7 Mar 2020 07:29:23 +0300 Subject: [PATCH 08/11] Add new option to the documentation. --- src/doc/rustc/src/command-line-arguments.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 659f8f65e65d2..7a7838d965bc7 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -146,6 +146,7 @@ The valid types of print values are: - `crate-name` — The name of the crate. - `file-names` — The names of the files created by the `link` emit kind. - `sysroot` — Path to the sysroot. +- `target-libdir` - Path to the target libdir. - `cfg` — List of cfg values. See [conditional compilation] for more information about cfg values. - `target-list` — List of known targets. The target may be selected with the From adc422f3d5f2f63445567cbbb37c7828368b1cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 7 Mar 2020 00:00:00 +0000 Subject: [PATCH 09/11] Compile address sanitizer test with debuginfo This makes error-pattern to match regardless of current configuration of `rust.debuginfo-level-tests` in `config.toml`. --- src/test/ui/sanitize/address.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/ui/sanitize/address.rs b/src/test/ui/sanitize/address.rs index d27a30a2dc55f..f8650cd86d51e 100644 --- a/src/test/ui/sanitize/address.rs +++ b/src/test/ui/sanitize/address.rs @@ -1,16 +1,15 @@ // needs-sanitizer-support // only-x86_64 // -// compile-flags: -Z sanitizer=address -O +// compile-flags: -Z sanitizer=address -O -g // // run-fail // error-pattern: AddressSanitizer: stack-buffer-overflow -// error-pattern: 'xs' <== Memory access at offset +// error-pattern: 'xs' (line 15) <== Memory access at offset #![feature(test)] use std::hint::black_box; -use std::mem; fn main() { let xs = [0, 1, 2, 3]; From 4db15d89a08580ad0c825a0c67b4b14e103cf1cd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 7 Mar 2020 18:42:09 +0100 Subject: [PATCH 10/11] Cleanup E0391 explanation --- src/librustc_error_codes/error_codes/E0391.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0391.md b/src/librustc_error_codes/error_codes/E0391.md index 5db9ad16d08f7..dff50ccaa0b77 100644 --- a/src/librustc_error_codes/error_codes/E0391.md +++ b/src/librustc_error_codes/error_codes/E0391.md @@ -1,7 +1,6 @@ -This error indicates that some types or traits depend on each other -and therefore cannot be constructed. +A type dependency cycle has been encountered. -The following example contains a circular dependency between two traits: +Erroneous code example: ```compile_fail,E0391 trait FirstTrait : SecondTrait { @@ -12,3 +11,6 @@ trait SecondTrait : FirstTrait { } ``` + +The previous example contains a circular dependency between two traits: +`FirstTrait` depends on `SecondTrait` which itself depends on `FirstTrait`. From 2676afeca49cfaeac99a5a558493fd16a0b08675 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 8 Mar 2020 10:44:23 +0100 Subject: [PATCH 11/11] clean up E0392 explanation --- src/librustc_error_codes/error_codes/E0392.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0392.md b/src/librustc_error_codes/error_codes/E0392.md index 1d93e904e37fc..f373d89456dd4 100644 --- a/src/librustc_error_codes/error_codes/E0392.md +++ b/src/librustc_error_codes/error_codes/E0392.md @@ -1,5 +1,6 @@ -This error indicates that a type or lifetime parameter has been declared -but not actually used. Here is an example that demonstrates the error: +A type or lifetime parameter has been declared but is not actually used. + +Erroneous code example: ```compile_fail,E0392 enum Foo {