diff options
| author | bors <bors@rust-lang.org> | 2021-02-27 02:18:11 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-02-27 02:18:11 +0000 |
| commit | 9fa580b1175018b0a276b0bc68f9827a106f7260 (patch) | |
| tree | 59c6d8c32cb9915f5ef2e461cda52c68ad4d87ba /compiler | |
| parent | 3da2dd3eae7b7cbf16960ab993de666470e43991 (diff) | |
| parent | 95b31cf94964dcd082c32b41de112541873c2d8b (diff) | |
| download | rust-9fa580b1175018b0a276b0bc68f9827a106f7260.tar.gz rust-9fa580b1175018b0a276b0bc68f9827a106f7260.zip | |
Auto merge of #82577 - Dylan-DPC:rollup-c3si8ju, r=Dylan-DPC
Rollup of 14 pull requests Successful merges: - #81794 (update tracking issue for `relaxed_struct_unsize`) - #82057 (Replace const_cstr with cstr crate) - #82370 (Improve anonymous lifetime note to indicate the target span) - #82394 (:arrow_up: rust-analyzer) - #82396 (Add Future trait for doc_spotlight feature doc) - #82404 (Test hexagon-enum only when llvm target is present) - #82419 (expand: Preserve order of inert attributes during expansion) - #82420 (Enable API documentation for `std::os::wasi`.) - #82421 (Add a `size()` function to WASI's `MetadataExt`.) - #82442 (Skip emitting closure diagnostic when closure_kind_origins has no entry) - #82473 (Use libc::accept4 on Android instead of raw syscall.) - #82482 (Use small hash set in `mir_inliner_callees`) - #82490 (Update cargo) - #82494 (Substitute erased lifetimes on bad placeholder type) Failed merges: - #82448 (Combine HasAttrs and HasTokens into AstLike) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
19 files changed, 157 insertions, 166 deletions
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index ebbb852f21c..260edd9570b 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -10,6 +10,7 @@ doctest = false [dependencies] bitflags = "1.0" +cstr = "0.2" libc = "0.2" measureme = "9.0.0" snap = "1" diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index a69241e456f..d714ff1fe9b 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -554,7 +554,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { llvm::AddCallSiteAttrString( callsite, llvm::AttributePlace::Function, - rustc_data_structures::const_cstr!("cmse_nonsecure_call"), + cstr::cstr!("cmse_nonsecure_call"), ); } } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 26111729ba5..09ece6164eb 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -2,8 +2,8 @@ use std::ffi::CString; +use cstr::cstr; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::const_cstr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; @@ -75,8 +75,8 @@ pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("frame-pointer"), - const_cstr!("all"), + cstr!("frame-pointer"), + cstr!("all"), ); } } @@ -95,7 +95,7 @@ fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("instrument-function-entry-inlined"), + cstr!("instrument-function-entry-inlined"), &mcount_name, ); } @@ -129,16 +129,16 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { StackProbeType::None => None, // Request LLVM to generate the probes inline. If the given LLVM version does not support // this, no probe is generated at all (even if the attribute is specified). - StackProbeType::Inline => Some(const_cstr!("inline-asm")), + StackProbeType::Inline => Some(cstr!("inline-asm")), // Flag our internal `__rust_probestack` function as the stack probe symbol. // This is defined in the `compiler-builtins` crate for each architecture. - StackProbeType::Call => Some(const_cstr!("__rust_probestack")), + StackProbeType::Call => Some(cstr!("__rust_probestack")), // Pick from the two above based on the LLVM version. StackProbeType::InlineOrCall { min_llvm_version_for_inline } => { if llvm_util::get_version() < min_llvm_version_for_inline { - Some(const_cstr!("__rust_probestack")) + Some(cstr!("__rust_probestack")) } else { - Some(const_cstr!("inline-asm")) + Some(cstr!("inline-asm")) } } }; @@ -146,7 +146,7 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("probe-stack"), + cstr!("probe-stack"), attr_value, ); } @@ -169,7 +169,7 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("target-cpu"), + cstr!("target-cpu"), target_cpu.as_c_str(), ); } @@ -180,7 +180,7 @@ pub fn apply_tune_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("tune-cpu"), + cstr!("tune-cpu"), tune_cpu.as_c_str(), ); } @@ -289,7 +289,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn); } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) { - llvm::AddFunctionAttrString(llfn, Function, const_cstr!("cmse_nonsecure_entry")); + llvm::AddFunctionAttrString(llfn, Function, cstr!("cmse_nonsecure_entry")); } sanitize(cx, codegen_fn_attrs.no_sanitize, llfn); @@ -319,7 +319,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("target-features"), + cstr!("target-features"), &val, ); } @@ -332,7 +332,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("wasm-import-module"), + cstr!("wasm-import-module"), &module, ); @@ -342,7 +342,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty:: llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, - const_cstr!("wasm-import-name"), + cstr!("wasm-import-name"), &name, ); } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index d2f4d3edc22..f4852c91e53 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -5,13 +5,13 @@ use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; +use cstr::cstr; use libc::{c_char, c_uint}; use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::MemFlags; -use rustc_data_structures::const_cstr; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; use rustc_middle::ty::layout::TyAndLayout; @@ -979,7 +979,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> { - let name = const_cstr!("cleanuppad"); + let name = cstr!("cleanuppad"); let ret = unsafe { llvm::LLVMRustBuildCleanupPad( self.llbuilder, @@ -1003,7 +1003,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> { - let name = const_cstr!("catchpad"); + let name = cstr!("catchpad"); let ret = unsafe { llvm::LLVMRustBuildCatchPad( self.llbuilder, @@ -1022,7 +1022,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { unwind: Option<&'ll BasicBlock>, num_handlers: usize, ) -> &'ll Value { - let name = const_cstr!("catchswitch"); + let name = cstr!("catchswitch"); let ret = unsafe { llvm::LLVMRustBuildCatchSwitch( self.llbuilder, diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 16e1a8a1242..99046839973 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -5,9 +5,9 @@ use crate::llvm::{self, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; +use cstr::cstr; use libc::c_uint; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::const_cstr; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ @@ -419,9 +419,9 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> { .all(|&byte| byte == 0); let sect_name = if all_bytes_are_zero { - const_cstr!("__DATA,__thread_bss") + cstr!("__DATA,__thread_bss") } else { - const_cstr!("__DATA,__thread_data") + cstr!("__DATA,__thread_data") }; llvm::LLVMSetSection(g, sect_name.as_ptr()); } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index ee099f93258..3ddc7424202 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -7,10 +7,10 @@ use crate::llvm_util; use crate::type_::Type; use crate::value::Value; +use cstr::cstr; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n; -use rustc_data_structures::const_cstr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::small_c_str::SmallCStr; use rustc_middle::bug; @@ -414,8 +414,8 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn create_used_variable(&self) { - let name = const_cstr!("llvm.used"); - let section = const_cstr!("llvm.metadata"); + let name = cstr!("llvm.used"); + let section = cstr!("llvm.metadata"); let array = self.const_array(&self.type_ptr_to(self.type_i8()), &*self.used_statics.borrow()); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 1464784ae28..85d1b702399 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -18,8 +18,8 @@ use crate::llvm::debuginfo::{ }; use crate::value::Value; +use cstr::cstr; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::const_cstr; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -1075,7 +1075,7 @@ pub fn compile_unit_metadata( gcov_cu_info.len() as c_uint, ); - let llvm_gcov_ident = const_cstr!("llvm.gcov"); + let llvm_gcov_ident = cstr!("llvm.gcov"); llvm::LLVMAddNamedMetadataOperand( debug_context.llmod, llvm_gcov_ident.as_ptr(), @@ -1093,7 +1093,7 @@ pub fn compile_unit_metadata( ); llvm::LLVMAddNamedMetadataOperand( debug_context.llmod, - const_cstr!("llvm.ident").as_ptr(), + cstr!("llvm.ident").as_ptr(), llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1), ); } diff --git a/compiler/rustc_data_structures/src/const_cstr.rs b/compiler/rustc_data_structures/src/const_cstr.rs deleted file mode 100644 index 1ebcb87818e..00000000000 --- a/compiler/rustc_data_structures/src/const_cstr.rs +++ /dev/null @@ -1,30 +0,0 @@ -/// This macro creates a zero-overhead &CStr by adding a NUL terminator to -/// the string literal passed into it at compile-time. Use it like: -/// -/// ``` -/// let some_const_cstr = const_cstr!("abc"); -/// ``` -/// -/// The above is roughly equivalent to: -/// -/// ``` -/// let some_const_cstr = CStr::from_bytes_with_nul(b"abc\0").unwrap() -/// ``` -/// -/// Note that macro only checks the string literal for internal NULs if -/// debug-assertions are enabled in order to avoid runtime overhead in release -/// builds. -#[macro_export] -macro_rules! const_cstr { - ($s:expr) => {{ - use std::ffi::CStr; - - let str_plus_nul = concat!($s, "\0"); - - if cfg!(debug_assertions) { - CStr::from_bytes_with_nul(str_plus_nul.as_bytes()).unwrap() - } else { - unsafe { CStr::from_bytes_with_nul_unchecked(str_plus_nul.as_bytes()) } - } - }}; -} diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 4ab493d3cc9..fcb2bca7b4c 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -69,7 +69,6 @@ pub mod base_n; pub mod binary_search_util; pub mod box_region; pub mod captures; -pub mod const_cstr; pub mod flock; pub mod functor; pub mod fx; diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 5a4737842f0..10c19ea105e 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -301,6 +301,8 @@ pub enum InvocationKind { }, Attr { attr: ast::Attribute, + // Re-insertion position for inert attributes. + pos: usize, item: Annotatable, // Required for resolving derive helper attributes. derives: Vec<Path>, @@ -690,7 +692,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => unreachable!(), }, - InvocationKind::Attr { attr, mut item, derives } => match ext { + InvocationKind::Attr { attr, pos, mut item, derives } => match ext { SyntaxExtensionKind::Attr(expander) => { self.gate_proc_macro_input(&item); self.gate_proc_macro_attr_item(span, &item); @@ -721,7 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ExpandResult::Retry(item) => { // Reassemble the original invocation for retrying. return ExpandResult::Retry(Invocation { - kind: InvocationKind::Attr { attr, item, derives }, + kind: InvocationKind::Attr { attr, pos, item, derives }, ..invoc }); } @@ -739,7 +741,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if *mark_used { self.cx.sess.mark_attr_used(&attr); } - item.visit_attrs(|attrs| attrs.push(attr)); + item.visit_attrs(|attrs| attrs.insert(pos, attr)); fragment_kind.expect_from_annotatables(iter::once(item)) } _ => unreachable!(), @@ -1000,17 +1002,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect_attr( &mut self, - (attr, derives): (ast::Attribute, Vec<Path>), + (attr, pos, derives): (ast::Attribute, usize, Vec<Path>), item: Annotatable, kind: AstFragmentKind, ) -> AstFragment { - self.collect(kind, InvocationKind::Attr { attr, item, derives }) + self.collect(kind, InvocationKind::Attr { attr, pos, item, derives }) } /// If `item` is an attribute invocation, remove the attribute and return it together with - /// derives following it. We have to collect the derives in order to resolve legacy derive - /// helpers (helpers written before derives that introduce them). - fn take_first_attr(&mut self, item: &mut impl HasAttrs) -> Option<(ast::Attribute, Vec<Path>)> { + /// its position and derives following it. We have to collect the derives in order to resolve + /// legacy derive helpers (helpers written before derives that introduce them). + fn take_first_attr( + &mut self, + item: &mut impl HasAttrs, + ) -> Option<(ast::Attribute, usize, Vec<Path>)> { let mut attr = None; item.visit_attrs(|attrs| { @@ -1033,7 +1038,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { }) .collect(); - (attr, following_derives) + (attr, attr_pos, following_derives) }) }); diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 3f484ab5686..6960b735f33 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -633,7 +633,7 @@ declare_features! ( (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None), /// Lessens the requirements for structs to implement `Unsize`. - (active, relaxed_struct_unsize, "1.51.0", Some(1), None), + (active, relaxed_struct_unsize, "1.51.0", Some(81793), None), /// Allows macro attributes to observe output of `#[derive]`. (active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None), diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 2d5f43e5890..eeff48a6395 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -50,6 +50,7 @@ use super::region_constraints::GenericKind; use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs}; use crate::infer; +use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::traits::error_reporting::report_object_safety_error; use crate::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, @@ -179,7 +180,14 @@ fn msg_span_from_early_bound_and_free_regions( } ty::ReFree(ref fr) => match fr.bound_region { ty::BrAnon(idx) => { - (format!("the anonymous lifetime #{} defined on", idx + 1), tcx.hir().span(node)) + if let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { + ("the anonymous lifetime defined on".to_string(), ty.span) + } else { + ( + format!("the anonymous lifetime #{} defined on", idx + 1), + tcx.hir().span(node), + ) + } } _ => ( format!("the lifetime `{}` as defined on", region), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index cdd68d83f22..1b35c4032f4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -1,6 +1,7 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where both the regions are anonymous. +use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; @@ -66,9 +67,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let scope_def_id_sub = anon_reg_sub.def_id; let bregion_sub = anon_reg_sub.boundregion; - let ty_sup = self.find_anon_type(sup, &bregion_sup)?; + let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?; - let ty_sub = self.find_anon_type(sub, &bregion_sub)?; + let ty_sub = find_anon_type(self.tcx(), sub, &bregion_sub)?; debug!( "try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}", diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index b014b9832e7..ffdaedf8666 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -1,4 +1,3 @@ -use crate::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_hir as hir; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::Node; @@ -6,67 +5,64 @@ use rustc_middle::hir::map::Map; use rustc_middle::middle::resolve_lifetime as rl; use rustc_middle::ty::{self, Region, TyCtxt}; -impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { - /// This function calls the `visit_ty` method for the parameters - /// corresponding to the anonymous regions. The `nested_visitor.found_type` - /// contains the anonymous type. - /// - /// # Arguments - /// region - the anonymous region corresponding to the anon_anon conflict - /// br - the bound region corresponding to the above region which is of type `BrAnon(_)` - /// - /// # Example - /// ``` - /// fn foo(x: &mut Vec<&u8>, y: &u8) - /// { x.push(y); } - /// ``` - /// The function returns the nested type corresponding to the anonymous region - /// for e.g., `&u8` and Vec<`&u8`. - pub(super) fn find_anon_type( - &self, - region: Region<'tcx>, - br: &ty::BoundRegionKind, - ) -> Option<(&hir::Ty<'tcx>, &hir::FnDecl<'tcx>)> { - if let Some(anon_reg) = self.tcx().is_suitable_region(region) { - let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id); - let fndecl = match self.tcx().hir().get(hir_id) { - Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. }) - | Node::TraitItem(&hir::TraitItem { - kind: hir::TraitItemKind::Fn(ref m, ..), - .. - }) - | Node::ImplItem(&hir::ImplItem { - kind: hir::ImplItemKind::Fn(ref m, ..), .. - }) => &m.decl, - _ => return None, - }; +/// This function calls the `visit_ty` method for the parameters +/// corresponding to the anonymous regions. The `nested_visitor.found_type` +/// contains the anonymous type. +/// +/// # Arguments +/// region - the anonymous region corresponding to the anon_anon conflict +/// br - the bound region corresponding to the above region which is of type `BrAnon(_)` +/// +/// # Example +/// ``` +/// fn foo(x: &mut Vec<&u8>, y: &u8) +/// { x.push(y); } +/// ``` +/// The function returns the nested type corresponding to the anonymous region +/// for e.g., `&u8` and Vec<`&u8`. +pub(crate) fn find_anon_type( + tcx: TyCtxt<'tcx>, + region: Region<'tcx>, + br: &ty::BoundRegionKind, +) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnDecl<'tcx>)> { + if let Some(anon_reg) = tcx.is_suitable_region(region) { + let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id); + let fndecl = match tcx.hir().get(hir_id) { + Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. }) + | Node::TraitItem(&hir::TraitItem { + kind: hir::TraitItemKind::Fn(ref m, ..), .. + }) + | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref m, ..), .. }) => { + &m.decl + } + _ => return None, + }; - fndecl - .inputs - .iter() - .find_map(|arg| self.find_component_for_bound_region(arg, br)) - .map(|ty| (ty, &**fndecl)) - } else { - None - } + fndecl + .inputs + .iter() + .find_map(|arg| find_component_for_bound_region(tcx, arg, br)) + .map(|ty| (ty, &**fndecl)) + } else { + None } +} - // This method creates a FindNestedTypeVisitor which returns the type corresponding - // to the anonymous region. - fn find_component_for_bound_region( - &self, - arg: &'tcx hir::Ty<'tcx>, - br: &ty::BoundRegionKind, - ) -> Option<&'tcx hir::Ty<'tcx>> { - let mut nested_visitor = FindNestedTypeVisitor { - tcx: self.tcx(), - bound_region: *br, - found_type: None, - current_index: ty::INNERMOST, - }; - nested_visitor.visit_ty(arg); - nested_visitor.found_type - } +// This method creates a FindNestedTypeVisitor which returns the type corresponding +// to the anonymous region. +fn find_component_for_bound_region( + tcx: TyCtxt<'tcx>, + arg: &'tcx hir::Ty<'tcx>, + br: &ty::BoundRegionKind, +) -> Option<&'tcx hir::Ty<'tcx>> { + let mut nested_visitor = FindNestedTypeVisitor { + tcx, + bound_region: *br, + found_type: None, + current_index: ty::INNERMOST, + }; + nested_visitor.visit_ty(arg); + nested_visitor.found_type } // The FindNestedTypeVisitor captures the corresponding `hir::Ty` of the diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index 0599c78ebfd..e20436690b3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -6,7 +6,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_span::source_map::Span; mod different_lifetimes; -mod find_anon_type; +pub mod find_anon_type; mod named_anon_conflict; mod placeholder_error; mod static_impl_trait; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 2f622231a08..2f3c0d6957a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -1,5 +1,6 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where one region is named and the other is anonymous. +use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir::intravisit::Visitor; @@ -74,7 +75,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { return None; } - if let Some((_, fndecl)) = self.find_anon_type(anon, &br) { + if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) { if self.is_self_anon(is_first, scope_def_id) { return None; } diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index 0400431a542..2f40a90fb55 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs @@ -513,32 +513,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let id = id.expect_local(); let tables = tcx.typeck(id); let hir_id = tcx.hir().local_def_id_to_hir_id(id); - let (span, place) = &tables.closure_kind_origins()[hir_id]; - let reason = if let PlaceBase::Upvar(upvar_id) = place.base { - let upvar = ty::place_to_string_for_capture(tcx, place); - match tables.upvar_capture(upvar_id) { - ty::UpvarCapture::ByRef(ty::UpvarBorrow { - kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow, - .. - }) => { - format!("mutable borrow of `{}`", upvar) - } - ty::UpvarCapture::ByValue(_) => { - format!("possible mutation of `{}`", upvar) + if let Some((span, place)) = tables.closure_kind_origins().get(hir_id) { + let reason = if let PlaceBase::Upvar(upvar_id) = place.base { + let upvar = ty::place_to_string_for_capture(tcx, place); + match tables.upvar_capture(upvar_id) { + ty::UpvarCapture::ByRef(ty::UpvarBorrow { + kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow, + .. + }) => { + format!("mutable borrow of `{}`", upvar) + } + ty::UpvarCapture::ByValue(_) => { + format!("possible mutation of `{}`", upvar) + } + val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val), } - val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val), - } - } else { - bug!("not an upvar") - }; - err.span_label( - *span, - format!( - "calling `{}` requires mutable binding due to {}", - self.describe_place(the_place_err).unwrap(), - reason - ), - ); + } else { + bug!("not an upvar") + }; + err.span_label( + *span, + format!( + "calling `{}` requires mutable binding due to {}", + self.describe_place(the_place_err).unwrap(), + reason + ), + ); + } } // Attempt to search similar mutable associated items for suggestion. diff --git a/compiler/rustc_mir/src/transform/inline/cycle.rs b/compiler/rustc_mir/src/transform/inline/cycle.rs index 4c24bec0ce3..295f3ec70dc 100644 --- a/compiler/rustc_mir/src/transform/inline/cycle.rs +++ b/compiler/rustc_mir/src/transform/inline/cycle.rs @@ -1,4 +1,5 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir::TerminatorKind; @@ -140,7 +141,7 @@ crate fn mir_inliner_callees<'tcx>( // Functions from other crates and MIR shims _ => tcx.instance_mir(instance), }; - let mut calls = Vec::new(); + let mut calls = SsoHashSet::new(); for bb_data in body.basic_blocks() { let terminator = bb_data.terminator(); if let TerminatorKind::Call { func, .. } = &terminator.kind { @@ -149,12 +150,8 @@ crate fn mir_inliner_callees<'tcx>( ty::FnDef(def_id, substs) => (*def_id, *substs), _ => continue, }; - // We've seen this before - if calls.contains(&call) { - continue; - } - calls.push(call); + calls.insert(call); } } - tcx.arena.alloc_slice(&calls) + tcx.arena.alloc_from_iter(calls.iter().copied()) } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 9fbc56f051b..3881d55ef91 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -371,6 +371,11 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { span: Span, ) -> &'tcx Const<'tcx> { bad_placeholder_type(self.tcx(), vec![span]).emit(); + // Typeck doesn't expect erased regions to be returned from `type_of`. + let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r { + ty::ReErased => self.tcx.lifetimes.re_static, + _ => r, + }); self.tcx().const_error(ty) } @@ -1647,6 +1652,12 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { match get_infer_ret_ty(&sig.decl.output) { Some(ty) => { let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id]; + // Typeck doesn't expect erased regions to be returned from `type_of`. + let fn_sig = tcx.fold_regions(fn_sig, &mut false, |r, _| match r { + ty::ReErased => tcx.lifetimes.re_static, + _ => r, + }); + let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_ty(ty); let mut diag = bad_placeholder_type(tcx, visitor.0); @@ -1675,6 +1686,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { } } diag.emit(); + ty::Binder::bind(fn_sig) } None => AstConv::ty_of_fn( |
