Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #91024

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
17ce56f
Fix Iterator::advance_by contract inconsistency
the8472 Oct 14, 2021
7272b6f
Make char conversion functions unstably const
est31 Sep 25, 2021
afd9dfa
bootstap: create .cargo/config only if not present
aplanas Nov 11, 2021
ddc1d58
windows: Return the "Not Found" error when a path is empty
JohnTitor Nov 16, 2021
483cff7
Add SourceMap::indentation_before.
m-ou-se Nov 4, 2021
453e242
Improve suggestion for unit Option/Result at the end of a block.
m-ou-se Nov 4, 2021
b331b66
Improve compatible enum variant suggestions.
m-ou-se Nov 4, 2021
4877756
Update tests.
m-ou-se Nov 4, 2021
5a25751
Add new tests for compatible variant diagnostics.
m-ou-se Nov 4, 2021
09e4a75
Use span_suggestions instead of multipart_suggestions.
m-ou-se Nov 4, 2021
b66fb64
Update test output.
m-ou-se Nov 16, 2021
5520737
Remove unnecessary lifetime argument from arena macros.
nnethercote Nov 15, 2021
f1aeebf
add const generics test
lcnr Nov 4, 2021
f5dc388
Point at source of trait bound obligations in more places
estebank Oct 5, 2021
3fe48b2
Change `trait_defs.rs` incremental hash test
estebank Oct 6, 2021
412793f
Point at bounds when comparing impl items to trait
estebank Oct 6, 2021
abf70a9
Do not mention associated items when they introduce an obligation
estebank Oct 12, 2021
a6b31eb
Align multiline messages to their label (add left margin)
estebank Oct 13, 2021
70e8240
Point at `impl` blocks when they introduce unmet obligations
estebank Oct 13, 2021
8d443ea
Suggest constraining `fn` type params when appropriate
estebank Oct 13, 2021
1cadfe6
Move tests for missing trait bounds to their own directory
estebank Oct 14, 2021
2c173af
review comments
estebank Nov 18, 2021
a8dcc87
Move tests from ui directory
estebank Nov 18, 2021
2f1a1f5
fix CTFE/Miri simd_insert/extract on array-style repr(simd) types
RalfJung Nov 18, 2021
0304e16
CTFE SIMD: also test 1-element array
RalfJung Nov 18, 2021
8ace192
bless nll
lcnr Nov 18, 2021
0a89598
Add some comments.
nnethercote Nov 15, 2021
0e39dca
Rollup merge of #89258 - est31:const_char_convert, r=oli-obk
matthiaskrgr Nov 18, 2021
da32a0f
Rollup merge of #89580 - estebank:trait-bounds-are-tricky, r=nagisa
matthiaskrgr Nov 18, 2021
79d3077
Rollup merge of #89916 - the8472:advance_by-avoid-err-0, r=dtolnay
matthiaskrgr Nov 18, 2021
281b65a
Rollup merge of #90575 - m-ou-se:compatible-variant-improvements, r=e…
matthiaskrgr Nov 18, 2021
439afef
Rollup merge of #90578 - lcnr:add-test, r=Mark-Simulacrum
matthiaskrgr Nov 18, 2021
2f371b0
Rollup merge of #90800 - aplanas:fix_cargo_config, r=Mark-Simulacrum
matthiaskrgr Nov 18, 2021
b9414a8
Rollup merge of #90942 - JohnTitor:should-os-error-3, r=m-ou-se
matthiaskrgr Nov 18, 2021
d1662ee
Rollup merge of #90990 - nnethercote:arenas-cleanup, r=oli-obk
matthiaskrgr Nov 18, 2021
7131806
Rollup merge of #90999 - RalfJung:miri_simd, r=oli-obk
matthiaskrgr Nov 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl<T> Default for TypedArena<T> {
// alloc() will trigger a grow().
ptr: Cell::new(ptr::null_mut()),
end: Cell::new(ptr::null_mut()),
chunks: RefCell::new(vec![]),
chunks: Default::default(),
_own: PhantomData,
}
}
Expand Down Expand Up @@ -325,13 +325,17 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {

unsafe impl<T: Send> Send for TypedArena<T> {}

/// An arena that can hold objects of multiple different types that impl `Copy`
/// and/or satisfy `!mem::needs_drop`.
pub struct DroplessArena {
/// A pointer to the start of the free space.
start: Cell<*mut u8>,

/// A pointer to the end of free space.
///
/// The allocation proceeds from the end of the chunk towards the start.
/// The allocation proceeds downwards from the end of the chunk towards the
/// start. (This is slightly simpler and faster than allocating upwards,
/// see <https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html>.)
/// When this pointer crosses the start pointer, a new chunk is allocated.
end: Cell<*mut u8>,

Expand Down Expand Up @@ -516,10 +520,14 @@ impl DroplessArena {
}
}

// Declare an `Arena` containing one dropless arena and many typed arenas (the
// types of the typed arenas are specified by the arguments). The dropless
// arena will be used for any types that impl `Copy`, and also for any of the
// specified types that satisfy `!mem::needs_drop`.
#[rustc_macro_transparency = "semitransparent"]
pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
#[derive(Default)]
pub struct Arena<$tcx> {
pub struct Arena<'tcx> {
pub dropless: $crate::DroplessArena,
$($name: $crate::TypedArena<$ty>,)*
}
Expand All @@ -532,6 +540,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
) -> &'a mut [Self];
}

// Any type that impls `Copy` can be arena-allocated in the `DroplessArena`.
impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T {
#[inline]
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
Expand All @@ -544,12 +553,11 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
) -> &'a mut [Self] {
arena.dropless.alloc_from_iter(iter)
}

}
$(
impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty {
impl<'tcx> ArenaAllocatable<'tcx, $ty> for $ty {
#[inline]
fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self {
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
if !::std::mem::needs_drop::<Self>() {
arena.dropless.alloc(self)
} else {
Expand All @@ -559,7 +567,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {

#[inline]
fn allocate_from_iter<'a>(
arena: &'a Arena<$tcx>,
arena: &'a Arena<'tcx>,
iter: impl ::std::iter::IntoIterator<Item = Self>,
) -> &'a mut [Self] {
if !::std::mem::needs_drop::<Self>() {
Expand All @@ -577,6 +585,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
value.allocate_on(self)
}

// Any type that impls `Copy` can have slices be arena-allocated in the `DroplessArena`.
#[inline]
pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] {
if value.is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ mod item;
mod pat;
mod path;

rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx);
rustc_hir::arena_types!(rustc_arena::declare_arena);

struct LoweringContext<'a, 'hir: 'a> {
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
Expand Down
47 changes: 16 additions & 31 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,48 +413,33 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::simd_insert => {
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
let elem = &args[2];
let input = &args[0];
let (len, e_ty) = input.layout.ty.simd_size_and_type(*self.tcx);
let (input, input_len) = self.operand_to_simd(&args[0])?;
let (dest, dest_len) = self.place_to_simd(dest)?;
assert_eq!(input_len, dest_len, "Return vector length must match input length");
assert!(
index < len,
"Index `{}` must be in bounds of vector type `{}`: `[0, {})`",
index < dest_len,
"Index `{}` must be in bounds of vector with length {}`",
index,
e_ty,
len
);
assert_eq!(
input.layout, dest.layout,
"Return type `{}` must match vector type `{}`",
dest.layout.ty, input.layout.ty
);
assert_eq!(
elem.layout.ty, e_ty,
"Scalar element type `{}` must match vector element type `{}`",
elem.layout.ty, e_ty
dest_len
);

for i in 0..len {
let place = self.place_index(dest, i)?;
let value = if i == index { *elem } else { self.operand_index(input, i)? };
self.copy_op(&value, &place)?;
for i in 0..dest_len {
let place = self.mplace_index(&dest, i)?;
let value =
if i == index { *elem } else { self.mplace_index(&input, i)?.into() };
self.copy_op(&value, &place.into())?;
}
}
sym::simd_extract => {
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
let (len, e_ty) = args[0].layout.ty.simd_size_and_type(*self.tcx);
let (input, input_len) = self.operand_to_simd(&args[0])?;
assert!(
index < len,
"index `{}` is out-of-bounds of vector type `{}` with length `{}`",
index < input_len,
"index `{}` must be in bounds of vector with length `{}`",
index,
e_ty,
len
);
assert_eq!(
e_ty, dest.layout.ty,
"Return type `{}` must match vector element type `{}`",
dest.layout.ty, e_ty
input_len
);
self.copy_op(&self.operand_index(&args[0], index)?, dest)?;
self.copy_op(&self.mplace_index(&input, index)?.into(), dest)?;
}
sym::likely | sym::unlikely | sym::black_box => {
// These just return their argument
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
})
}

/// Converts a repr(simd) operand into an operand where `place_index` accesses the SIMD elements.
/// Also returns the number of elements.
pub fn operand_to_simd(
&self,
base: &OpTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
// Basically we just transmute this place into an array following simd_size_and_type.
// This only works in memory, but repr(simd) types should never be immediates anyway.
assert!(base.layout.ty.is_simd());
self.mplace_to_simd(&base.assert_mem_place())
}

/// Read from a local. Will not actually access the local if reading from a ZST.
/// Will not access memory, instead an indirect `Operand` is returned.
///
Expand Down
28 changes: 27 additions & 1 deletion compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
}
} else {
// Go through the layout. There are lots of types that support a length,
// e.g., SIMD types.
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
match self.layout.fields {
FieldsShape::Array { count, .. } => Ok(count),
_ => bug!("len not supported on sized type {:?}", self.layout.ty),
Expand Down Expand Up @@ -533,6 +533,22 @@ where
})
}

/// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
/// Also returns the number of elements.
pub fn mplace_to_simd(
&self,
base: &MPlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
// Basically we just transmute this place into an array following simd_size_and_type.
// (Transmuting is okay since this is an in-memory place. We also double-check the size
// stays the same.)
let (len, e_ty) = base.layout.ty.simd_size_and_type(*self.tcx);
let array = self.tcx.mk_array(e_ty, len);
let layout = self.layout_of(array)?;
assert_eq!(layout.size, base.layout.size);
Ok((MPlaceTy { layout, ..*base }, len))
}

/// Gets the place of a field inside the place, and also the field's type.
/// Just a convenience function, but used quite a bit.
/// This is the only projection that might have a side-effect: We cannot project
Expand Down Expand Up @@ -594,6 +610,16 @@ where
})
}

/// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
/// Also returns the number of elements.
pub fn place_to_simd(
&mut self,
base: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
let mplace = self.force_allocation(base)?;
self.mplace_to_simd(&mplace)
}

/// Computes a place. You should only use this if you intend to write into this
/// place; for reading, a more efficient alternative is `eval_place_for_read`.
pub fn eval_place(
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,22 +1266,37 @@ impl EmitterWriter {
}
self.msg_to_buffer(&mut buffer, msg, max_line_num_len, "note", None);
} else {
let mut label_width = 0;
// The failure note level itself does not provide any useful diagnostic information
if *level != Level::FailureNote {
buffer.append(0, level.to_str(), Style::Level(*level));
label_width += level.to_str().len();
}
// only render error codes, not lint codes
if let Some(DiagnosticId::Error(ref code)) = *code {
buffer.append(0, "[", Style::Level(*level));
buffer.append(0, &code, Style::Level(*level));
buffer.append(0, "]", Style::Level(*level));
label_width += 2 + code.len();
}
let header_style = if is_secondary { Style::HeaderMsg } else { Style::MainHeaderMsg };
if *level != Level::FailureNote {
buffer.append(0, ": ", header_style);
label_width += 2;
}
for &(ref text, _) in msg.iter() {
buffer.append(0, &replace_tabs(text), header_style);
// Account for newlines to align output to its label.
for (line, text) in replace_tabs(text).lines().enumerate() {
buffer.append(
0 + line,
&format!(
"{}{}",
if line == 0 { String::new() } else { " ".repeat(label_width) },
text
),
header_style,
);
}
}
}

Expand Down
76 changes: 38 additions & 38 deletions compiler/rustc_hir/src/arena.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,52 @@
/// This declares a list of types which can be allocated by `Arena`.
/// This higher-order macro declares a list of types which can be allocated by `Arena`.
///
/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`,
/// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro.
#[macro_export]
macro_rules! arena_types {
($macro:path, $tcx:lifetime) => (
($macro:path) => (
$macro!([
// HIR types
[] hir_krate: rustc_hir::Crate<$tcx>,
[] arm: rustc_hir::Arm<$tcx>,
[] asm_operand: (rustc_hir::InlineAsmOperand<$tcx>, Span),
[] hir_krate: rustc_hir::Crate<'tcx>,
[] arm: rustc_hir::Arm<'tcx>,
[] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, Span),
[] asm_template: rustc_ast::InlineAsmTemplatePiece,
[] attribute: rustc_ast::Attribute,
[] block: rustc_hir::Block<$tcx>,
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
[] body: rustc_hir::Body<$tcx>,
[] generic_arg: rustc_hir::GenericArg<$tcx>,
[] generic_args: rustc_hir::GenericArgs<$tcx>,
[] generic_bound: rustc_hir::GenericBound<$tcx>,
[] generic_param: rustc_hir::GenericParam<$tcx>,
[] expr: rustc_hir::Expr<$tcx>,
[] expr_field: rustc_hir::ExprField<$tcx>,
[] pat_field: rustc_hir::PatField<$tcx>,
[] fn_decl: rustc_hir::FnDecl<$tcx>,
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
[] block: rustc_hir::Block<'tcx>,
[] bare_fn_ty: rustc_hir::BareFnTy<'tcx>,
[] body: rustc_hir::Body<'tcx>,
[] generic_arg: rustc_hir::GenericArg<'tcx>,
[] generic_args: rustc_hir::GenericArgs<'tcx>,
[] generic_bound: rustc_hir::GenericBound<'tcx>,
[] generic_param: rustc_hir::GenericParam<'tcx>,
[] expr: rustc_hir::Expr<'tcx>,
[] expr_field: rustc_hir::ExprField<'tcx>,
[] pat_field: rustc_hir::PatField<'tcx>,
[] fn_decl: rustc_hir::FnDecl<'tcx>,
[] foreign_item: rustc_hir::ForeignItem<'tcx>,
[] foreign_item_ref: rustc_hir::ForeignItemRef,
[] impl_item: rustc_hir::ImplItem<$tcx>,
[] impl_item: rustc_hir::ImplItem<'tcx>,
[] impl_item_ref: rustc_hir::ImplItemRef,
[] item: rustc_hir::Item<$tcx>,
[] inline_asm: rustc_hir::InlineAsm<$tcx>,
[] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
[] local: rustc_hir::Local<$tcx>,
[] mod_: rustc_hir::Mod<$tcx>,
[] owner_info: rustc_hir::OwnerInfo<$tcx>,
[] param: rustc_hir::Param<$tcx>,
[] pat: rustc_hir::Pat<$tcx>,
[] path: rustc_hir::Path<$tcx>,
[] path_segment: rustc_hir::PathSegment<$tcx>,
[] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
[] qpath: rustc_hir::QPath<$tcx>,
[] stmt: rustc_hir::Stmt<$tcx>,
[] field_def: rustc_hir::FieldDef<$tcx>,
[] trait_item: rustc_hir::TraitItem<$tcx>,
[] item: rustc_hir::Item<'tcx>,
[] inline_asm: rustc_hir::InlineAsm<'tcx>,
[] llvm_inline_asm: rustc_hir::LlvmInlineAsm<'tcx>,
[] local: rustc_hir::Local<'tcx>,
[] mod_: rustc_hir::Mod<'tcx>,
[] owner_info: rustc_hir::OwnerInfo<'tcx>,
[] param: rustc_hir::Param<'tcx>,
[] pat: rustc_hir::Pat<'tcx>,
[] path: rustc_hir::Path<'tcx>,
[] path_segment: rustc_hir::PathSegment<'tcx>,
[] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>,
[] qpath: rustc_hir::QPath<'tcx>,
[] stmt: rustc_hir::Stmt<'tcx>,
[] field_def: rustc_hir::FieldDef<'tcx>,
[] trait_item: rustc_hir::TraitItem<'tcx>,
[] trait_item_ref: rustc_hir::TraitItemRef,
[] ty: rustc_hir::Ty<$tcx>,
[] type_binding: rustc_hir::TypeBinding<$tcx>,
[] variant: rustc_hir::Variant<$tcx>,
[] where_predicate: rustc_hir::WherePredicate<$tcx>,
], $tcx);
[] ty: rustc_hir::Ty<'tcx>,
[] type_binding: rustc_hir::TypeBinding<'tcx>,
[] variant: rustc_hir::Variant<'tcx>,
[] where_predicate: rustc_hir::WherePredicate<'tcx>,
]);
)
}
15 changes: 12 additions & 3 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,10 +2113,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
None
},
self.tcx.generics_of(owner.to_def_id()),
hir.span(hir_id),
)
});

let span = match generics {
// This is to get around the trait identity obligation, that has a `DUMMY_SP` as signal
// for other diagnostics, so we need to recover it here.
Some((_, _, node)) if span.is_dummy() => node,
_ => span,
};

let type_param_span = match (generics, bound_kind) {
(Some((_, ref generics)), GenericKind::Param(ref param)) => {
(Some((_, ref generics, _)), GenericKind::Param(ref param)) => {
// Account for the case where `param` corresponds to `Self`,
// which doesn't have the expected type argument.
if !(generics.has_self && param.index == 0) {
Expand Down Expand Up @@ -2153,7 +2162,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};
let new_lt = generics
.as_ref()
.and_then(|(parent_g, g)| {
.and_then(|(parent_g, g, _)| {
let mut possible = (b'a'..=b'z').map(|c| format!("'{}", c as char));
let mut lts_names = g
.params
Expand All @@ -2175,7 +2184,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.unwrap_or("'lt".to_string());
let add_lt_sugg = generics
.as_ref()
.and_then(|(_, g)| g.params.first())
.and_then(|(_, g, _)| g.params.first())
.and_then(|param| param.def_id.as_local())
.map(|def_id| {
(
Expand Down
Loading