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 diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 2be60d35af330..9dc0b24cd2f3f 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -612,6 +612,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() @@ -632,6 +637,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_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 9e52598f2e05a..19bd0b6f7e674 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1779,13 +1779,20 @@ 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(); + let is_unsigned = match discr.ty.kind { + ty::Int(_) => false, + ty::Uint(_) => true, + _ => bug!("non integer discriminant"), + }; 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, + is_unsigned, )) } }) @@ -1794,13 +1801,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(), - // FIXME: what if enumeration has i128 discriminant? - variant_index.as_usize() as u64, + name.as_ptr().cast(), + name.len(), + // Generators use u32 as discriminant type. + variant_index.as_u32().into(), + true, // 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/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 789507fb48b52..e6c98ad27e8ef 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -680,6 +680,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_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`. 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 { diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 5c37faaa82a54..76475e7095868 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/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3c4a1857f9690..82a467c7ba92c 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -798,6 +798,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. diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index db4412a18a35b..c273e7fdbf916 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, @@ -912,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]", ), @@ -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, 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( 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) 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 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];