From 1a605a6bda22750a1be9e21b988345f343260bb6 Mon Sep 17 00:00:00 2001 From: Vasya Novikov Date: Fri, 28 Sep 2018 19:36:53 +0300 Subject: [PATCH 01/38] fix std::thread::sleep typo --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 3987ae83866e5..ec9f20def7dd0 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -657,7 +657,7 @@ pub fn panicking() -> bool { /// /// # Platform-specific behavior /// -/// On Unix platforms this function will not return early due to a +/// On Unix platforms this function might return early due to a /// signal being received or a spurious wakeup. /// /// # Examples From 049ccbb174552bac2f19df5361c3470828bf04c4 Mon Sep 17 00:00:00 2001 From: Vasya Novikov Date: Fri, 28 Sep 2018 22:40:20 +0300 Subject: [PATCH 02/38] update wording for std::thread::sleep --- src/libstd/thread/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index ec9f20def7dd0..96ce38d12e196 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -650,15 +650,15 @@ pub fn panicking() -> bool { panicking::panicking() } -/// Puts the current thread to sleep for the specified amount of time. +/// Puts the current thread to sleep for at least the specified amount of time. /// /// The thread may sleep longer than the duration specified due to scheduling -/// specifics or platform-dependent functionality. +/// specifics or platform-dependent functionality. It will never sleep less. /// /// # Platform-specific behavior /// -/// On Unix platforms this function might return early due to a -/// signal being received or a spurious wakeup. +/// On Unix platforms this function may invoke multiple syscalls +/// in case of a signal being received or a spurious wakeup. /// /// # Examples /// From b63517a2c3bade20ebfbbd328b11ecf9a1558bd2 Mon Sep 17 00:00:00 2001 From: Vasya Novikov Date: Mon, 1 Oct 2018 11:01:15 +0300 Subject: [PATCH 03/38] update wording for thread::sleep --- src/libstd/thread/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 96ce38d12e196..70a9532665805 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -674,17 +674,17 @@ pub fn sleep_ms(ms: u32) { sleep(Duration::from_millis(ms as u64)) } -/// Puts the current thread to sleep for the specified amount of time. +/// Puts the current thread to sleep for at least the specified amount of time. /// /// The thread may sleep longer than the duration specified due to scheduling -/// specifics or platform-dependent functionality. +/// specifics or platform-dependent functionality. It will never sleep less. /// /// # Platform-specific behavior /// -/// On Unix platforms this function will not return early due to a -/// signal being received or a spurious wakeup. Platforms which do not support -/// nanosecond precision for sleeping will have `dur` rounded up to the nearest -/// granularity of time they can sleep for. +/// On Unix platforms this function may invoke multiple syscalls +/// in case of a signal being received or a spurious wakeup. +/// Platforms which do not support nanosecond precision for sleeping will +/// have `dur` rounded up to the nearest granularity of time they can sleep for. /// /// # Examples /// From 8efd9dd81bbcc0a39857a9f4de90860d799d2dfd Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 9 Oct 2018 15:13:11 +0200 Subject: [PATCH 04/38] codegen_llvm/misc: whitespace & formatting improvements --- .../debuginfo/metadata.rs | 30 ++++++------- .../debuginfo/type_names.rs | 2 +- src/librustc_codegen_llvm/mir/analyze.rs | 6 +-- src/librustc_codegen_llvm/mir/block.rs | 45 ++++++++++--------- src/librustc_codegen_llvm/mir/mod.rs | 8 ++-- 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 706568b544661..c90dd53aa3582 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -582,12 +582,12 @@ pub fn type_metadata( } ty::Dynamic(..) => { MetadataCreationResult::new( - trait_pointer_metadata(cx, t, None, unique_type_id), - false) + trait_pointer_metadata(cx, t, None, unique_type_id), + false) } ty::Foreign(..) => { MetadataCreationResult::new( - foreign_type_metadata(cx, t, unique_type_id), + foreign_type_metadata(cx, t, unique_type_id), false) } ty::RawPtr(ty::TypeAndMut{ty, ..}) | @@ -646,16 +646,16 @@ pub fn type_metadata( } AdtKind::Union => { prepare_union_metadata(cx, - t, - unique_type_id, - usage_site_span).finalize(cx) + t, + unique_type_id, + usage_site_span).finalize(cx) } AdtKind::Enum => { prepare_enum_metadata(cx, - t, - def.did, - unique_type_id, - usage_site_span).finalize(cx) + t, + def.did, + unique_type_id, + usage_site_span).finalize(cx) } }, ty::Tuple(ref elements) => { @@ -943,7 +943,7 @@ enum MemberDescriptionFactory<'ll, 'tcx> { impl MemberDescriptionFactory<'ll, 'tcx> { fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) - -> Vec> { + -> Vec> { match *self { StructMDF(ref this) => { this.create_member_descriptions(cx) @@ -977,7 +977,7 @@ struct StructMemberDescriptionFactory<'tcx> { impl<'tcx> StructMemberDescriptionFactory<'tcx> { fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) - -> Vec> { + -> Vec> { let layout = cx.layout_of(self.ty); self.variant.fields.iter().enumerate().map(|(i, f)| { let name = if self.variant.ctor_kind == CtorKind::Fn { @@ -1047,7 +1047,7 @@ struct TupleMemberDescriptionFactory<'tcx> { impl<'tcx> TupleMemberDescriptionFactory<'tcx> { fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) - -> Vec> { + -> Vec> { let layout = cx.layout_of(self.ty); self.component_types.iter().enumerate().map(|(i, &component_type)| { let (size, align) = cx.size_and_align_of(component_type); @@ -1101,7 +1101,7 @@ struct UnionMemberDescriptionFactory<'tcx> { impl<'tcx> UnionMemberDescriptionFactory<'tcx> { fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) - -> Vec> { + -> Vec> { self.variant.fields.iter().enumerate().map(|(i, f)| { let field = self.layout.field(cx, i); let (size, align) = field.size_and_align(); @@ -1170,7 +1170,7 @@ struct EnumMemberDescriptionFactory<'ll, 'tcx> { impl EnumMemberDescriptionFactory<'ll, 'tcx> { fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) - -> Vec> { + -> Vec> { let adt = &self.enum_type.ty_adt_def().unwrap(); match self.layout.variants { layout::Variants::Single { .. } if adt.variants.is_empty() => vec![], diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs index 2f110fd552a8d..68b1f0c33d065 100644 --- a/src/librustc_codegen_llvm/debuginfo/type_names.rs +++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs @@ -179,7 +179,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::GeneratorWitness(..) | ty::Param(_) => { bug!("debuginfo: Trying to create type name for \ - unexpected type: {:?}", t); + unexpected type: {:?}", t); } } diff --git a/src/librustc_codegen_llvm/mir/analyze.rs b/src/librustc_codegen_llvm/mir/analyze.rs index c3e3785a724a2..a0d6cc4629589 100644 --- a/src/librustc_codegen_llvm/mir/analyze.rs +++ b/src/librustc_codegen_llvm/mir/analyze.rs @@ -151,9 +151,9 @@ impl Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'll, 'tcx> { } fn visit_place(&mut self, - place: &mir::Place<'tcx>, - context: PlaceContext<'tcx>, - location: Location) { + place: &mir::Place<'tcx>, + context: PlaceContext<'tcx>, + location: Location) { debug!("visit_place(place={:?}, context={:?})", place, context); let cx = self.fx.cx; diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index db95b46c38ebe..68e30227185c0 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -49,9 +49,9 @@ impl FunctionCx<'a, 'll, 'tcx> { } fn codegen_terminator(&mut self, - mut bx: Builder<'a, 'll, 'tcx>, - bb: mir::BasicBlock, - terminator: &mir::Terminator<'tcx>) + mut bx: Builder<'a, 'll, 'tcx>, + bb: mir::BasicBlock, + terminator: &mir::Terminator<'tcx>) { debug!("codegen_terminator: {:?}", terminator); @@ -125,10 +125,10 @@ impl FunctionCx<'a, 'll, 'tcx> { this.unreachable_block() }; let invokeret = bx.invoke(fn_ptr, - &llargs, - ret_bx, - llblock(this, cleanup), - cleanup_bundle); + &llargs, + ret_bx, + llblock(this, cleanup), + cleanup_bundle); fn_ty.apply_attrs_callsite(&bx, invokeret); if let Some((ret_dest, target)) = destination { @@ -213,7 +213,8 @@ impl FunctionCx<'a, 'll, 'tcx> { } else { let (otherwise, targets) = targets.split_last().unwrap(); let switch = bx.switch(discr.immediate(), - llblock(self, *otherwise), values.len()); + llblock(self, *otherwise), + values.len()); let switch_llty = bx.cx.layout_of(switch_ty).immediate_llvm_type(bx.cx); for (&value, target) in values.iter().zip(targets) { let llval = C_uint_big(switch_llty, value); @@ -387,8 +388,8 @@ impl FunctionCx<'a, 'll, 'tcx> { let msg_str = Symbol::intern(str).as_str(); let msg_str = C_str_slice(bx.cx, msg_str); let msg_file_line_col = C_struct(bx.cx, - &[msg_str, filename, line, col], - false); + &[msg_str, filename, line, col], + false); let msg_file_line_col = consts::addr_of(bx.cx, msg_file_line_col, align, @@ -509,8 +510,8 @@ impl FunctionCx<'a, 'll, 'tcx> { let msg_str = Symbol::intern(&str).as_str(); let msg_str = C_str_slice(bx.cx, msg_str); let msg_file_line_col = C_struct(bx.cx, - &[msg_str, filename, line, col], - false); + &[msg_str, filename, line, col], + false); let msg_file_line_col = consts::addr_of(bx.cx, msg_file_line_col, align, @@ -619,7 +620,7 @@ impl FunctionCx<'a, 'll, 'tcx> { let callee_ty = instance.as_ref().unwrap().ty(bx.cx.tcx); codegen_intrinsic_call(&bx, callee_ty, &fn_ty, &args, dest, - terminator.source_info.span); + terminator.source_info.span); if let ReturnDest::IndirectOperand(dst, _) = ret_dest { self.store_return(&bx, ret_dest, &fn_ty.ret, dst.llval); @@ -756,7 +757,7 @@ impl FunctionCx<'a, 'll, 'tcx> { // Have to load the argument, maybe while casting it. if let PassMode::Cast(ty) = arg.mode { llval = bx.load(bx.pointercast(llval, ty.llvm_type(bx.cx).ptr_to()), - align.min(arg.layout.align)); + align.min(arg.layout.align)); } else { // We can't use `PlaceRef::load` here because the argument // may have a type we don't treat as immediate, but the ABI @@ -778,10 +779,10 @@ impl FunctionCx<'a, 'll, 'tcx> { } fn codegen_arguments_untupled(&mut self, - bx: &Builder<'a, 'll, 'tcx>, - operand: &mir::Operand<'tcx>, - llargs: &mut Vec<&'ll Value>, - args: &[ArgType<'tcx, Ty<'tcx>>]) { + bx: &Builder<'a, 'll, 'tcx>, + operand: &mir::Operand<'tcx>, + llargs: &mut Vec<&'ll Value>, + args: &[ArgType<'tcx, Ty<'tcx>>]) { let tuple = self.codegen_operand(bx, operand); // Handle both by-ref and immediate tuples. @@ -933,8 +934,8 @@ impl FunctionCx<'a, 'll, 'tcx> { } fn codegen_transmute(&mut self, bx: &Builder<'a, 'll, 'tcx>, - src: &mir::Operand<'tcx>, - dst: &mir::Place<'tcx>) { + src: &mir::Operand<'tcx>, + dst: &mir::Place<'tcx>) { if let mir::Place::Local(index) = *dst { match self.locals[index] { LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place), @@ -961,8 +962,8 @@ impl FunctionCx<'a, 'll, 'tcx> { } fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>, - src: &mir::Operand<'tcx>, - dst: PlaceRef<'ll, 'tcx>) { + src: &mir::Operand<'tcx>, + dst: PlaceRef<'ll, 'tcx>) { let src = self.codegen_operand(bx, src); let llty = src.layout.llvm_type(bx.cx); let cast_ptr = bx.pointercast(dst.llval, llty.ptr_to()); diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index c61a326e7c839..a6e2ccf92e4e3 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -162,16 +162,16 @@ impl FunctionCx<'a, 'll, 'tcx> { // corresponding to span's containing source scope. If so, we need to create a DIScope // "extension" into that file. fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos) - -> Option<&'ll DIScope> { + -> Option<&'ll DIScope> { let scope_metadata = self.scopes[scope_id].scope_metadata; if pos < self.scopes[scope_id].file_start_pos || pos >= self.scopes[scope_id].file_end_pos { let cm = self.cx.sess().source_map(); let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate; Some(debuginfo::extend_scope_to_file(self.cx, - scope_metadata.unwrap(), - &cm.lookup_char_pos(pos).file, - defining_crate)) + scope_metadata.unwrap(), + &cm.lookup_char_pos(pos).file, + defining_crate)) } else { scope_metadata } From e90e8aaeba102760b9a8b4237b37085f50b6f573 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 9 Oct 2018 15:14:38 +0200 Subject: [PATCH 05/38] codegen_llvm/misc: remove explicit returns --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 6 +++--- src/librustc_codegen_llvm/debuginfo/mod.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index c90dd53aa3582..34e770c845cd1 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1551,7 +1551,7 @@ fn composite_type_metadata( composite_type_metadata, member_descriptions); - return composite_type_metadata; + composite_type_metadata } fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>, @@ -1639,7 +1639,7 @@ fn create_struct_stub( unique_type_id.as_ptr()) }; - return metadata_stub; + metadata_stub } fn create_union_stub( @@ -1675,7 +1675,7 @@ fn create_union_stub( unique_type_id.as_ptr()) }; - return metadata_stub; + metadata_stub } /// Creates debug information for the given global variable. diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 7b0c413e85761..417b34cef4c34 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -371,7 +371,7 @@ pub fn create_function_debug_context( } } - return create_DIArray(DIB(cx), &signature[..]); + create_DIArray(DIB(cx), &signature[..]) } fn get_template_parameters( @@ -428,7 +428,7 @@ pub fn create_function_debug_context( vec![] }; - return create_DIArray(DIB(cx), &template_params[..]); + create_DIArray(DIB(cx), &template_params[..]) } fn get_parameter_names(cx: &CodegenCx, From b07a2d02cac099de28f00cc6422154d41c870eac Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 9 Oct 2018 15:15:41 +0200 Subject: [PATCH 06/38] codegen_llvm/misc: improve common patterns --- .../debuginfo/create_scope_map.rs | 2 +- .../debuginfo/metadata.rs | 47 +++++++++---------- src/librustc_codegen_llvm/debuginfo/mod.rs | 14 +++--- .../debuginfo/source_loc.rs | 7 +-- 4 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index 0484837a48d7d..56352ae963f20 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -37,7 +37,7 @@ pub struct MirDebugScope<'ll> { impl MirDebugScope<'ll> { pub fn is_valid(&self) -> bool { - !self.scope_metadata.is_none() + self.scope_metadata.is_some() } } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 34e770c845cd1..5383d5fbebe89 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -163,10 +163,10 @@ impl TypeMap<'ll, 'tcx> { fn get_unique_type_id_of_type<'a>(&mut self, cx: &CodegenCx<'a, 'tcx>, type_: Ty<'tcx>) -> UniqueTypeId { // Let's see if we already have something in the cache - match self.type_to_unique_id.get(&type_).cloned() { - Some(unique_type_id) => return unique_type_id, - None => { /* generate one */} - }; + if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() { + return unique_type_id + } + // if not, generate one // The hasher we are using to generate the UniqueTypeId. We want // something that provides more than the 64 bits of the DefaultHasher. @@ -286,11 +286,11 @@ impl RecursiveTypeDescription<'ll, 'tcx> { // unique id can be found in the type map macro_rules! return_if_metadata_created_in_meantime { ($cx: expr, $unique_type_id: expr) => ( - match debug_context($cx).type_map - .borrow() - .find_metadata_for_unique_id($unique_type_id) { - Some(metadata) => return MetadataCreationResult::new(metadata, true), - None => { /* proceed normally */ } + if let Some(metadata) = debug_context($cx).type_map + .borrow() + .find_metadata_for_unique_id($unique_type_id) + { + return MetadataCreationResult::new(metadata, true) } ) } @@ -548,12 +548,12 @@ pub fn type_metadata( _ => { let pointee_metadata = type_metadata(cx, ty, usage_site_span); - match debug_context(cx).type_map - .borrow() - .find_metadata_for_unique_id(unique_type_id) { - Some(metadata) => return Err(metadata), - None => { /* proceed normally */ } - }; + if let Some(metadata) = debug_context(cx).type_map + .borrow() + .find_metadata_for_unique_id(unique_type_id) + { + return Err(metadata) + } Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata), false)) @@ -608,12 +608,12 @@ pub fn type_metadata( unique_type_id, t.fn_sig(cx.tcx), usage_site_span).metadata; - match debug_context(cx).type_map - .borrow() - .find_metadata_for_unique_id(unique_type_id) { - Some(metadata) => return metadata, - None => { /* proceed normally */ } - }; + if let Some(metadata) = debug_context(cx).type_map + .borrow() + .find_metadata_for_unique_id(unique_type_id) + { + return metadata + } // This is actually a function pointer, so wrap it in pointer DI MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false) @@ -1476,9 +1476,8 @@ fn prepare_enum_metadata( } }; - match (&layout.abi, discriminant_type_metadata) { - (&layout::Abi::Scalar(_), Some(discr)) => return FinalMetadata(discr), - _ => {} + if let (&layout::Abi::Scalar(_), Some(discr)) = (&layout.abi, discriminant_type_metadata) { + return FinalMetadata(discr) } let (enum_type_size, enum_type_align) = layout.size_and_align(); diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 417b34cef4c34..acb79d6f568cc 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -271,16 +271,14 @@ pub fn create_function_debug_context( let mut flags = DIFlags::FlagPrototyped; let local_id = cx.tcx.hir.as_local_node_id(def_id); - match *cx.sess().entry_fn.borrow() { - Some((id, _, _)) => { - if local_id == Some(id) { - flags = flags | DIFlags::FlagMainSubprogram; - } + if let Some((id, _, _)) = *cx.sess().entry_fn.borrow() { + if local_id == Some(id) { + flags |= DIFlags::FlagMainSubprogram; } - None => {} - }; + } + if cx.layout_of(sig.output()).abi.is_uninhabited() { - flags = flags | DIFlags::FlagNoReturn; + flags |= DIFlags::FlagNoReturn; } let fn_metadata = unsafe { diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index c59b5e2b8f5f5..405cffdefa285 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -56,11 +56,8 @@ pub fn set_source_location( /// switches source location emitting on and must therefore be called before the /// first real statement/expression of the function is codegened. pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext<'ll>) { - match *dbg_context { - FunctionDebugContext::RegularContext(ref data) => { - data.source_locations_enabled.set(true) - }, - _ => { /* safe to ignore */ } + if let FunctionDebugContext::RegularContext(ref data) = *dbg_context { + data.source_locations_enabled.set(true) } } From fa81576023ef0538608b62f5bf343ff9caf1163b Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 9 Oct 2018 15:16:20 +0200 Subject: [PATCH 07/38] codegen_llvm/misc: convert string literals with to_owned --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 10 +++++----- src/librustc_codegen_llvm/llvm/archive_ro.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 5383d5fbebe89..6dcca65a73601 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -352,7 +352,7 @@ fn vec_slice_metadata( let member_descriptions = vec![ MemberDescription { - name: "data_ptr".to_string(), + name: "data_ptr".to_owned(), type_metadata: data_ptr_metadata, offset: Size::ZERO, size: pointer_size, @@ -360,7 +360,7 @@ fn vec_slice_metadata( flags: DIFlags::FlagZero, }, MemberDescription { - name: "length".to_string(), + name: "length".to_owned(), type_metadata: type_metadata(cx, cx.tcx.types.usize, span), offset: pointer_size, size: usize_size, @@ -463,7 +463,7 @@ fn trait_pointer_metadata( let vtable_field = layout.field(cx, 1); let member_descriptions = vec![ MemberDescription { - name: "pointer".to_string(), + name: "pointer".to_owned(), type_metadata: type_metadata(cx, cx.tcx.mk_mut_ptr(cx.tcx.types.u8), syntax_pos::DUMMY_SP), @@ -473,7 +473,7 @@ fn trait_pointer_metadata( flags: DIFlags::FlagArtificial, }, MemberDescription { - name: "vtable".to_string(), + name: "vtable".to_owned(), type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP), offset: layout.fields.offset(1), size: vtable_field.size, @@ -1362,7 +1362,7 @@ fn describe_enum_variant( // We have the layout of an enum variant, we need the layout of the outer enum let enum_layout = cx.layout_of(layout.ty); (Some(enum_layout.fields.offset(0)), - Some(("RUST$ENUM$DISR".to_string(), enum_layout.field(cx, 0).ty))) + Some(("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, 0).ty))) } _ => (None, None), }; diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 4cbf0d92d7b99..e0a9f31e508ba 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -40,7 +40,7 @@ impl ArchiveRO { return unsafe { let s = path2cstr(dst); let ar = super::LLVMRustOpenArchive(s.as_ptr()).ok_or_else(|| { - super::last_error().unwrap_or("failed to open archive".to_string()) + super::last_error().unwrap_or("failed to open archive".to_owned()) })?; Ok(ArchiveRO { raw: ar }) }; From ac66b04ccb04e264004189970c817eb3da208f4a Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 3 Oct 2018 10:01:56 -0600 Subject: [PATCH 08/38] Run both lldb and gdb tests Currently lldb tests are run only on macOS, and gdb tests are only run elsewhere. This patch changes this to run tests depending on what is available. One test is changed, as it was previously marked as failing on macOS, whereas really it is a generic failure with lldb. Closes #54721 --- src/bootstrap/test.rs | 20 +-- .../debuginfo/lexical-scope-with-macro.rs | 2 +- src/tools/compiletest/src/common.rs | 3 + src/tools/compiletest/src/header.rs | 157 +++++++++++++++--- src/tools/compiletest/src/main.rs | 34 +++- src/tools/compiletest/src/runtest.rs | 29 ++-- 6 files changed, 183 insertions(+), 62 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 633c15b54b9ef..80c89b9ff3826 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -812,8 +812,7 @@ default_test!(Incremental { default_test!(Debuginfo { path: "src/test/debuginfo", - // What this runs varies depending on the native platform being apple - mode: "debuginfo-XXX", + mode: "debuginfo", suite: "debuginfo" }); @@ -950,18 +949,11 @@ impl Step for Compiletest { return; } - if mode == "debuginfo-XXX" { - return if builder.config.build.contains("apple") { - builder.ensure(Compiletest { - mode: "debuginfo-lldb", - ..self - }); - } else { - builder.ensure(Compiletest { - mode: "debuginfo-gdb", - ..self - }); - }; + if mode == "debuginfo" { + return builder.ensure(Compiletest { + mode: "debuginfo-both", + ..self + }); } builder.ensure(dist::DebuggerScripts { diff --git a/src/test/debuginfo/lexical-scope-with-macro.rs b/src/test/debuginfo/lexical-scope-with-macro.rs index 4e88f65ad1d00..d11a42bb0ed13 100644 --- a/src/test/debuginfo/lexical-scope-with-macro.rs +++ b/src/test/debuginfo/lexical-scope-with-macro.rs @@ -9,7 +9,7 @@ // except according to those terms. // min-lldb-version: 310 -// ignore-macos FIXME #48807 +// ignore-lldb FIXME #48807 // compile-flags:-g -Zdebug-macros diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 7006fb9427e1c..fab2ea7ba6c36 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -25,6 +25,7 @@ pub enum Mode { RunPass, RunPassValgrind, Pretty, + DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Codegen, @@ -60,6 +61,7 @@ impl FromStr for Mode { "run-pass" => Ok(RunPass), "run-pass-valgrind" => Ok(RunPassValgrind), "pretty" => Ok(Pretty), + "debuginfo-both" => Ok(DebugInfoBoth), "debuginfo-lldb" => Ok(DebugInfoLldb), "debuginfo-gdb" => Ok(DebugInfoGdb), "codegen" => Ok(Codegen), @@ -83,6 +85,7 @@ impl fmt::Display for Mode { RunPass => "run-pass", RunPassValgrind => "run-pass-valgrind", Pretty => "pretty", + DebugInfoBoth => "debuginfo-both", DebugInfoGdb => "debuginfo-gdb", DebugInfoLldb => "debuginfo-lldb", Codegen => "codegen", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 688f2babe6e8c..06eeef61a194d 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -19,10 +19,62 @@ use util; use extract_gdb_version; +/// Whether to ignore the test. +#[derive(Clone, Copy, PartialEq, Debug)] +pub enum Ignore { + /// Run it. + Run, + /// Ignore it totally. + Ignore, + /// Ignore only the gdb test, but run the lldb test. + IgnoreGdb, + /// Ignore only the lldb test, but run the gdb test. + IgnoreLldb, +} + +impl Ignore { + pub fn can_run_gdb(&self) -> bool { + *self == Ignore::Run || *self == Ignore::IgnoreLldb + } + + pub fn can_run_lldb(&self) -> bool { + *self == Ignore::Run || *self == Ignore::IgnoreGdb + } + + pub fn no_gdb(&self) -> Ignore { + match *self { + Ignore::Run => Ignore::IgnoreGdb, + Ignore::IgnoreGdb => Ignore::IgnoreGdb, + _ => Ignore::Ignore, + } + } + + pub fn no_lldb(&self) -> Ignore { + match *self { + Ignore::Run => Ignore::IgnoreLldb, + Ignore::IgnoreLldb => Ignore::IgnoreLldb, + _ => Ignore::Ignore, + } + } +} + +/// The result of parse_cfg_name_directive. +#[derive(Clone, Copy, PartialEq, Debug)] +enum ParsedNameDirective { + /// No match. + NoMatch, + /// Match. + Match, + /// Mode was DebugInfoBoth and this matched gdb. + MatchGdb, + /// Mode was DebugInfoBoth and this matched lldb. + MatchLldb, +} + /// Properties which must be known very early, before actually running /// the test. pub struct EarlyProps { - pub ignore: bool, + pub ignore: Ignore, pub should_fail: bool, pub aux: Vec, pub revisions: Vec, @@ -31,20 +83,55 @@ pub struct EarlyProps { impl EarlyProps { pub fn from_file(config: &Config, testfile: &Path) -> Self { let mut props = EarlyProps { - ignore: false, + ignore: Ignore::Run, should_fail: false, aux: Vec::new(), revisions: vec![], }; + if config.mode == common::DebugInfoBoth { + if config.lldb_python_dir.is_none() { + props.ignore = props.ignore.no_lldb(); + } + if config.gdb_version.is_none() { + props.ignore = props.ignore.no_gdb(); + } + } + iter_header(testfile, None, &mut |ln| { // we should check if any only- exists and if it exists // and does not matches the current platform, skip the test - props.ignore = props.ignore || config.parse_cfg_name_directive(ln, "ignore") - || (config.has_cfg_prefix(ln, "only") - && !config.parse_cfg_name_directive(ln, "only")) - || ignore_gdb(config, ln) || ignore_lldb(config, ln) - || ignore_llvm(config, ln); + if props.ignore != Ignore::Ignore { + props.ignore = match config.parse_cfg_name_directive(ln, "ignore") { + ParsedNameDirective::Match => Ignore::Ignore, + ParsedNameDirective::NoMatch => props.ignore, + ParsedNameDirective::MatchGdb => props.ignore.no_gdb(), + ParsedNameDirective::MatchLldb => props.ignore.no_lldb(), + }; + + if config.has_cfg_prefix(ln, "only") { + props.ignore = match config.parse_cfg_name_directive(ln, "only") { + ParsedNameDirective::Match => props.ignore, + ParsedNameDirective::NoMatch => Ignore::Ignore, + ParsedNameDirective::MatchLldb => props.ignore.no_gdb(), + ParsedNameDirective::MatchGdb => props.ignore.no_lldb(), + }; + } + + if ignore_llvm(config, ln) { + props.ignore = Ignore::Ignore; + } + } + + if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoBoth) && + props.ignore.can_run_gdb() && ignore_gdb(config, ln) { + props.ignore = props.ignore.no_gdb(); + } + + if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoBoth) && + props.ignore.can_run_lldb() && ignore_lldb(config, ln) { + props.ignore = props.ignore.no_lldb(); + } if let Some(s) = config.parse_aux_build(ln) { props.aux.push(s); @@ -60,10 +147,6 @@ impl EarlyProps { return props; fn ignore_gdb(config: &Config, line: &str) -> bool { - if config.mode != common::DebugInfoGdb { - return false; - } - if let Some(actual_version) = config.gdb_version { if line.starts_with("min-gdb-version") { let (start_ver, end_ver) = extract_gdb_version_range(line); @@ -120,10 +203,6 @@ impl EarlyProps { } fn ignore_lldb(config: &Config, line: &str) -> bool { - if config.mode != common::DebugInfoLldb { - return false; - } - if let Some(ref actual_version) = config.lldb_version { if line.starts_with("min-lldb-version") { let min_version = line.trim_right() @@ -604,7 +683,7 @@ impl Config { } fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> { - if self.parse_cfg_name_directive(line, prefix) { + if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match { let from = match parse_normalization_string(&mut line) { Some(s) => s, None => return None, @@ -620,35 +699,59 @@ impl Config { } /// Parses a name-value directive which contains config-specific information, e.g. `ignore-x86` - /// or `normalize-stderr-32bit`. Returns `true` if the line matches it. - fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> bool { + /// or `normalize-stderr-32bit`. + fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective { if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') { let name = line[prefix.len() + 1..] .split(&[':', ' '][..]) .next() .unwrap(); - name == "test" || + if name == "test" || util::matches_os(&self.target, name) || // target name == util::get_arch(&self.target) || // architecture name == util::get_pointer_width(&self.target) || // pointer width name == self.stage_id.split('-').next().unwrap() || // stage Some(name) == util::get_env(&self.target) || // env - match self.mode { - common::DebugInfoGdb => name == "gdb", - common::DebugInfoLldb => name == "lldb", - common::Pretty => name == "pretty", - _ => false, - } || (self.target != self.host && name == "cross-compile") || match self.compare_mode { Some(CompareMode::Nll) => name == "compare-mode-nll", Some(CompareMode::Polonius) => name == "compare-mode-polonius", None => false, } || - (cfg!(debug_assertions) && name == "debug") + (cfg!(debug_assertions) && name == "debug") { + ParsedNameDirective::Match + } else { + match self.mode { + common::DebugInfoBoth => { + if name == "gdb" { + ParsedNameDirective::MatchGdb + } else if name == "lldb" { + ParsedNameDirective::MatchLldb + } else { + ParsedNameDirective::NoMatch + } + }, + common::DebugInfoGdb => if name == "gdb" { + ParsedNameDirective::Match + } else { + ParsedNameDirective::NoMatch + }, + common::DebugInfoLldb => if name == "lldb" { + ParsedNameDirective::Match + } else { + ParsedNameDirective::NoMatch + }, + common::Pretty => if name == "pretty" { + ParsedNameDirective::Match + } else { + ParsedNameDirective::NoMatch + }, + _ => ParsedNameDirective::NoMatch, + } + } } else { - false + ParsedNameDirective::NoMatch } } diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index f46e031d768bd..c931d3c0e30b7 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -32,7 +32,7 @@ extern crate rustfix; use common::CompareMode; use common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS}; use common::{Config, TestPaths}; -use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; +use common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; use filetime::FileTime; use getopts::Options; use std::env; @@ -44,7 +44,7 @@ use std::process::Command; use test::ColorConfig; use util::logv; -use self::header::EarlyProps; +use self::header::{EarlyProps, Ignore}; pub mod common; pub mod errors; @@ -425,7 +425,7 @@ pub fn opt_str2(maybestr: Option) -> String { pub fn run_tests(config: &Config) { if config.target.contains("android") { - if let DebugInfoGdb = config.mode { + if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth { println!( "{} debug-info test uses tcp 5039 port.\ please reserve it", @@ -443,7 +443,9 @@ pub fn run_tests(config: &Config) { } match config.mode { - DebugInfoLldb => { + // Note that we don't need to emit the gdb warning when + // DebugInfoBoth, so it is ok to list that here. + DebugInfoBoth | DebugInfoLldb => { if let Some(lldb_version) = config.lldb_version.as_ref() { if is_blacklisted_lldb_version(&lldb_version[..]) { println!( @@ -647,15 +649,18 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec Vec, ) -> test::TestFn { - let config = config.clone(); + let mut config = config.clone(); + if config.mode == DebugInfoBoth { + // If both gdb and lldb were ignored, then the test as a whole + // would be ignored. + if !ignore.can_run_gdb() { + config.mode = DebugInfoLldb; + } else if !ignore.can_run_lldb() { + config.mode = DebugInfoGdb; + } + } + let testpaths = testpaths.clone(); let revision = revision.cloned(); test::DynTestFn(Box::new(move || { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 4cb6f6b83bdd1..153c9907b0c19 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -11,7 +11,7 @@ use common::CompareMode; use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT}; use common::{output_base_dir, output_base_name, output_testname_unique}; -use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc}; +use common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc}; use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind}; use common::{Config, TestPaths}; use common::{Incremental, MirOpt, RunMake, Ui}; @@ -225,19 +225,20 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) { pub fn compute_stamp_hash(config: &Config) -> String { let mut hash = DefaultHasher::new(); config.stage_id.hash(&mut hash); - match config.mode { - DebugInfoGdb => match config.gdb { + + if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth { + match config.gdb { None => env::var_os("PATH").hash(&mut hash), Some(ref s) if s.is_empty() => env::var_os("PATH").hash(&mut hash), Some(ref s) => s.hash(&mut hash), - }, - DebugInfoLldb => { - env::var_os("PATH").hash(&mut hash); - env::var_os("PYTHONPATH").hash(&mut hash); - }, + }; + } + + if config.mode == DebugInfoLldb || config.mode == DebugInfoBoth { + env::var_os("PATH").hash(&mut hash); + env::var_os("PYTHONPATH").hash(&mut hash); + } - _ => {}, - }; format!("{:x}", hash.finish()) } @@ -268,6 +269,10 @@ impl<'test> TestCx<'test> { RunFail => self.run_rfail_test(), RunPassValgrind => self.run_valgrind_test(), Pretty => self.run_pretty_test(), + DebugInfoBoth => { + self.run_debuginfo_gdb_test(); + self.run_debuginfo_lldb_test(); + }, DebugInfoGdb => self.run_debuginfo_gdb_test(), DebugInfoLldb => self.run_debuginfo_lldb_test(), Codegen => self.run_codegen_test(), @@ -640,6 +645,7 @@ impl<'test> TestCx<'test> { let config = Config { target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), + mode: DebugInfoGdb, ..self.config.clone() }; @@ -910,6 +916,7 @@ impl<'test> TestCx<'test> { let config = Config { target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), + mode: DebugInfoLldb, ..self.config.clone() }; @@ -1774,7 +1781,7 @@ impl<'test> TestCx<'test> { rustc.arg(dir_opt); } - RunFail | RunPassValgrind | Pretty | DebugInfoGdb | DebugInfoLldb + RunFail | RunPassValgrind | Pretty | DebugInfoBoth | DebugInfoGdb | DebugInfoLldb | Codegen | Rustdoc | RunMake | CodegenUnits => { // do not use JSON output } From 7a0fa95336439120d89bb2f6116146011fd40307 Mon Sep 17 00:00:00 2001 From: Vasya Novikov Date: Thu, 11 Oct 2018 21:37:30 +0300 Subject: [PATCH 09/38] improve docs on thread::sleep --- src/libstd/thread/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 70a9532665805..3f29a81f25e6b 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -657,8 +657,10 @@ pub fn panicking() -> bool { /// /// # Platform-specific behavior /// -/// On Unix platforms this function may invoke multiple syscalls -/// in case of a signal being received or a spurious wakeup. +/// On Unix platforms, the underlying syscall may be interrupted by a +/// spurious wakeup or signal handler. To ensure the sleep occurs for at least +/// the specified duration, this function may invoke that system call multiple +/// times. /// /// # Examples /// @@ -681,8 +683,10 @@ pub fn sleep_ms(ms: u32) { /// /// # Platform-specific behavior /// -/// On Unix platforms this function may invoke multiple syscalls -/// in case of a signal being received or a spurious wakeup. +/// On Unix platforms, the underlying syscall may be interrupted by a +/// spurious wakeup or signal handler. To ensure the sleep occurs for at least +/// the specified duration, this function may invoke that system call multiple +/// times. /// Platforms which do not support nanosecond precision for sleeping will /// have `dur` rounded up to the nearest granularity of time they can sleep for. /// From b57366a85457ddf6c5cb8ff4f329776c5311c5a4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 13 Oct 2018 10:52:18 +0200 Subject: [PATCH 10/38] Improve verify_llvm_ir config option * Make it influence the behavior of the compiled rustc, rather than just the rustc build system. That is, if verify_llvm_ir=true, even manual invocations of the built rustc will verify LLVM IR. * Enable verification of LLVM IR in CI, for non-deploy and deploy-alt builds. This is similar to how LLVM assertions are handled. --- src/bootstrap/bin/rustc.rs | 4 ---- src/bootstrap/builder.rs | 4 ---- src/bootstrap/compile.rs | 3 +++ src/ci/run.sh | 3 +++ src/librustc/build.rs | 7 +++++++ src/librustc/session/mod.rs | 1 + 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index b89976eca26c4..b6764c1aaeab6 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -287,10 +287,6 @@ fn main() { cmd.arg("--cfg").arg("parallel_queries"); } - if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() { - cmd.arg("-Z").arg("verify-llvm-ir"); - } - if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none() { cmd.arg("-Dwarnings"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b842bc43f5baa..aa4e44df2ef94 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1000,10 +1000,6 @@ impl<'a> Builder<'a> { cargo.env("RUSTC_BACKTRACE_ON_ICE", "1"); } - if self.config.rust_verify_llvm_ir { - cargo.env("RUSTC_VERIFY_LLVM_IR", "1"); - } - cargo.env("RUSTC_VERBOSE", self.verbosity.to_string()); // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful. diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 7d235743c2c46..69d45acdedaf9 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -569,6 +569,9 @@ pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) { if builder.config.rustc_parallel_queries { cargo.env("RUSTC_PARALLEL_QUERIES", "1"); } + if builder.config.rust_verify_llvm_ir { + cargo.env("RUSTC_VERIFY_LLVM_IR", "1"); + } } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/src/ci/run.sh b/src/ci/run.sh index a9e506645f189..42561cf95d3ac 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -61,6 +61,7 @@ if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" elif [ "$DEPLOY_ALT" != "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir" fi else # We almost always want debug assertions enabled, but sometimes this takes too @@ -74,6 +75,8 @@ else if [ "$NO_LLVM_ASSERTIONS" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions" fi + + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir" fi if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]; then diff --git a/src/librustc/build.rs b/src/librustc/build.rs index 4df5f0e64050c..bde503d86de73 100644 --- a/src/librustc/build.rs +++ b/src/librustc/build.rs @@ -8,8 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::env; + fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-env-changed=CFG_LIBDIR_RELATIVE"); println!("cargo:rerun-if-env-changed=CFG_COMPILER_HOST_TRIPLE"); + println!("cargo:rerun-if-env-changed=RUSTC_VERIFY_LLVM_IR"); + + if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() { + println!("cargo:rustc-cfg=always_verify_llvm_ir"); + } } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3c209a4324675..fbe252fcfaf50 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -531,6 +531,7 @@ impl Session { } pub fn verify_llvm_ir(&self) -> bool { self.opts.debugging_opts.verify_llvm_ir + || cfg!(always_verify_llvm_ir) } pub fn borrowck_stats(&self) -> bool { self.opts.debugging_opts.borrowck_stats From 91f57787c0a46b7e6f9ae19ed7249498b564fbf1 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 13 Oct 2018 21:39:21 +0200 Subject: [PATCH 11/38] doc std::fmt: the Python inspiration is already mentioned in preceding paragraph --- src/liballoc/fmt.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index b49ec0ae25212..c6597ffd9d617 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -335,8 +335,7 @@ //! //! Each argument being formatted can be transformed by a number of formatting //! parameters (corresponding to `format_spec` in the syntax above). These -//! parameters affect the string representation of what's being formatted. This -//! syntax draws heavily from Python's, so it may seem a bit familiar. +//! parameters affect the string representation of what's being formatted. //! //! ## Fill/Alignment //! From 86d5a33c890404da65c48925525af06b9b68a0ac Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 15 Oct 2018 00:48:57 +0100 Subject: [PATCH 12/38] rustdoc: Use dyn keyword when rendering dynamic traits The dyn keyword has been stable for a while now so rustdoc should start using it. --- src/librustdoc/html/format.rs | 3 +++ src/test/rustdoc/assoc-consts.rs | 2 +- src/test/rustdoc/inline_cross/issue-32881.rs | 4 ++-- src/test/rustdoc/test-parens.rs | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 7643aade83b7d..445fc2e833a3f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -553,6 +553,9 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: f.write_str(name) } clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => { + if typarams.is_some() { + f.write_str("dyn ")?; + } // Paths like T::Output and Self::Output should be rendered with all segments resolved_path(f, did, path, is_generic, use_absolute)?; tybounds(f, typarams) diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs index 71e7db5f4a543..cbb2a00214a5a 100644 --- a/src/test/rustdoc/assoc-consts.rs +++ b/src/test/rustdoc/assoc-consts.rs @@ -52,7 +52,7 @@ pub fn f(_: &(ToString + 'static)) {} impl Bar { // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \ - // "const F: fn(_: &(ToString + 'static))" + // "const F: fn(_: &(dyn ToString + 'static))" pub const F: fn(_: &(ToString + 'static)) = f; } diff --git a/src/test/rustdoc/inline_cross/issue-32881.rs b/src/test/rustdoc/inline_cross/issue-32881.rs index 948061bdcbed5..c55a69bcb7bc5 100644 --- a/src/test/rustdoc/inline_cross/issue-32881.rs +++ b/src/test/rustdoc/inline_cross/issue-32881.rs @@ -15,8 +15,8 @@ extern crate rustdoc_trait_object_impl; // @has issue_32881/trait.Bar.html -// @has - '//code' "impl<'a> Bar" -// @has - '//code' "impl<'a> Debug for Bar" +// @has - '//code' "impl<'a> dyn Bar" +// @has - '//code' "impl<'a> Debug for dyn Bar" pub use rustdoc_trait_object_impl::Bar; diff --git a/src/test/rustdoc/test-parens.rs b/src/test/rustdoc/test-parens.rs index 792dc9c218d56..0c9452fa1e1af 100644 --- a/src/test/rustdoc/test-parens.rs +++ b/src/test/rustdoc/test-parens.rs @@ -11,5 +11,5 @@ #![crate_name = "foo"] // @has foo/fn.foo.html -// @has - '//*[@class="rust fn"]' "_: &(ToString + 'static)" +// @has - '//*[@class="rust fn"]' "_: &(dyn ToString + 'static)" pub fn foo(_: &(ToString + 'static)) {} From d4e2dcaff1bb957f41384e9e6a0dbb830dffe09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roy=20Wellington=20=E2=85=A3?= Date: Sun, 14 Oct 2018 17:23:47 -0700 Subject: [PATCH 13/38] Detect if access to localStorage is forbidden by the user's browser If the user's cookie/persistent storage setting forbid access to localStorage, catch the exception and abort the access. Currently, attempting to use the expand/contract links at the top of the page for structs/consts/etc. fails due to an unhandled error while accessing localStorage, if such access is forbidden, as the exception from the failed access propagates all the way out, interrupting the expand/contract. Instead, I would like to degrade gracefully; the access won't happen (the collapse/expand state won't get persisted) but the actual expanding/contracting of the item will go on to succeed. Fixes #55079 --- src/librustdoc/html/static/storage.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 4ef8349fa9ce9..9dc78f7beb610 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -28,6 +28,12 @@ function onEach(arr, func) { function updateLocalStorage(name, value) { if (typeof(Storage) !== "undefined") { + try { + window.localStorage; + } catch(err) { + // Storage is supported, but browser preferences deny access to it. + return; + } localStorage[name] = value; } else { // No Web Storage support so we do nothing From 481ad0ea35afb795b04e2aba99c194d50a0ebe3f Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 15 Oct 2018 14:07:19 +0200 Subject: [PATCH 14/38] regression test for issue #54597 --- ...54597-reject-move-out-of-borrow-via-pat.rs | 22 +++++++++++++++++++ ...7-reject-move-out-of-borrow-via-pat.stderr | 12 ++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs create mode 100644 src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs new file mode 100644 index 0000000000000..0749900986d2e --- /dev/null +++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs @@ -0,0 +1,22 @@ +#![feature(nll)] + +#![allow(dead_code)] + +#[derive(Debug)] +struct Value; +impl Value { + fn as_array(&self) -> Option<&Vec> { + None + } +} + +fn foo(val: Value) { + let _reviewers_original: Vec = match val.as_array() { + Some(array) => { + *array + } + None => vec![] + }; +} + +fn main() { } diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr new file mode 100644 index 0000000000000..6a12016b2a5e3 --- /dev/null +++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr @@ -0,0 +1,12 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:16:13 + | +LL | *array + | ^^^^^^ + | | + | cannot move out of borrowed content + | help: consider removing the `*`: `array` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. From 80feed380d478a14e5acd99fc8721ed0e6de19ba Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 12 Oct 2018 16:10:16 +0200 Subject: [PATCH 15/38] Deduplicate vtables within a single evaluation --- src/librustc_mir/interpret/eval_context.rs | 5 +++++ src/librustc_mir/interpret/traits.rs | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 85a8376134aa4..be9f2b8f658dd 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -27,6 +27,7 @@ use rustc::mir::interpret::{ EvalResult, EvalErrorKind, truncate, sign_extend, }; +use rustc_data_structures::fx::FxHashMap; use syntax::source_map::{self, Span}; @@ -50,6 +51,9 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> { /// The virtual call stack. pub(crate) stack: Vec>, + + /// A cache for deduplicating vtables + pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), AllocId>, } /// A stack frame. @@ -209,6 +213,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc param_env, memory: Memory::new(tcx, memory_data), stack: Vec::new(), + vtables: FxHashMap(), } } diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 227c85772d228..b4c73ad02c313 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -28,7 +28,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> ) -> EvalResult<'tcx, Pointer> { debug!("get_vtable(trait_ref={:?})", trait_ref); - // FIXME: Cache this! + if let Some(&vtable) = self.vtables.get(&(ty, trait_ref)) { + return Ok(Pointer::from(vtable).with_default_tag()); + } let layout = self.layout_of(trait_ref.self_ty())?; assert!(!layout.is_unsized(), "can't create a vtable for an unsized type"); @@ -64,6 +66,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } self.memory.mark_immutable(vtable.alloc_id)?; + assert!(self.vtables.insert((ty, trait_ref), vtable.alloc_id).is_none()); Ok(vtable) } From 8ac7fa414bf6fce856c10bafbe0bf068d48a02be Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 12 Oct 2018 16:45:17 +0200 Subject: [PATCH 16/38] Synchronize get_vtable with the `codegen_llvm` one --- src/librustc_mir/interpret/cast.rs | 7 +------ src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/interpret/traits.rs | 18 ++++++++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index f4ddfa5293e1e..f5e824b762888 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -327,12 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } (_, &ty::Dynamic(ref data, _)) => { // Initial cast from sized to dyn trait - let trait_ref = data.principal().with_self_ty( - *self.tcx, - src_pointee_ty, - ); - let trait_ref = self.tcx.erase_regions(&trait_ref); - let vtable = self.get_vtable(src_pointee_ty, trait_ref)?; + let vtable = self.get_vtable(src_pointee_ty, data.principal())?; let ptr = self.read_value(src)?.to_scalar_ptr()?; let val = Value::new_dyn_trait(ptr, vtable); self.write_value(val, dest) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index be9f2b8f658dd..13b6fa44de203 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -53,7 +53,7 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> { pub(crate) stack: Vec>, /// A cache for deduplicating vtables - pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), AllocId>, + pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), AllocId>, } /// A stack frame. diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index b4c73ad02c313..30591a4ff5a5e 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -24,22 +24,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> pub fn get_vtable( &mut self, ty: Ty<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, + poly_trait_ref: ty::PolyExistentialTraitRef<'tcx>, ) -> EvalResult<'tcx, Pointer> { - debug!("get_vtable(trait_ref={:?})", trait_ref); + debug!("get_vtable(trait_ref={:?})", poly_trait_ref); - if let Some(&vtable) = self.vtables.get(&(ty, trait_ref)) { + let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref)); + + if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) { return Ok(Pointer::from(vtable).with_default_tag()); } - let layout = self.layout_of(trait_ref.self_ty())?; + let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty); + let trait_ref = self.tcx.erase_regions(&trait_ref); + + let methods = self.tcx.vtable_methods(trait_ref); + + let layout = self.layout_of(ty)?; assert!(!layout.is_unsized(), "can't create a vtable for an unsized type"); let size = layout.size.bytes(); let align = layout.align.abi(); let ptr_size = self.pointer_size(); let ptr_align = self.tcx.data_layout.pointer_align; - let methods = self.tcx.vtable_methods(trait_ref); let vtable = self.memory.allocate( ptr_size * (3 + methods.len() as u64), ptr_align, @@ -66,7 +72,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } self.memory.mark_immutable(vtable.alloc_id)?; - assert!(self.vtables.insert((ty, trait_ref), vtable.alloc_id).is_none()); + assert!(self.vtables.insert((ty, poly_trait_ref), vtable.alloc_id).is_none()); Ok(vtable) } From ef3ece74446d964066a21c9b47fb945a9b04f3ef Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 12 Oct 2018 16:59:55 +0200 Subject: [PATCH 17/38] Uplift some comments to doc comments --- src/librustc/ty/query/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 7f5bc35f91f9b..ac5c0352453e7 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -369,16 +369,16 @@ define_queries! { <'tcx> -> Lrc, [] fn is_object_safe: ObjectSafety(DefId) -> bool, - // Get the ParameterEnvironment for a given item; this environment - // will be in "user-facing" mode, meaning that it is suitabe for - // type-checking etc, and it does not normalize specializable - // associated types. This is almost always what you want, - // unless you are doing MIR optimizations, in which case you - // might want to use `reveal_all()` method to change modes. + /// Get the ParameterEnvironment for a given item; this environment + /// will be in "user-facing" mode, meaning that it is suitabe for + /// type-checking etc, and it does not normalize specializable + /// associated types. This is almost always what you want, + /// unless you are doing MIR optimizations, in which case you + /// might want to use `reveal_all()` method to change modes. [] fn param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>, - // Trait selection queries. These are best used by invoking `ty.moves_by_default()`, - // `ty.is_copy()`, etc, since that will prune the environment where possible. + /// Trait selection queries. These are best used by invoking `ty.moves_by_default()`, + /// `ty.is_copy()`, etc, since that will prune the environment where possible. [] fn is_copy_raw: is_copy_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool, [] fn is_sized_raw: is_sized_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool, [] fn is_freeze_raw: is_freeze_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool, From c95ee9e91dce4fa56c4636e0b8b9cbc4e676b830 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 12 Oct 2018 17:08:36 +0200 Subject: [PATCH 18/38] Add comments to remind everyone to keep the `get_vtable` impls in sync --- src/librustc_codegen_llvm/meth.rs | 4 ++++ src/librustc_mir/interpret/traits.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index db06b87f44e1e..29c2e71960c2c 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -94,6 +94,10 @@ pub fn get_vtable( }); let (size, align) = cx.size_and_align_of(ty); + // ///////////////////////////////////////////////////////////////////////////////////////////// + // If you touch this code, be sure to also make the corresponding changes to + // `get_vtable` in rust_mir/interpret/traits.rs + // ///////////////////////////////////////////////////////////////////////////////////////////// let components: Vec<_> = [ callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)), C_usize(cx, size.bytes()), diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 30591a4ff5a5e..2b0febc1ce717 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -46,6 +46,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let ptr_size = self.pointer_size(); let ptr_align = self.tcx.data_layout.pointer_align; + // ///////////////////////////////////////////////////////////////////////////////////////// + // If you touch this code, be sure to also make the corresponding changes to + // `get_vtable` in rust_codegen_llvm/meth.rs + // ///////////////////////////////////////////////////////////////////////////////////////// let vtable = self.memory.allocate( ptr_size * (3 + methods.len() as u64), ptr_align, From 70dd9ca5da56b805c9495f4e0e91e67fdb1d4a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Oct 2018 14:17:54 -0700 Subject: [PATCH 19/38] Add test for #34229 --- src/test/ui/issues/issue-34229.rs | 4 ++++ src/test/ui/issues/issue-34229.stderr | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/test/ui/issues/issue-34229.rs create mode 100644 src/test/ui/issues/issue-34229.stderr diff --git a/src/test/ui/issues/issue-34229.rs b/src/test/ui/issues/issue-34229.rs new file mode 100644 index 0000000000000..bcdfcc767fb9e --- /dev/null +++ b/src/test/ui/issues/issue-34229.rs @@ -0,0 +1,4 @@ +#[derive(PartialEq)] struct Comparable; +#[derive(PartialEq, PartialOrd)] struct Nope(Comparable); + +fn main() {} diff --git a/src/test/ui/issues/issue-34229.stderr b/src/test/ui/issues/issue-34229.stderr new file mode 100644 index 0000000000000..c57f80cd4091c --- /dev/null +++ b/src/test/ui/issues/issue-34229.stderr @@ -0,0 +1,12 @@ +error[E0277]: can't compare `Comparable` with `Comparable` + --> $DIR/issue-34229.rs:2:46 + | +LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable); + | ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable` + | + = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable` + = note: required by `std::cmp::PartialOrd::partial_cmp` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 8362aa2178959186c09899ca173ffb296fb3445e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roy=20Wellington=20=E2=85=A3?= Date: Mon, 15 Oct 2018 20:38:51 -0700 Subject: [PATCH 20/38] Extract localStorage tests out into a helper method; use in getCurrentValue() 1. Extract the tests for whether or not we have workable localStorage out into a helper method, so it can be more easily reused 2. Use it in getCurrentValue() too, for the same reasons, as suggested in code review --- src/librustdoc/html/static/storage.js | 28 +++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 9dc78f7beb610..206b3128eb359 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -27,13 +27,7 @@ function onEach(arr, func) { } function updateLocalStorage(name, value) { - if (typeof(Storage) !== "undefined") { - try { - window.localStorage; - } catch(err) { - // Storage is supported, but browser preferences deny access to it. - return; - } + if (usableLocalStorage()) { localStorage[name] = value; } else { // No Web Storage support so we do nothing @@ -41,12 +35,30 @@ function updateLocalStorage(name, value) { } function getCurrentValue(name) { - if (typeof(Storage) !== "undefined" && localStorage[name] !== undefined) { + if (usableLocalStorage() && localStorage[name] !== undefined) { return localStorage[name]; } return null; } +function usableLocalStorage() { + // Check if the browser supports localStorage at all: + if (typeof(Storage) === "undefined") { + return false; + } + // Check if we can access it; this access will fail if the browser + // preferences deny access to localStorage, e.g., to prevent storage of + // "cookies" (or cookie-likes, as is the case here). + try { + window.localStorage; + } catch(err) { + // Storage is supported, but browser preferences deny access to it. + return false; + } + + return true; +} + function switchTheme(styleElem, mainStyleElem, newTheme) { var fullBasicCss = "rustdoc" + resourcesSuffix + ".css"; var fullNewTheme = newTheme + resourcesSuffix + ".css"; From 8e10ea68296c8ba6b4f6fddb445522d4b5281084 Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Mon, 15 Oct 2018 21:35:56 -0700 Subject: [PATCH 21/38] [Rustc Book] Explain --cfg's arguments --- src/doc/rustc/src/command-line-arguments.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index e2b001832fe31..ea3277b13205a 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -10,6 +10,11 @@ This flag will print out help information for `rustc`. This flag can turn on or off various `#[cfg]` settings. +The value can either be a single identifier or two identifiers separated by `=`. + +For examples, `--cfg 'verbose'` or `--cfg 'feature=serde'`. These correspond +to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. + ## `-L`: add a directory to the library search path When looking for external crates, a directory passed to this flag will be searched. From 8c186af538218aaac40572bff64f0032ba968dbd Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Tue, 16 Oct 2018 00:13:05 -0700 Subject: [PATCH 22/38] [Rustc Book] Quotes around value in --cfg example --- src/doc/rustc/src/command-line-arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index ea3277b13205a..b60c55240140e 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -12,7 +12,7 @@ This flag can turn on or off various `#[cfg]` settings. The value can either be a single identifier or two identifiers separated by `=`. -For examples, `--cfg 'verbose'` or `--cfg 'feature=serde'`. These correspond +For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. ## `-L`: add a directory to the library search path From b1d3111ba2f4c7d318632c330b4356fec52b4055 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 16 Oct 2018 10:39:48 +0200 Subject: [PATCH 23/38] Use forward compatible `FxHashMap` initialization --- src/librustc_mir/interpret/eval_context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 13b6fa44de203..cf5358a989672 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -213,7 +213,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc param_env, memory: Memory::new(tcx, memory_data), stack: Vec::new(), - vtables: FxHashMap(), + vtables: FxHashMap::default(), } } From 24b74b27443192f6d440be10f7aa0617d8003fab Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 16 Oct 2018 11:14:10 +0200 Subject: [PATCH 24/38] end return statements and void expressions with a semicolon --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 10 +++++----- src/librustc_codegen_llvm/debuginfo/source_loc.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 6dcca65a73601..163a8b91f4c4f 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -164,7 +164,7 @@ impl TypeMap<'ll, 'tcx> { type_: Ty<'tcx>) -> UniqueTypeId { // Let's see if we already have something in the cache if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() { - return unique_type_id + return unique_type_id; } // if not, generate one @@ -290,7 +290,7 @@ macro_rules! return_if_metadata_created_in_meantime { .borrow() .find_metadata_for_unique_id($unique_type_id) { - return MetadataCreationResult::new(metadata, true) + return MetadataCreationResult::new(metadata, true); } ) } @@ -552,7 +552,7 @@ pub fn type_metadata( .borrow() .find_metadata_for_unique_id(unique_type_id) { - return Err(metadata) + return Err(metadata); } Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata), @@ -612,7 +612,7 @@ pub fn type_metadata( .borrow() .find_metadata_for_unique_id(unique_type_id) { - return metadata + return metadata; } // This is actually a function pointer, so wrap it in pointer DI @@ -1477,7 +1477,7 @@ fn prepare_enum_metadata( }; if let (&layout::Abi::Scalar(_), Some(discr)) = (&layout.abi, discriminant_type_metadata) { - return FinalMetadata(discr) + return FinalMetadata(discr); } let (enum_type_size, enum_type_align) = layout.size_and_align(); diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index 405cffdefa285..60ebcb888166f 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -57,7 +57,7 @@ pub fn set_source_location( /// first real statement/expression of the function is codegened. pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext<'ll>) { if let FunctionDebugContext::RegularContext(ref data) = *dbg_context { - data.source_locations_enabled.set(true) + data.source_locations_enabled.set(true); } } From f40932f106d3670a4b2041d54bf37fa3f49c20f2 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 16 Oct 2018 18:19:04 +0100 Subject: [PATCH 25/38] Fix LLVMRustInlineAsmVerify return type mismatch --- src/librustc_codegen_llvm/builder.rs | 2 +- src/librustc_codegen_llvm/llvm/ffi.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index df9c4e874bd95..169bd9a8466a0 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -756,7 +756,7 @@ impl Builder<'a, 'll, 'tcx> { // Ask LLVM to verify that the constraints are well-formed. let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons); debug!("Constraint verification result: {:?}", constraints_ok); - if constraints_ok == llvm::True { + if constraints_ok { let v = llvm::LLVMRustInlineAsm( fty, asm, cons, volatile, alignstack, dia); Some(self.call(v, inputs, None)) diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 6108af6c884cb..0b98fa4eaf551 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1212,8 +1212,8 @@ extern "C" { Dialect: AsmDialect) -> &Value; pub fn LLVMRustInlineAsmVerify(Ty: &Type, - Constraints: *const c_char) - -> Bool; + Constraints: *const c_char) + -> bool; pub fn LLVMRustDebugMetadataVersion() -> u32; pub fn LLVMRustVersionMajor() -> u32; From 1dd92c4a7000822612e553a121f09bb3e9a55793 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 16 Oct 2018 18:36:44 +0200 Subject: [PATCH 26/38] Remove HybridBitSet::dummy --- src/librustc_data_structures/bit_set.rs | 50 +++++++------------------ 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs index 1fba57fa541f0..28aad49b09b99 100644 --- a/src/librustc_data_structures/bit_set.rs +++ b/src/librustc_data_structures/bit_set.rs @@ -423,15 +423,6 @@ pub enum HybridBitSet { } impl HybridBitSet { - // FIXME: This function is used in conjunction with `mem::replace()` in - // several pieces of awful code below. I can't work out how else to appease - // the borrow checker. - fn dummy() -> Self { - // The cheapest HybridBitSet to construct, which is only used to get - // around the borrow checker. - HybridBitSet::Sparse(SparseBitSet::new_empty(0)) - } - pub fn new_empty(domain_size: usize) -> Self { HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size)) } @@ -487,20 +478,14 @@ impl HybridBitSet { // that doesn't matter because `elem` is already present. false } - HybridBitSet::Sparse(_) => { + HybridBitSet::Sparse(sparse) => { // The set is sparse and full. Convert to a dense set. - match mem::replace(self, HybridBitSet::dummy()) { - HybridBitSet::Sparse(sparse) => { - let mut dense = sparse.to_dense(); - let changed = dense.insert(elem); - assert!(changed); - *self = HybridBitSet::Dense(dense); - changed - } - _ => unreachable!() - } + let mut dense = sparse.to_dense(); + let changed = dense.insert(elem); + assert!(changed); + *self = HybridBitSet::Dense(dense); + changed } - HybridBitSet::Dense(dense) => dense.insert(elem), } } @@ -525,33 +510,26 @@ impl HybridBitSet { pub fn union(&mut self, other: &HybridBitSet) -> bool { match self { - HybridBitSet::Sparse(_) => { + HybridBitSet::Sparse(self_sparse) => { match other { HybridBitSet::Sparse(other_sparse) => { // Both sets are sparse. Add the elements in - // `other_sparse` to `self_hybrid` one at a time. This - // may or may not cause `self_hybrid` to be densified. + // `other_sparse` to `self` one at a time. This + // may or may not cause `self` to be densified. assert_eq!(self.domain_size(), other.domain_size()); - let mut self_hybrid = mem::replace(self, HybridBitSet::dummy()); let mut changed = false; for elem in other_sparse.iter() { - changed |= self_hybrid.insert(*elem); + changed |= self.insert(*elem); } - *self = self_hybrid; changed } HybridBitSet::Dense(other_dense) => { // `self` is sparse and `other` is dense. Densify // `self` and then do the bitwise union. - match mem::replace(self, HybridBitSet::dummy()) { - HybridBitSet::Sparse(self_sparse) => { - let mut new_dense = self_sparse.to_dense(); - let changed = new_dense.union(other_dense); - *self = HybridBitSet::Dense(new_dense); - changed - } - _ => unreachable!() - } + let mut new_dense = self_sparse.to_dense(); + let changed = new_dense.union(other_dense); + *self = HybridBitSet::Dense(new_dense); + changed } } } From cbe98ec803c023deb6d200b6761acd7c7d73254c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roy=20Wellington=20=E2=85=A3?= Date: Tue, 16 Oct 2018 22:15:27 -0700 Subject: [PATCH 27/38] Move usableLocalStorage() above functions that make use of it --- src/librustdoc/html/static/storage.js | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 206b3128eb359..e10e330402f5e 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -26,21 +26,6 @@ function onEach(arr, func) { return false; } -function updateLocalStorage(name, value) { - if (usableLocalStorage()) { - localStorage[name] = value; - } else { - // No Web Storage support so we do nothing - } -} - -function getCurrentValue(name) { - if (usableLocalStorage() && localStorage[name] !== undefined) { - return localStorage[name]; - } - return null; -} - function usableLocalStorage() { // Check if the browser supports localStorage at all: if (typeof(Storage) === "undefined") { @@ -59,6 +44,21 @@ function usableLocalStorage() { return true; } +function updateLocalStorage(name, value) { + if (usableLocalStorage()) { + localStorage[name] = value; + } else { + // No Web Storage support so we do nothing + } +} + +function getCurrentValue(name) { + if (usableLocalStorage() && localStorage[name] !== undefined) { + return localStorage[name]; + } + return null; +} + function switchTheme(styleElem, mainStyleElem, newTheme) { var fullBasicCss = "rustdoc" + resourcesSuffix + ".css"; var fullNewTheme = newTheme + resourcesSuffix + ".css"; From c31819b3ff35be5bdec58cba9515578fbff0a5b8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 17 Oct 2018 09:24:43 +0200 Subject: [PATCH 28/38] layout should not affect CTFE checks (outside of validation) --- src/librustc_mir/interpret/operand.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index c72a5894b6ac7..2d6b19ca4a7fc 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -688,9 +688,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> rval: OpTy<'tcx, M::PointerTag>, ) -> EvalResult<'tcx, (u128, usize)> { trace!("read_discriminant_value {:#?}", rval.layout); - if rval.layout.abi.is_uninhabited() { - return err!(Unreachable); - } match rval.layout.variants { layout::Variants::Single { index } => { From 350f9a2be56c2527647300287599464cdd508340 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 15 Oct 2018 23:43:59 +0300 Subject: [PATCH 29/38] resolve: Do not skip extern prelude during speculative resolution --- src/librustc_resolve/lib.rs | 12 +++++++++--- .../run-pass/extern/extern-prelude-no-speculative.rs | 2 +- src/test/ui/impl-trait/auxiliary/extra-item.rs | 1 + src/test/ui/impl-trait/extra-item.rs | 10 ++++++++++ src/test/ui/impl-trait/extra-item.stderr | 9 +++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/impl-trait/auxiliary/extra-item.rs create mode 100644 src/test/ui/impl-trait/extra-item.rs create mode 100644 src/test/ui/impl-trait/extra-item.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 86fe584dc3a40..ac0616e50b091 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1980,9 +1980,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } if !module.no_implicit_prelude { - // `record_used` means that we don't try to load crates during speculative resolution - if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) { - let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span); + if ns == TypeNS && self.extern_prelude.contains(&ident.name) { + let crate_id = if record_used { + self.crate_loader.process_path_extern(ident.name, ident.span) + } else if let Some(crate_id) = + self.crate_loader.maybe_process_path_extern(ident.name, ident.span) { + crate_id + } else { + return None; + }; let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }); self.populate_module_if_necessary(&crate_root); diff --git a/src/test/run-pass/extern/extern-prelude-no-speculative.rs b/src/test/run-pass/extern/extern-prelude-no-speculative.rs index 6ca1815a1917e..372f34454de92 100644 --- a/src/test/run-pass/extern/extern-prelude-no-speculative.rs +++ b/src/test/run-pass/extern/extern-prelude-no-speculative.rs @@ -10,7 +10,7 @@ // run-pass #![allow(unused_variables)] -// compile-flags: --extern LooksLikeExternCrate=/path/to/nowhere +// compile-flags: --extern LooksLikeExternCrate mod m { pub struct LooksLikeExternCrate; diff --git a/src/test/ui/impl-trait/auxiliary/extra-item.rs b/src/test/ui/impl-trait/auxiliary/extra-item.rs new file mode 100644 index 0000000000000..8eaeafa5207df --- /dev/null +++ b/src/test/ui/impl-trait/auxiliary/extra-item.rs @@ -0,0 +1 @@ +pub trait MyTrait {} diff --git a/src/test/ui/impl-trait/extra-item.rs b/src/test/ui/impl-trait/extra-item.rs new file mode 100644 index 0000000000000..d82237ccecc7d --- /dev/null +++ b/src/test/ui/impl-trait/extra-item.rs @@ -0,0 +1,10 @@ +// aux-build:extra-item.rs +// compile-flags:--extern extra_item + +struct S; + +impl extra_item::MyTrait for S { + fn extra() {} //~ ERROR method `extra` is not a member of trait `extra_item::MyTrait` +} + +fn main() {} diff --git a/src/test/ui/impl-trait/extra-item.stderr b/src/test/ui/impl-trait/extra-item.stderr new file mode 100644 index 0000000000000..de3c7ba5d3118 --- /dev/null +++ b/src/test/ui/impl-trait/extra-item.stderr @@ -0,0 +1,9 @@ +error[E0407]: method `extra` is not a member of trait `extra_item::MyTrait` + --> $DIR/extra-item.rs:7:5 + | +LL | fn extra() {} //~ ERROR method `extra` is not a member of trait `extra_item::MyTrait` + | ^^^^^^^^^^^^^ not a member of trait `extra_item::MyTrait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0407`. From 3ba62dd0f6d3c609a5d5ac61f0e1fc7c6861f66c Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 16 Oct 2018 15:06:59 +0200 Subject: [PATCH 30/38] mir/borrowck: simplify common patterns --- src/librustc_mir/borrow_check/borrow_set.rs | 92 +++-- .../borrow_check/error_reporting.rs | 321 +++++++++--------- src/librustc_mir/borrow_check/mod.rs | 6 +- .../borrow_check/mutability_errors.rs | 3 +- 4 files changed, 203 insertions(+), 219 deletions(-) diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index bcf3772213014..18cc1430c2a8f 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -244,7 +244,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { K: Clone + Eq + Hash, V: Eq + Hash, { - map.entry(k.clone()).or_insert(FxHashSet()).insert(v); + map.entry(k.clone()).or_default().insert(v); } } @@ -261,57 +261,53 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { // ... check whether we (earlier) saw a 2-phase borrow like // // TMP = &mut place - match self.pending_activations.get(temp) { - Some(&borrow_index) => { - let borrow_data = &mut self.idx_vec[borrow_index]; - - // Watch out: the use of TMP in the borrow itself - // doesn't count as an activation. =) - if borrow_data.reserve_location == location && context == PlaceContext::Store { - return; - } + if let Some(&borrow_index) = self.pending_activations.get(temp) { + let borrow_data = &mut self.idx_vec[borrow_index]; - if let TwoPhaseActivation::ActivatedAt(other_location) = - borrow_data.activation_location { - span_bug!( - self.mir.source_info(location).span, - "found two uses for 2-phase borrow temporary {:?}: \ - {:?} and {:?}", - temp, - location, - other_location, - ); - } + // Watch out: the use of TMP in the borrow itself + // doesn't count as an activation. =) + if borrow_data.reserve_location == location && context == PlaceContext::Store { + return; + } - // Otherwise, this is the unique later use - // that we expect. - borrow_data.activation_location = match context { - // The use of TMP in a shared borrow does not - // count as an actual activation. - PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. } - | PlaceContext::Borrow { kind: mir::BorrowKind::Shallow, .. } => { - TwoPhaseActivation::NotActivated - } - _ => { - // Double check: This borrow is indeed a two-phase borrow (that is, - // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and - // we've not found any other activations (checked above). - assert_eq!( - borrow_data.activation_location, - TwoPhaseActivation::NotActivated, - "never found an activation for this borrow!", - ); - - self.activation_map - .entry(location) - .or_default() - .push(borrow_index); - TwoPhaseActivation::ActivatedAt(location) - } - }; + if let TwoPhaseActivation::ActivatedAt(other_location) = + borrow_data.activation_location { + span_bug!( + self.mir.source_info(location).span, + "found two uses for 2-phase borrow temporary {:?}: \ + {:?} and {:?}", + temp, + location, + other_location, + ); } - None => {} + // Otherwise, this is the unique later use + // that we expect. + borrow_data.activation_location = match context { + // The use of TMP in a shared borrow does not + // count as an actual activation. + PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. } + | PlaceContext::Borrow { kind: mir::BorrowKind::Shallow, .. } => { + TwoPhaseActivation::NotActivated + } + _ => { + // Double check: This borrow is indeed a two-phase borrow (that is, + // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and + // we've not found any other activations (checked above). + assert_eq!( + borrow_data.activation_location, + TwoPhaseActivation::NotActivated, + "never found an activation for this borrow!", + ); + + self.activation_map + .entry(location) + .or_default() + .push(borrow_index); + TwoPhaseActivation::ActivatedAt(location) + } + }; } } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 546746aa72ebb..8d5629270feea 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -188,11 +188,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let tables = self.infcx.tcx.typeck_tables_of(id); let node_id = self.infcx.tcx.hir.as_local_node_id(id).unwrap(); let hir_id = self.infcx.tcx.hir.node_to_hir_id(node_id); - if tables.closure_kind_origins().get(hir_id).is_some() { - false - } else { - true - } + + tables.closure_kind_origins().get(hir_id).is_none() } _ => true, }; @@ -1366,191 +1363,184 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "annotate_argument_and_return_for_borrow: location={:?}", location ); - match &self.mir[location.block] - .statements - .get(location.statement_index) + if let Some(&Statement { kind: StatementKind::Assign(ref reservation, _), ..}) + = &self.mir[location.block].statements.get(location.statement_index) { - Some(&Statement { - kind: StatementKind::Assign(ref reservation, _), - .. - }) => { + debug!( + "annotate_argument_and_return_for_borrow: reservation={:?}", + reservation + ); + // Check that the initial assignment of the reserve location is into a temporary. + let mut target = *match reservation { + Place::Local(local) if self.mir.local_kind(*local) == LocalKind::Temp => local, + _ => return None, + }; + + // Next, look through the rest of the block, checking if we are assigning the + // `target` (that is, the place that contains our borrow) to anything. + let mut annotated_closure = None; + for stmt in &self.mir[location.block].statements[location.statement_index + 1..] { debug!( - "annotate_argument_and_return_for_borrow: reservation={:?}", - reservation + "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}", + target, stmt ); - // Check that the initial assignment of the reserve location is into a temporary. - let mut target = *match reservation { - Place::Local(local) if self.mir.local_kind(*local) == LocalKind::Temp => local, - _ => return None, - }; - - // Next, look through the rest of the block, checking if we are assigning the - // `target` (that is, the place that contains our borrow) to anything. - let mut annotated_closure = None; - for stmt in &self.mir[location.block].statements[location.statement_index + 1..] { + if let StatementKind::Assign(Place::Local(assigned_to), box rvalue) = &stmt.kind + { debug!( - "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}", - target, stmt + "annotate_argument_and_return_for_borrow: assigned_to={:?} \ + rvalue={:?}", + assigned_to, rvalue ); - if let StatementKind::Assign(Place::Local(assigned_to), box rvalue) = &stmt.kind + // Check if our `target` was captured by a closure. + if let Rvalue::Aggregate( + box AggregateKind::Closure(def_id, substs), + operands, + ) = rvalue { - debug!( - "annotate_argument_and_return_for_borrow: assigned_to={:?} \ - rvalue={:?}", - assigned_to, rvalue - ); - // Check if our `target` was captured by a closure. - if let Rvalue::Aggregate( - box AggregateKind::Closure(def_id, substs), - operands, - ) = rvalue - { - for operand in operands { - let assigned_from = match operand { - Operand::Copy(assigned_from) | Operand::Move(assigned_from) => { - assigned_from - } - _ => continue, - }; - debug!( - "annotate_argument_and_return_for_borrow: assigned_from={:?}", + for operand in operands { + let assigned_from = match operand { + Operand::Copy(assigned_from) | Operand::Move(assigned_from) => { assigned_from - ); - - // Find the local from the operand. - let assigned_from_local = match assigned_from.local() { - Some(local) => local, - None => continue, - }; - - if assigned_from_local != target { - continue; } + _ => continue, + }; + debug!( + "annotate_argument_and_return_for_borrow: assigned_from={:?}", + assigned_from + ); - // If a closure captured our `target` and then assigned - // into a place then we should annotate the closure in - // case it ends up being assigned into the return place. - annotated_closure = self.annotate_fn_sig( - *def_id, - self.infcx.closure_sig(*def_id, *substs), - ); - debug!( - "annotate_argument_and_return_for_borrow: \ - annotated_closure={:?} assigned_from_local={:?} \ - assigned_to={:?}", - annotated_closure, assigned_from_local, assigned_to - ); - - if *assigned_to == mir::RETURN_PLACE { - // If it was assigned directly into the return place, then - // return now. - return annotated_closure; - } else { - // Otherwise, update the target. - target = *assigned_to; - } + // Find the local from the operand. + let assigned_from_local = match assigned_from.local() { + Some(local) => local, + None => continue, + }; + + if assigned_from_local != target { + continue; } - // If none of our closure's operands matched, then skip to the next - // statement. - continue; + // If a closure captured our `target` and then assigned + // into a place then we should annotate the closure in + // case it ends up being assigned into the return place. + annotated_closure = self.annotate_fn_sig( + *def_id, + self.infcx.closure_sig(*def_id, *substs), + ); + debug!( + "annotate_argument_and_return_for_borrow: \ + annotated_closure={:?} assigned_from_local={:?} \ + assigned_to={:?}", + annotated_closure, assigned_from_local, assigned_to + ); + + if *assigned_to == mir::RETURN_PLACE { + // If it was assigned directly into the return place, then + // return now. + return annotated_closure; + } else { + // Otherwise, update the target. + target = *assigned_to; + } } - // Otherwise, look at other types of assignment. - let assigned_from = match rvalue { - Rvalue::Ref(_, _, assigned_from) => assigned_from, - Rvalue::Use(operand) => match operand { - Operand::Copy(assigned_from) | Operand::Move(assigned_from) => { - assigned_from - } - _ => continue, - }, - _ => continue, - }; - debug!( - "annotate_argument_and_return_for_borrow: \ - assigned_from={:?}", - assigned_from, - ); + // If none of our closure's operands matched, then skip to the next + // statement. + continue; + } - // Find the local from the rvalue. - let assigned_from_local = match assigned_from.local() { - Some(local) => local, - None => continue, - }; - debug!( - "annotate_argument_and_return_for_borrow: \ - assigned_from_local={:?}", - assigned_from_local, - ); + // Otherwise, look at other types of assignment. + let assigned_from = match rvalue { + Rvalue::Ref(_, _, assigned_from) => assigned_from, + Rvalue::Use(operand) => match operand { + Operand::Copy(assigned_from) | Operand::Move(assigned_from) => { + assigned_from + } + _ => continue, + }, + _ => continue, + }; + debug!( + "annotate_argument_and_return_for_borrow: \ + assigned_from={:?}", + assigned_from, + ); - // Check if our local matches the target - if so, we've assigned our - // borrow to a new place. - if assigned_from_local != target { - continue; - } + // Find the local from the rvalue. + let assigned_from_local = match assigned_from.local() { + Some(local) => local, + None => continue, + }; + debug!( + "annotate_argument_and_return_for_borrow: \ + assigned_from_local={:?}", + assigned_from_local, + ); - // If we assigned our `target` into a new place, then we should - // check if it was the return place. - debug!( - "annotate_argument_and_return_for_borrow: \ - assigned_from_local={:?} assigned_to={:?}", - assigned_from_local, assigned_to - ); - if *assigned_to == mir::RETURN_PLACE { - // If it was then return the annotated closure if there was one, - // else, annotate this function. - return annotated_closure.or_else(fallback); - } + // Check if our local matches the target - if so, we've assigned our + // borrow to a new place. + if assigned_from_local != target { + continue; + } - // If we didn't assign into the return place, then we just update - // the target. - target = *assigned_to; + // If we assigned our `target` into a new place, then we should + // check if it was the return place. + debug!( + "annotate_argument_and_return_for_borrow: \ + assigned_from_local={:?} assigned_to={:?}", + assigned_from_local, assigned_to + ); + if *assigned_to == mir::RETURN_PLACE { + // If it was then return the annotated closure if there was one, + // else, annotate this function. + return annotated_closure.or_else(fallback); } + + // If we didn't assign into the return place, then we just update + // the target. + target = *assigned_to; } + } - // Check the terminator if we didn't find anything in the statements. - let terminator = &self.mir[location.block].terminator(); + // Check the terminator if we didn't find anything in the statements. + let terminator = &self.mir[location.block].terminator(); + debug!( + "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}", + target, terminator + ); + if let TerminatorKind::Call { + destination: Some((Place::Local(assigned_to), _)), + args, + .. + } = &terminator.kind + { debug!( - "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}", - target, terminator + "annotate_argument_and_return_for_borrow: assigned_to={:?} args={:?}", + assigned_to, args ); - if let TerminatorKind::Call { - destination: Some((Place::Local(assigned_to), _)), - args, - .. - } = &terminator.kind - { + for operand in args { + let assigned_from = match operand { + Operand::Copy(assigned_from) | Operand::Move(assigned_from) => { + assigned_from + } + _ => continue, + }; debug!( - "annotate_argument_and_return_for_borrow: assigned_to={:?} args={:?}", - assigned_to, args + "annotate_argument_and_return_for_borrow: assigned_from={:?}", + assigned_from, ); - for operand in args { - let assigned_from = match operand { - Operand::Copy(assigned_from) | Operand::Move(assigned_from) => { - assigned_from - } - _ => continue, - }; + + if let Some(assigned_from_local) = assigned_from.local() { debug!( - "annotate_argument_and_return_for_borrow: assigned_from={:?}", - assigned_from, + "annotate_argument_and_return_for_borrow: assigned_from_local={:?}", + assigned_from_local, ); - if let Some(assigned_from_local) = assigned_from.local() { - debug!( - "annotate_argument_and_return_for_borrow: assigned_from_local={:?}", - assigned_from_local, - ); - - if *assigned_to == mir::RETURN_PLACE && assigned_from_local == target { - return annotated_closure.or_else(fallback); - } + if *assigned_to == mir::RETURN_PLACE && assigned_from_local == target { + return annotated_closure.or_else(fallback); } } } } - _ => {} } // If we haven't found an assignment into the return place, then we need not add @@ -1605,13 +1595,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // Need to use the `rustc::ty` types to compare against the // `return_region`. Then use the `rustc::hir` type to get only // the lifetime span. - match &fn_decl.inputs[index].node { - hir::TyKind::Rptr(lifetime, _) => { - // With access to the lifetime, we can get - // the span of it. - arguments.push((*argument, lifetime.span)); - } - _ => bug!("ty type is a ref but hir type is not"), + if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].node { + // With access to the lifetime, we can get + // the span of it. + arguments.push((*argument, lifetime.span)); + } else { + bug!("ty type is a ref but hir type is not"); } } } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 1f8d077fb6904..59bb534881e33 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -284,7 +284,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( let temporary_used_locals: FxHashSet = mbcx .used_mut .iter() - .filter(|&local| !mbcx.mir.local_decls[*local].is_user_variable.is_some()) + .filter(|&local| mbcx.mir.local_decls[*local].is_user_variable.is_none()) .cloned() .collect(); mbcx.gather_used_muts(temporary_used_locals); @@ -342,7 +342,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( diag.buffer(&mut mbcx.errors_buffer); } - if mbcx.errors_buffer.len() > 0 { + if !mbcx.errors_buffer.is_empty() { mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span()); if tcx.migrate_borrowck() { @@ -2171,7 +2171,7 @@ impl ContextKind { fn new(self, loc: Location) -> Context { Context { kind: self, - loc: loc, + loc, } } } diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 5ab1605d7f07a..f0b4a5ac7435b 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -408,7 +408,6 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { .map(|replacement| (pattern_span, replacement)) } - // ClearCrossCrate::Set(mir::BindingForm::RefForGuard) => unreachable!(), ClearCrossCrate::Clear => bug!("saw cleared local state"), @@ -573,7 +572,7 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>( opt_ty_info: Option, ) -> (Span, String) { let locations = mir.find_assignments(local); - if locations.len() > 0 { + if !locations.is_empty() { let assignment_rhs_span = mir.source_info(locations[0]).span; if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) { if let (true, Some(ws_pos)) = ( From 684c4e8419ae737fa2e1bc4a43961e3a5daa7c3a Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 16 Oct 2018 15:10:59 +0200 Subject: [PATCH 31/38] mir/borrowck: a few string tweaks --- src/librustc_mir/borrow_check/borrow_set.rs | 8 ++++---- src/librustc_mir/borrow_check/error_reporting.rs | 16 +++++++--------- src/librustc_mir/borrow_check/move_errors.rs | 6 +++--- .../borrow_check/mutability_errors.rs | 4 ++-- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 18cc1430c2a8f..a316fc5ca1029 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -92,12 +92,12 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> { mir::BorrowKind::Mut { .. } => "mut ", }; let region = self.region.to_string(); - let region = if region.len() > 0 { - format!("{} ", region) + let separator = if !region.is_empty() { + " " } else { - region + "" }; - write!(w, "&{}{}{:?}", region, kind, self.borrowed_place) + write!(w, "&{}{}{}{:?}", region, separator, kind, self.borrowed_place) } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 8d5629270feea..06918d9ebab37 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -579,7 +579,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { fn report_local_value_does_not_live_long_enough( &mut self, context: Context, - name: &String, + name: &str, scope_tree: &Lrc, borrow: &BorrowData<'tcx>, drop_span: Span, @@ -1192,10 +1192,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Static(ref static_) => self.describe_field_from_ty(&static_.ty, field), Place::Projection(ref proj) => match proj.elem { ProjectionElem::Deref => self.describe_field(&proj.base, field), - ProjectionElem::Downcast(def, variant_index) => format!( - "{}", - def.variants[variant_index].fields[field.index()].ident - ), + ProjectionElem::Downcast(def, variant_index) => + def.variants[variant_index].fields[field.index()].ident.to_string(), ProjectionElem::Field(_, field_type) => { self.describe_field_from_ty(&field_type, field) } @@ -1783,8 +1781,8 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }), _, _, - ) => with_highlight_region_for_bound_region(*br, counter, || format!("{}", ty)), - _ => format!("{}", ty), + ) => with_highlight_region_for_bound_region(*br, counter, || ty.to_string()), + _ => ty.to_string(), } } @@ -1795,9 +1793,9 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { ty::TyKind::Ref(region, _, _) => match region { ty::RegionKind::ReLateBound(_, br) | ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }) => { - with_highlight_region_for_bound_region(*br, counter, || format!("{}", region)) + with_highlight_region_for_bound_region(*br, counter, || region.to_string()) } - _ => format!("{}", region), + _ => region.to_string(), }, _ => bug!("ty for annotation of borrow region is not a reference"), } diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index ea62694f8be75..a556199b875bf 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -331,7 +331,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { _ => { let source = self.borrowed_content_source(place); self.infcx.tcx.cannot_move_out_of( - span, &format!("{}", source), origin + span, &source.to_string(), origin ) }, } @@ -469,9 +469,9 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { let binding_span = bind_to.source_info.span; if j == 0 { - err.span_label(binding_span, format!("data moved here")); + err.span_label(binding_span, "data moved here"); } else { - err.span_label(binding_span, format!("...and here")); + err.span_label(binding_span, "...and here"); } if binds_to.len() == 1 { diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index f0b4a5ac7435b..30f4fc9d5ea23 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -504,7 +504,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { ); let extra = if found { - String::from("") + String::new() } else { format!(", but it is not implemented for `{}`", substs.type_at(0)) @@ -583,7 +583,7 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>( let ty = &src[ws_pos..]; return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty)); } else if src.starts_with('&') { - let borrowed_expr = src[1..].to_string(); + let borrowed_expr = &src[1..]; return (assignment_rhs_span, format!("&mut {}", borrowed_expr)); } } From cd03f5d1e06227261b310790d4a4d6a24002f1bd Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 16 Oct 2018 15:13:11 +0200 Subject: [PATCH 32/38] mir/borrowck: deduplicate assignments and returns --- src/librustc_mir/borrow_check/mod.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 59bb534881e33..ce0cc20f6de34 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1009,13 +1009,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { return Control::Continue; } + error_reported = true; match kind { ReadKind::Copy => { - error_reported = true; this.report_use_while_mutably_borrowed(context, place_span, borrow) } ReadKind::Borrow(bk) => { - error_reported = true; this.report_conflicting_borrow(context, place_span, bk, &borrow) } } @@ -1045,13 +1044,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Read(..) | Write(..) => {} } + error_reported = true; match kind { WriteKind::MutableBorrow(bk) => { - error_reported = true; this.report_conflicting_borrow(context, place_span, bk, &borrow) } WriteKind::StorageDeadOrDrop => { - error_reported = true; this.report_borrowed_value_does_not_live_long_enough( context, borrow, @@ -1059,11 +1057,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Some(kind)) } WriteKind::Mutate => { - error_reported = true; this.report_illegal_mutation_of_borrowed(context, place_span, borrow) } WriteKind::Move => { - error_reported = true; this.report_move_out_while_borrowed(context, place_span, &borrow) } } From f53d2b257cfef3e02192f2735924aaf1223818a0 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 16 Oct 2018 15:25:18 +0200 Subject: [PATCH 33/38] mir/borrowck: remove redundant returns --- src/librustc_mir/borrow_check/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index ce0cc20f6de34..aeb77c67317a0 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1589,7 +1589,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Local(_) => panic!("should have move path for every Local"), Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"), Place::Promoted(_) | - Place::Static(_) => return Err(NoMovePathFound::ReachedStatic), + Place::Static(_) => Err(NoMovePathFound::ReachedStatic), } } @@ -1881,7 +1881,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } // at this point, we have set up the error reporting state. - if previously_initialized { + return if previously_initialized { self.report_mutability_error( place, span, @@ -1889,10 +1889,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { error_access, location, ); - return true; + true } else { - return false; - } + false + }; } fn is_local_ever_initialized(&self, @@ -1907,7 +1907,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { return Some(index); } } - return None; + None } /// Adds the place into the used mutable variables set From 5620f6d2445c4b699c7cfa9020a2e9813a13a05c Mon Sep 17 00:00:00 2001 From: ljedrz Date: Tue, 16 Oct 2018 15:33:03 +0200 Subject: [PATCH 34/38] mir/borrowck: remove a redundant clone --- src/librustc_mir/borrow_check/error_reporting.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 06918d9ebab37..759b842e9dfee 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -77,9 +77,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { if move_out_indices.is_empty() { let root_place = self.prefixes(&used_place, PrefixSet::All).last().unwrap(); - if self.uninitialized_error_reported - .contains(&root_place.clone()) - { + if self.uninitialized_error_reported.contains(root_place) { debug!( "report_use_of_moved_or_uninitialized place: error about {:?} suppressed", root_place From e62ce98009fa4fc647220570ccb12927d3992ecb Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 17 Oct 2018 16:52:35 +0200 Subject: [PATCH 35/38] nll: improve allocations --- .../borrow_check/nll/constraint_generation.rs | 5 ++++- .../borrow_check/nll/explain_borrow/mod.rs | 10 ++++------ .../nll/region_infer/error_reporting/region_name.rs | 5 ++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 30b263a923a7f..495e84528a3c3 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -141,6 +141,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx if let Some(all_facts) = self.all_facts { if let Place::Local(temp) = place { if let Some(borrow_indices) = self.borrow_set.local_map.get(temp) { + all_facts.killed.reserve(borrow_indices.len()); for &borrow_index in borrow_indices { let location_index = self.location_table.mid_index(location); all_facts.killed.push((borrow_index, location_index)); @@ -164,7 +165,9 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx self.location_table.mid_index(location), )); - for successor_block in terminator.successors() { + let successor_blocks = terminator.successors(); + all_facts.cfg_edge.reserve(successor_blocks.size_hint().0); + for successor_block in successor_blocks { all_facts.cfg_edge.push(( self.location_table.mid_index(location), self.location_table diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 307112f8ba16a..a0ccfb8dc4c49 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -279,9 +279,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { pending_locations.push(target.start_location()); }, TerminatorKind::SwitchInt { ref targets, .. } => { - for target in targets { - pending_locations.push(target.start_location()); - } + pending_locations.extend( + targets.into_iter().map(|target| target.start_location())); }, TerminatorKind::Drop { target, unwind, .. } | TerminatorKind::DropAndReplace { target, unwind, .. } | @@ -303,9 +302,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { }, TerminatorKind::FalseEdges { real_target, ref imaginary_targets, .. } => { pending_locations.push(real_target.start_location()); - for target in imaginary_targets { - pending_locations.push(target.start_location()); - } + pending_locations.extend( + imaginary_targets.into_iter().map(|target| target.start_location())); }, _ => {}, } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 65ba2f537bf21..8d3cb7273181f 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -462,9 +462,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { argument_hir_ty: &hir::Ty, counter: &mut usize, ) -> Option { - let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> = &mut Vec::new(); - - search_stack.push((argument_ty, argument_hir_ty)); + let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> = + &mut vec![(argument_ty, argument_hir_ty)]; while let Some((ty, hir_ty)) = search_stack.pop() { match (&ty.sty, &hir_ty.node) { From 2bda0c196f7118971801b0f5d6ddce5c6fb74fd3 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 17 Oct 2018 16:54:17 +0200 Subject: [PATCH 36/38] nll: improve format operations --- .../borrow_check/nll/explain_borrow/mod.rs | 4 ++-- .../borrow_check/nll/region_infer/dump_mir.rs | 12 ++++++------ .../nll/region_infer/error_reporting/mod.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index a0ccfb8dc4c49..b58604d1bfe35 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -87,9 +87,9 @@ impl<'tcx> BorrowExplanation<'tcx> { // Otherwise, just report the whole type (and use // the intentionally fuzzy phrase "destructor") ty::Closure(..) => - ("destructor", format!("closure")), + ("destructor", "closure".to_owned()), ty::Generator(..) => - ("destructor", format!("generator")), + ("destructor", "generator".to_owned()), _ => ("destructor", format!("type `{}`", local_decl.ty)), }; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs index ee900afc44de8..268a37c708681 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs @@ -36,12 +36,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { let outlived_by = self.universal_region_relations.regions_outlived_by(region); writeln!( out, - "| {r:rw$} | {c:cw$} | {ob}", - r = format!("{:?}", region), + "| {r:rw$?} | {c:cw$?} | {ob:?}", + r = region, rw = REGION_WIDTH, - c = format!("{:?}", classification), + c = classification, cw = 8, // "External" at most - ob = format!("{:?}", outlived_by) + ob = outlived_by )?; } } @@ -51,8 +51,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { for region in self.regions() { writeln!( out, - "| {r:rw$} | {ui:4?} | {v}", - r = format!("{:?}", region), + "| {r:rw$?} | {ui:4?} | {v}", + r = region, rw = REGION_WIDTH, ui = self.region_universe(region), v = self.region_value_str(region), diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 8191dd720e7b2..5ff50c606d641 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -550,7 +550,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let span = infcx.tcx.def_span(*did); if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(span) { let suggestable_fr_name = if fr_name.was_named() { - format!("{}", fr_name) + fr_name.to_string() } else { "'_".to_string() }; From ffecbc5e1027aab54402817dd1874c715ec9ba05 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 17 Oct 2018 16:58:12 +0200 Subject: [PATCH 37/38] nll: improve common patterns --- .../borrow_check/nll/explain_borrow/mod.rs | 59 +++++++++---------- .../borrow_check/nll/invalidation.rs | 2 +- .../error_reporting/region_name.rs | 6 +- 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index b58604d1bfe35..a0f832c544934 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -439,17 +439,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Operand::Move(Place::Local(from)) if *from == target => { debug!("was_captured_by_trait_object: ty={:?}", ty); // Check the type for a trait object. - match ty.sty { + return match ty.sty { // `&dyn Trait` - ty::TyKind::Ref(_, ty, _) if ty.is_trait() => return true, + ty::TyKind::Ref(_, ty, _) if ty.is_trait() => true, // `Box` _ if ty.is_box() && ty.boxed_ty().is_trait() => - return true, + true, // `dyn Trait` - _ if ty.is_trait() => return true, + _ if ty.is_trait() => true, // Anything else. - _ => return false, - } + _ => false, + }; }, _ => return false, }, @@ -464,32 +464,29 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let terminator = block.terminator(); debug!("was_captured_by_trait_object: terminator={:?}", terminator); - match &terminator.kind { - TerminatorKind::Call { - destination: Some((Place::Local(dest), block)), - args, - .. - } => { - debug!( - "was_captured_by_trait_object: target={:?} dest={:?} args={:?}", - target, dest, args - ); - // Check if one of the arguments to this function is the target place. - let found_target = args.iter().any(|arg| { - if let Operand::Move(Place::Local(potential)) = arg { - *potential == target - } else { - false - } - }); - - // If it is, follow this to the next block and update the target. - if found_target { - target = *dest; - queue.push(block.start_location()); + if let TerminatorKind::Call { + destination: Some((Place::Local(dest), block)), + args, + .. + } = &terminator.kind { + debug!( + "was_captured_by_trait_object: target={:?} dest={:?} args={:?}", + target, dest, args + ); + // Check if one of the arguments to this function is the target place. + let found_target = args.iter().any(|arg| { + if let Operand::Move(Place::Local(potential)) = arg { + *potential == target + } else { + false } - }, - _ => {}, + }); + + // If it is, follow this to the next block and update the target. + if found_target { + target = *dest; + queue.push(block.start_location()); + } } } diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index a9b5531bae519..002f35880ae6b 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -35,7 +35,7 @@ pub(super) fn generate_invalidates<'cx, 'gcx, 'tcx>( mir: &Mir<'tcx>, borrow_set: &BorrowSet<'tcx>, ) { - if !all_facts.is_some() { + if all_facts.is_none() { // Nothing to do if we don't have any facts return; } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 8d3cb7273181f..e07dfda406b19 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -566,10 +566,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { | hir::LifetimeName::Underscore => { let region_name = self.synthesize_region_name(counter); let ampersand_span = lifetime.span; - return Some(RegionName { + Some(RegionName { name: region_name, source: RegionNameSource::MatchedAdtAndSegment(ampersand_span), - }); + }) } hir::LifetimeName::Implicit => { @@ -584,7 +584,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // T>`. We don't consider this a match; instead we let // the "fully elaborated" type fallback above handle // it. - return None; + None } } } From c55e1e69e32686b5d10fb5df650ec8cbee8b19fb Mon Sep 17 00:00:00 2001 From: Alexander Komarov Date: Wed, 17 Oct 2018 23:58:21 +0300 Subject: [PATCH 38/38] [librustdoc] Disable spellcheck for search field --- src/librustdoc/html/layout.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 582f31ce7c716..6868c7707adc8 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -83,6 +83,7 @@ pub fn render(
\ \ \