Auto merge of #69833 - Centril:rollup-mh74yue, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #69120 (Don't give invalid suggestion on desugared span.)
 - #69326 (mir-interpret: add method to read wide strings from Memory)
 - #69608 (Expose target libdir information via print command)
 - #69734 (Change DIBuilderCreateEnumerator signature to match LLVM 9)
 - #69800 (Compile address sanitizer test with debuginfo)
 - #69807 (Cleanup E0391 explanation)
 - #69820 (clean up E0392 explanation)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-03-08 19:54:57 +00:00
commit 2cb0b8582e
15 changed files with 152 additions and 72 deletions

View file

@ -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

View file

@ -612,6 +612,11 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
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<Tag> {
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()

View file

@ -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
))
}
})

View file

@ -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(

View file

@ -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(|| {

View file

@ -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`.

View file

@ -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<T> {

View file

@ -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!(

View file

@ -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<u16>.
/// Terminator 0x0000 is not included in the returned Vec<u16>.
///
/// Performs appropriate bounds checks.
pub fn read_wide_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, Vec<u16>> {
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.

View file

@ -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<RustcOptGroup> {
"",
"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,

View file

@ -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(

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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];