diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 80633e141fc6d..16cd7a0bcdd39 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1186,9 +1186,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } None => self - .loop_scopes - .last() - .cloned() + .loop_scope .map(|id| Ok(self.lower_node_id(id))) .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope)), }; @@ -1208,18 +1206,9 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn with_catch_scope(&mut self, catch_id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { - let len = self.catch_scopes.len(); - self.catch_scopes.push(catch_id); - + let old_scope = self.catch_scope.replace(catch_id); let result = f(self); - assert_eq!( - len + 1, - self.catch_scopes.len(), - "catch scopes should be added and removed in stack order" - ); - - self.catch_scopes.pop().unwrap(); - + self.catch_scope = old_scope; result } @@ -1228,17 +1217,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; - let len = self.loop_scopes.len(); - self.loop_scopes.push(loop_id); - + let old_scope = self.loop_scope.replace(loop_id); let result = f(self); - assert_eq!( - len + 1, - self.loop_scopes.len(), - "loop scopes should be added and removed in stack order" - ); - - self.loop_scopes.pop().unwrap(); + self.loop_scope = old_scope; self.is_in_loop_condition = was_in_loop_condition; @@ -1565,8 +1546,7 @@ impl<'hir> LoweringContext<'_, 'hir> { unstable_span, ); let thin_attrs = ThinVec::from(attrs); - let catch_scope = self.catch_scopes.last().copied(); - let ret_expr = if let Some(catch_node) = catch_scope { + let ret_expr = if let Some(catch_node) = self.catch_scope { let target_id = Ok(self.lower_node_id(catch_node)); self.arena.alloc(self.expr( try_span, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8fd8075725b48..5391d4b0c9363 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -64,7 +64,6 @@ use rustc_span::{Span, DUMMY_SP}; use smallvec::SmallVec; use std::collections::BTreeMap; -use std::mem; use tracing::{debug, trace}; macro_rules! arena_vec { @@ -117,8 +116,8 @@ struct LoweringContext<'a, 'hir: 'a> { /// outside of an `async fn`. current_item: Option, - catch_scopes: Vec, - loop_scopes: Vec, + catch_scope: Option, + loop_scope: Option, is_in_loop_condition: bool, is_in_trait_impl: bool, is_in_dyn_type: bool, @@ -323,8 +322,8 @@ pub fn lower_crate<'a, 'hir>( bodies: BTreeMap::new(), modules: BTreeMap::new(), attrs: BTreeMap::default(), - catch_scopes: Vec::new(), - loop_scopes: Vec::new(), + catch_scope: None, + loop_scope: None, is_in_loop_condition: false, is_in_trait_impl: false, is_in_dyn_type: false, @@ -911,11 +910,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; - let catch_scopes = mem::take(&mut self.catch_scopes); - let loop_scopes = mem::take(&mut self.loop_scopes); + let catch_scope = self.catch_scope.take(); + let loop_scope = self.loop_scope.take(); let ret = f(self); - self.catch_scopes = catch_scopes; - self.loop_scopes = loop_scopes; + self.catch_scope = catch_scope; + self.loop_scope = loop_scope; self.is_in_loop_condition = was_in_loop_condition; @@ -1497,20 +1496,50 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.allocate_hir_id_counter(opaque_ty_node_id); - let hir_bounds = self.with_hir_id_owner(opaque_ty_node_id, lower_bounds); + let collected_lifetimes = self.with_hir_id_owner(opaque_ty_node_id, move |lctx| { + let hir_bounds = lower_bounds(lctx); - let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds( - opaque_ty_node_id, - opaque_ty_def_id, - &hir_bounds, - capturable_lifetimes, - ); + let collected_lifetimes = lifetimes_from_impl_trait_bounds( + opaque_ty_node_id, + &hir_bounds, + capturable_lifetimes, + ); - debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes); + let lifetime_defs = + lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(|&(name, span)| { + let def_node_id = lctx.resolver.next_node_id(); + let hir_id = lctx.lower_node_id(def_node_id); + lctx.resolver.create_def( + opaque_ty_def_id, + def_node_id, + DefPathData::LifetimeNs(name.ident().name), + ExpnId::root(), + span, + ); - debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs); + let (name, kind) = match name { + hir::LifetimeName::Underscore => ( + hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)), + hir::LifetimeParamKind::Elided, + ), + hir::LifetimeName::Param(param_name) => { + (param_name, hir::LifetimeParamKind::Explicit) + } + _ => panic!("expected `LifetimeName::Param` or `ParamName::Plain`"), + }; + + hir::GenericParam { + hir_id, + name, + span, + pure_wrt_drop: false, + bounds: &[], + kind: hir::GenericParamKind::Lifetime { kind }, + } + })); + + debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs); - self.with_hir_id_owner(opaque_ty_node_id, move |lctx| { let opaque_ty_item = hir::OpaqueTy { generics: hir::Generics { params: lifetime_defs, @@ -1525,9 +1554,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id); lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span); - // `impl Trait` now just becomes `Foo<'a, 'b, ..>`. - hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes) - }) + collected_lifetimes + }); + + let lifetimes = + self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(name, span)| { + hir::GenericArg::Lifetime(hir::Lifetime { hir_id: self.next_id(), span, name }) + })); + + debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes); + + // `impl Trait` now just becomes `Foo<'a, 'b, ..>`. + hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes) } /// Registers a new opaque type with the proper `NodeId`s and @@ -1556,193 +1594,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.insert_item(opaque_ty_item); } - fn lifetimes_from_impl_trait_bounds( - &mut self, - opaque_ty_id: NodeId, - parent_def_id: LocalDefId, - bounds: hir::GenericBounds<'hir>, - lifetimes_to_include: Option<&FxHashSet>, - ) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) { - debug!( - "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \ - parent_def_id={:?}, \ - bounds={:#?})", - opaque_ty_id, parent_def_id, bounds, - ); - - // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that - // appear in the bounds, excluding lifetimes that are created within the bounds. - // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`. - struct ImplTraitLifetimeCollector<'r, 'a, 'hir> { - context: &'r mut LoweringContext<'a, 'hir>, - parent: LocalDefId, - opaque_ty_id: NodeId, - collect_elided_lifetimes: bool, - currently_bound_lifetimes: Vec, - already_defined_lifetimes: FxHashSet, - output_lifetimes: Vec>, - output_lifetime_params: Vec>, - lifetimes_to_include: Option<&'r FxHashSet>, - } - - impl<'r, 'a, 'v, 'hir> intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> { - type Map = intravisit::ErasedMap<'v>; - - fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { - intravisit::NestedVisitorMap::None - } - - fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs<'v>) { - // Don't collect elided lifetimes used inside of `Fn()` syntax. - if parameters.parenthesized { - let old_collect_elided_lifetimes = self.collect_elided_lifetimes; - self.collect_elided_lifetimes = false; - intravisit::walk_generic_args(self, span, parameters); - self.collect_elided_lifetimes = old_collect_elided_lifetimes; - } else { - intravisit::walk_generic_args(self, span, parameters); - } - } - - fn visit_ty(&mut self, t: &'v hir::Ty<'v>) { - // Don't collect elided lifetimes used inside of `fn()` syntax. - if let hir::TyKind::BareFn(_) = t.kind { - let old_collect_elided_lifetimes = self.collect_elided_lifetimes; - self.collect_elided_lifetimes = false; - - // Record the "stack height" of `for<'a>` lifetime bindings - // to be able to later fully undo their introduction. - let old_len = self.currently_bound_lifetimes.len(); - intravisit::walk_ty(self, t); - self.currently_bound_lifetimes.truncate(old_len); - - self.collect_elided_lifetimes = old_collect_elided_lifetimes; - } else { - intravisit::walk_ty(self, t) - } - } - - fn visit_poly_trait_ref( - &mut self, - trait_ref: &'v hir::PolyTraitRef<'v>, - modifier: hir::TraitBoundModifier, - ) { - // Record the "stack height" of `for<'a>` lifetime bindings - // to be able to later fully undo their introduction. - let old_len = self.currently_bound_lifetimes.len(); - intravisit::walk_poly_trait_ref(self, trait_ref, modifier); - self.currently_bound_lifetimes.truncate(old_len); - } - - fn visit_generic_param(&mut self, param: &'v hir::GenericParam<'v>) { - // Record the introduction of 'a in `for<'a> ...`. - if let hir::GenericParamKind::Lifetime { .. } = param.kind { - // Introduce lifetimes one at a time so that we can handle - // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`. - let lt_name = hir::LifetimeName::Param(param.name); - self.currently_bound_lifetimes.push(lt_name); - } - - intravisit::walk_generic_param(self, param); - } - - fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) { - let name = match lifetime.name { - hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => { - if self.collect_elided_lifetimes { - // Use `'_` for both implicit and underscore lifetimes in - // `type Foo<'_> = impl SomeTrait<'_>;`. - hir::LifetimeName::Underscore - } else { - return; - } - } - hir::LifetimeName::Param(_) => lifetime.name, - - // Refers to some other lifetime that is "in - // scope" within the type. - hir::LifetimeName::ImplicitObjectLifetimeDefault => return, - - hir::LifetimeName::Error | hir::LifetimeName::Static => return, - }; - - if !self.currently_bound_lifetimes.contains(&name) - && !self.already_defined_lifetimes.contains(&name) - && self.lifetimes_to_include.map_or(true, |lifetimes| lifetimes.contains(&name)) - { - self.already_defined_lifetimes.insert(name); - - self.output_lifetimes.push(hir::GenericArg::Lifetime(hir::Lifetime { - hir_id: self.context.next_id(), - span: self.context.lower_span(lifetime.span), - name, - })); - - let def_node_id = self.context.resolver.next_node_id(); - let hir_id = - self.context.lower_node_id_with_owner(def_node_id, self.opaque_ty_id); - self.context.resolver.create_def( - self.parent, - def_node_id, - DefPathData::LifetimeNs(name.ident().name), - ExpnId::root(), - lifetime.span, - ); - - let (name, kind) = match name { - hir::LifetimeName::Underscore => ( - hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)), - hir::LifetimeParamKind::Elided, - ), - hir::LifetimeName::Param(param_name) => { - (param_name, hir::LifetimeParamKind::Explicit) - } - _ => panic!("expected `LifetimeName::Param` or `ParamName::Plain`"), - }; - let name = match name { - hir::ParamName::Plain(ident) => { - hir::ParamName::Plain(self.context.lower_ident(ident)) - } - name => name, - }; - - self.output_lifetime_params.push(hir::GenericParam { - hir_id, - name, - span: self.context.lower_span(lifetime.span), - pure_wrt_drop: false, - bounds: &[], - kind: hir::GenericParamKind::Lifetime { kind }, - }); - } - } - } - - let mut lifetime_collector = ImplTraitLifetimeCollector { - context: self, - parent: parent_def_id, - opaque_ty_id, - collect_elided_lifetimes: true, - currently_bound_lifetimes: Vec::new(), - already_defined_lifetimes: FxHashSet::default(), - output_lifetimes: Vec::new(), - output_lifetime_params: Vec::new(), - lifetimes_to_include, - }; - - for bound in bounds { - intravisit::walk_param_bound(&mut lifetime_collector, &bound); - } - - let ImplTraitLifetimeCollector { output_lifetimes, output_lifetime_params, .. } = - lifetime_collector; - - ( - self.arena.alloc_from_iter(output_lifetimes), - self.arena.alloc_from_iter(output_lifetime_params), - ) - } - fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] { // Skip the `...` (`CVarArgs`) trailing arguments from the AST, // as they are not explicit in HIR/Ty function signatures. @@ -2723,3 +2574,132 @@ impl<'hir> GenericArgsCtor<'hir> { this.arena.alloc(ga) } } + +fn lifetimes_from_impl_trait_bounds( + opaque_ty_id: NodeId, + bounds: hir::GenericBounds<'_>, + lifetimes_to_include: Option<&FxHashSet>, +) -> Vec<(hir::LifetimeName, Span)> { + debug!( + "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \ + bounds={:#?})", + opaque_ty_id, bounds, + ); + + // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that + // appear in the bounds, excluding lifetimes that are created within the bounds. + // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`. + struct ImplTraitLifetimeCollector<'r> { + collect_elided_lifetimes: bool, + currently_bound_lifetimes: Vec, + already_defined_lifetimes: FxHashSet, + lifetimes: Vec<(hir::LifetimeName, Span)>, + lifetimes_to_include: Option<&'r FxHashSet>, + } + + impl<'r, 'v> intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r> { + type Map = intravisit::ErasedMap<'v>; + + fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { + intravisit::NestedVisitorMap::None + } + + fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs<'v>) { + // Don't collect elided lifetimes used inside of `Fn()` syntax. + if parameters.parenthesized { + let old_collect_elided_lifetimes = self.collect_elided_lifetimes; + self.collect_elided_lifetimes = false; + intravisit::walk_generic_args(self, span, parameters); + self.collect_elided_lifetimes = old_collect_elided_lifetimes; + } else { + intravisit::walk_generic_args(self, span, parameters); + } + } + + fn visit_ty(&mut self, t: &'v hir::Ty<'v>) { + // Don't collect elided lifetimes used inside of `fn()` syntax. + if let hir::TyKind::BareFn(_) = t.kind { + let old_collect_elided_lifetimes = self.collect_elided_lifetimes; + self.collect_elided_lifetimes = false; + + // Record the "stack height" of `for<'a>` lifetime bindings + // to be able to later fully undo their introduction. + let old_len = self.currently_bound_lifetimes.len(); + intravisit::walk_ty(self, t); + self.currently_bound_lifetimes.truncate(old_len); + + self.collect_elided_lifetimes = old_collect_elided_lifetimes; + } else { + intravisit::walk_ty(self, t) + } + } + + fn visit_poly_trait_ref( + &mut self, + trait_ref: &'v hir::PolyTraitRef<'v>, + modifier: hir::TraitBoundModifier, + ) { + // Record the "stack height" of `for<'a>` lifetime bindings + // to be able to later fully undo their introduction. + let old_len = self.currently_bound_lifetimes.len(); + intravisit::walk_poly_trait_ref(self, trait_ref, modifier); + self.currently_bound_lifetimes.truncate(old_len); + } + + fn visit_generic_param(&mut self, param: &'v hir::GenericParam<'v>) { + // Record the introduction of 'a in `for<'a> ...`. + if let hir::GenericParamKind::Lifetime { .. } = param.kind { + // Introduce lifetimes one at a time so that we can handle + // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`. + let lt_name = hir::LifetimeName::Param(param.name); + self.currently_bound_lifetimes.push(lt_name); + } + + intravisit::walk_generic_param(self, param); + } + + fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) { + let name = match lifetime.name { + hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => { + if self.collect_elided_lifetimes { + // Use `'_` for both implicit and underscore lifetimes in + // `type Foo<'_> = impl SomeTrait<'_>;`. + hir::LifetimeName::Underscore + } else { + return; + } + } + hir::LifetimeName::Param(_) => lifetime.name, + + // Refers to some other lifetime that is "in + // scope" within the type. + hir::LifetimeName::ImplicitObjectLifetimeDefault => return, + + hir::LifetimeName::Error | hir::LifetimeName::Static => return, + }; + + if !self.currently_bound_lifetimes.contains(&name) + && !self.already_defined_lifetimes.contains(&name) + && self.lifetimes_to_include.map_or(true, |lifetimes| lifetimes.contains(&name)) + { + self.already_defined_lifetimes.insert(name); + + self.lifetimes.push((name, lifetime.span)); + } + } + } + + let mut lifetime_collector = ImplTraitLifetimeCollector { + collect_elided_lifetimes: true, + currently_bound_lifetimes: Vec::new(), + already_defined_lifetimes: FxHashSet::default(), + lifetimes: Vec::new(), + lifetimes_to_include, + }; + + for bound in bounds { + intravisit::walk_param_bound(&mut lifetime_collector, &bound); + } + + lifetime_collector.lifetimes +} diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs index 22897c43e7ef9..0fa228fc944a1 100644 --- a/compiler/rustc_codegen_cranelift/src/archive.rs +++ b/compiler/rustc_codegen_cranelift/src/archive.rs @@ -4,8 +4,7 @@ use std::collections::BTreeMap; use std::fs::File; use std::path::{Path, PathBuf}; -use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder}; -use rustc_codegen_ssa::METADATA_FILENAME; +use rustc_codegen_ssa::back::archive::ArchiveBuilder; use rustc_session::Session; use object::{Object, ObjectSymbol, SymbolKind}; @@ -19,7 +18,6 @@ enum ArchiveEntry { pub(crate) struct ArArchiveBuilder<'a> { sess: &'a Session, dst: PathBuf, - lib_search_paths: Vec, use_gnu_style_archive: bool, no_builtin_ranlib: bool, @@ -31,8 +29,6 @@ pub(crate) struct ArArchiveBuilder<'a> { impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self { - use rustc_codegen_ssa::back::link::archive_search_paths; - let (src_archives, entries) = if let Some(input) = input { let mut archive = ar::Archive::new(File::open(input).unwrap()); let mut entries = Vec::new(); @@ -55,7 +51,6 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { ArArchiveBuilder { sess, dst: output.to_path_buf(), - lib_search_paths: archive_search_paths(sess), use_gnu_style_archive: sess.target.archive_format == "gnu", // FIXME fix builtin ranlib on macOS no_builtin_ranlib: sess.target.is_like_osx, @@ -85,42 +80,27 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { )); } - fn add_native_library(&mut self, name: rustc_span::symbol::Symbol, verbatim: bool) { - let location = find_library(name, verbatim, &self.lib_search_paths, self.sess); - self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| { - panic!("failed to add native library {}: {}", location.to_string_lossy(), e); - }); - } - - fn add_rlib( - &mut self, - rlib: &Path, - name: &str, - lto: bool, - skip_objects: bool, - ) -> std::io::Result<()> { - let obj_start = name.to_owned(); - - self.add_archive(rlib.to_owned(), move |fname: &str| { - // Ignore metadata files, no matter the name. - if fname == METADATA_FILENAME { - return true; - } - - // Don't include Rust objects if LTO is enabled - if lto && fname.starts_with(&obj_start) && fname.ends_with(".o") { - return true; - } + fn add_archive(&mut self, archive_path: &Path, mut skip: F) -> std::io::Result<()> + where + F: FnMut(&str) -> bool + 'static, + { + let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?); + let archive_index = self.src_archives.len(); - // Otherwise if this is *not* a rust object and we're skipping - // objects then skip this file - if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { - return true; + let mut i = 0; + while let Some(entry) = archive.next_entry() { + let entry = entry?; + let file_name = String::from_utf8(entry.header().identifier().to_vec()) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; + if !skip(&file_name) { + self.entries + .push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i })); } + i += 1; + } - // ok, don't skip this - false - }) + self.src_archives.push((archive_path.to_owned(), archive)); + Ok(()) } fn update_symbols(&mut self) {} @@ -264,28 +244,3 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { bug!("injecting dll imports is not supported"); } } - -impl<'a> ArArchiveBuilder<'a> { - fn add_archive(&mut self, archive_path: PathBuf, mut skip: F) -> std::io::Result<()> - where - F: FnMut(&str) -> bool + 'static, - { - let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?); - let archive_index = self.src_archives.len(); - - let mut i = 0; - while let Some(entry) = archive.next_entry() { - let entry = entry?; - let file_name = String::from_utf8(entry.header().identifier().to_vec()) - .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; - if !skip(&file_name) { - self.entries - .push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i })); - } - i += 1; - } - - self.src_archives.push((archive_path, archive)); - Ok(()) - } -} diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 03f462a63b31b..6f7ca51d038c0 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -1,4 +1,5 @@ use rustc_index::vec::IndexVec; +use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers}; use rustc_middle::ty::SymbolName; use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Integer, Primitive}; @@ -256,12 +257,12 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) inline_asm_index: u32, } -impl<'tcx> LayoutOf<'tcx> for FunctionCx<'_, '_, 'tcx> { - type Ty = Ty<'tcx>; - type TyAndLayout = TyAndLayout<'tcx>; +impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> { + type LayoutOfResult = TyAndLayout<'tcx>; - fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> { - RevealAllLayoutCx(self.tcx).layout_of(ty) + #[inline] + fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { + RevealAllLayoutCx(self.tcx).handle_layout_err(err, span, ty) } } @@ -364,19 +365,16 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) struct RevealAllLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); -impl<'tcx> LayoutOf<'tcx> for RevealAllLayoutCx<'tcx> { - type Ty = Ty<'tcx>; - type TyAndLayout = TyAndLayout<'tcx>; +impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { + type LayoutOfResult = TyAndLayout<'tcx>; - fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> { - assert!(!ty.still_further_specializable()); - self.0.layout_of(ParamEnv::reveal_all().and(&ty)).unwrap_or_else(|e| { - if let layout::LayoutError::SizeOverflow(_) = e { - self.0.sess.fatal(&e.to_string()) - } else { - bug!("failed to get layout for `{}`: {}", ty, e) - } - }) + #[inline] + fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { + if let layout::LayoutError::SizeOverflow(_) = err { + self.0.sess.span_fatal(span, &err.to_string()) + } else { + span_bug!(span, "failed to get layout for `{}`: {}", ty, err) + } } } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 6c7c8cbc311f9..2e5e8f683cdaa 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -79,12 +79,12 @@ mod prelude { pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub(crate) use rustc_middle::bug; pub(crate) use rustc_middle::mir::{self, *}; - pub(crate) use rustc_middle::ty::layout::{self, TyAndLayout}; + pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, UintTy, }; - pub(crate) use rustc_target::abi::{Abi, LayoutOf, Scalar, Size, VariantIdx}; + pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx}; pub(crate) use rustc_data_structures::fx::FxHashMap; diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index abf0ea8cc0a65..cd55a61cbaf9d 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -11,11 +11,12 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::MemFlags; use rustc_middle::bug; +use rustc_middle::ty::layout::LayoutOf; pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use rustc_middle::ty::Ty; use rustc_target::abi::call::ArgAbi; pub use rustc_target::abi::call::*; -use rustc_target::abi::{self, HasDataLayout, Int, LayoutOf}; +use rustc_target::abi::{self, HasDataLayout, Int}; pub use rustc_target::spec::abi::Abi; use libc::c_uint; diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 6ac7093b7dee8..4e86946219fb1 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -9,18 +9,15 @@ use std::str; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; -use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder}; -use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME}; +use rustc_codegen_ssa::back::archive::ArchiveBuilder; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_middle::middle::cstore::{DllCallingConvention, DllImport}; use rustc_session::Session; -use rustc_span::symbol::Symbol; struct ArchiveConfig<'a> { pub sess: &'a Session, pub dst: PathBuf, pub src: Option, - pub lib_search_paths: Vec, } /// Helper for adding many files to an archive. @@ -54,13 +51,7 @@ fn is_relevant_child(c: &Child<'_>) -> bool { } fn archive_config<'a>(sess: &'a Session, output: &Path, input: Option<&Path>) -> ArchiveConfig<'a> { - use rustc_codegen_ssa::back::link::archive_search_paths; - ArchiveConfig { - sess, - dst: output.to_path_buf(), - src: input.map(|p| p.to_path_buf()), - lib_search_paths: archive_search_paths(sess), - } + ArchiveConfig { sess, dst: output.to_path_buf(), src: input.map(|p| p.to_path_buf()) } } /// Map machine type strings to values of LLVM's MachineTypes enum. @@ -111,57 +102,23 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { .collect() } - /// Adds all of the contents of a native library to this archive. This will - /// search in the relevant locations for a library named `name`. - fn add_native_library(&mut self, name: Symbol, verbatim: bool) { - let location = - find_library(name, verbatim, &self.config.lib_search_paths, self.config.sess); - self.add_archive(&location, |_| false).unwrap_or_else(|e| { - self.config.sess.fatal(&format!( - "failed to add native library {}: {}", - location.to_string_lossy(), - e - )); + fn add_archive(&mut self, archive: &Path, skip: F) -> io::Result<()> + where + F: FnMut(&str) -> bool + 'static, + { + let archive_ro = match ArchiveRO::open(archive) { + Ok(ar) => ar, + Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)), + }; + if self.additions.iter().any(|ar| ar.path() == archive) { + return Ok(()); + } + self.additions.push(Addition::Archive { + path: archive.to_path_buf(), + archive: archive_ro, + skip: Box::new(skip), }); - } - - /// Adds all of the contents of the rlib at the specified path to this - /// archive. - /// - /// This ignores adding the bytecode from the rlib, and if LTO is enabled - /// then the object file also isn't added. - fn add_rlib( - &mut self, - rlib: &Path, - name: &str, - lto: bool, - skip_objects: bool, - ) -> io::Result<()> { - // Ignoring obj file starting with the crate name - // as simple comparison is not enough - there - // might be also an extra name suffix - let obj_start = name.to_owned(); - - self.add_archive(rlib, move |fname: &str| { - // Ignore metadata files, no matter the name. - if fname == METADATA_FILENAME { - return true; - } - - // Don't include Rust objects if LTO is enabled - if lto && looks_like_rust_object_file(fname) { - return true; - } - - // Otherwise if this is *not* a rust object and we're skipping - // objects then skip this file - if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { - return true; - } - - // ok, don't skip this - false - }) + Ok(()) } /// Adds an arbitrary file to this archive @@ -270,25 +227,6 @@ impl<'a> LlvmArchiveBuilder<'a> { self.src_archive.as_ref().unwrap().as_ref() } - fn add_archive(&mut self, archive: &Path, skip: F) -> io::Result<()> - where - F: FnMut(&str) -> bool + 'static, - { - let archive_ro = match ArchiveRO::open(archive) { - Ok(ar) => ar, - Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)), - }; - if self.additions.iter().any(|ar| ar.path() == archive) { - return Ok(()); - } - self.additions.push(Addition::Archive { - path: archive.to_path_buf(), - archive: archive_ro, - skip: Box::new(skip), - }); - Ok(()) - } - fn llvm_archive_kind(&self) -> Result { let kind = &*self.config.sess.target.archive_format; kind.parse().map_err(|_| kind) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 47529f719b514..da24fe08f0dfd 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -15,7 +15,7 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::MemFlags; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::def_id::DefId; -use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; use rustc_target::abi::{self, Align, Size}; @@ -88,12 +88,12 @@ impl HasTargetSpec for Builder<'_, '_, 'tcx> { } } -impl abi::LayoutOf<'tcx> for Builder<'_, '_, 'tcx> { - type Ty = Ty<'tcx>; - type TyAndLayout = TyAndLayout<'tcx>; +impl LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> { + type LayoutOfResult = TyAndLayout<'tcx>; - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.cx.layout_of(ty) + #[inline] + fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { + self.cx.handle_layout_err(err, span, ty) } } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 5532f53e40823..cee582aec95eb 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -12,9 +12,10 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_middle::bug; use rustc_middle::mir::interpret::{Allocation, GlobalAlloc, Scalar}; -use rustc_middle::ty::{layout::TyAndLayout, ScalarInt}; +use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::ScalarInt; use rustc_span::symbol::Symbol; -use rustc_target::abi::{self, AddressSpace, HasDataLayout, LayoutOf, Pointer, Size}; +use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer, Size}; use libc::{c_char, c_uint}; use tracing::debug; diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index a4e4fc4fffb8f..e673b06f15527 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -15,10 +15,11 @@ use rustc_middle::mir::interpret::{ Scalar as InterpScalar, }; use rustc_middle::mir::mono::MonoItem; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{ - AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size, WrappingRange, + AddressSpace, Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange, }; use std::ops::Range; use tracing::debug; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 45da18d4a24f3..2d397dc583534 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -14,15 +14,15 @@ use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_middle::bug; use rustc_middle::mir::mono::CodegenUnit; -use rustc_middle::ty::layout::{HasParamEnv, LayoutError, TyAndLayout}; +use rustc_middle::ty::layout::{HasParamEnv, LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::config::{CFGuard, CrateType, DebugInfo}; use rustc_session::Session; -use rustc_span::source_map::{Span, DUMMY_SP}; +use rustc_span::source_map::Span; use rustc_span::symbol::Symbol; -use rustc_target::abi::{HasDataLayout, LayoutOf, PointeeInfo, Size, TargetDataLayout, VariantIdx}; +use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx}; use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel}; use smallvec::SmallVec; @@ -835,22 +835,16 @@ impl ty::layout::HasTyCtxt<'tcx> for CodegenCx<'ll, 'tcx> { } } -impl LayoutOf<'tcx> for CodegenCx<'ll, 'tcx> { - type Ty = Ty<'tcx>; - type TyAndLayout = TyAndLayout<'tcx>; +impl LayoutOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> { + type LayoutOfResult = TyAndLayout<'tcx>; - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.spanned_layout_of(ty, DUMMY_SP) - } - - fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyAndLayout { - self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap_or_else(|e| { - if let LayoutError::SizeOverflow(_) = e { - self.sess().span_fatal(span, &e.to_string()) - } else { - bug!("failed to get layout for `{}`: {}", ty, e) - } - }) + #[inline] + fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { + if let LayoutError::SizeOverflow(_) = err { + self.sess().span_fatal(span, &err.to_string()) + } else { + span_bug!(span, "failed to get layout for `{}`: {}", ty, err) + } } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 346c51c5426d8..9a6391443dd01 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -28,7 +28,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::ich::NodeIdHashingMode; use rustc_middle::mir::{self, GeneratorLayout}; -use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout}; +use rustc_middle::ty::layout::{self, IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::Instance; use rustc_middle::ty::{self, AdtKind, GeneratorSubsts, ParamEnv, Ty, TyCtxt}; @@ -37,7 +37,7 @@ use rustc_session::config::{self, DebugInfo}; use rustc_span::symbol::{Interner, Symbol}; use rustc_span::FileNameDisplayPreference; use rustc_span::{self, SourceFile, SourceFileHash, Span}; -use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding}; +use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, TagEncoding}; use rustc_target::abi::{Int, Pointer, F32, F64}; use rustc_target::abi::{Primitive, Size, VariantIdx, Variants}; use tracing::debug; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index f6953b8b50ae9..fbaf8c8bdf63d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -25,14 +25,14 @@ use rustc_data_structures::sync::Lrc; use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_index::vec::IndexVec; use rustc_middle::mir; -use rustc_middle::ty::layout::HasTyCtxt; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeFoldable}; use rustc_session::config::{self, DebugInfo}; use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_span::{self, BytePos, Pos, SourceFile, SourceFileAndLine, Span}; -use rustc_target::abi::{LayoutOf, Primitive, Size}; +use rustc_target::abi::{Primitive, Size}; use libc::c_uint; use smallvec::SmallVec; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index e30c49295ba8c..1aa52d975e9a0 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -15,11 +15,11 @@ use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_hir as hir; -use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; +use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{sym, symbol::kw, Span, Symbol}; -use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive}; +use rustc_target::abi::{self, HasDataLayout, Primitive}; use rustc_target::spec::PanicStrategy; use std::cmp::Ordering; diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 8a8ece640fcc7..8ba3e870fbb71 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -8,10 +8,9 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; -use rustc_middle::ty::layout::FnAbiExt; +use rustc_middle::ty::layout::{FnAbiExt, LayoutOf}; use rustc_middle::ty::{self, Instance, TypeFoldable}; use rustc_session::config::CrateType; -use rustc_target::abi::LayoutOf; use rustc_target::spec::RelocModel; use tracing::debug; diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 9818905464dce..d615d230ea0d1 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -4,12 +4,12 @@ use crate::context::TypeLowering; use crate::type_::Type; use rustc_codegen_ssa::traits::*; use rustc_middle::bug; -use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout}; +use rustc_middle::ty::layout::{FnAbiExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TypeFoldable}; use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape}; use rustc_target::abi::{Int, Pointer, F32, F64}; -use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAbiInterface, Variants}; +use rustc_target::abi::{PointeeInfo, Scalar, Size, TyAbiInterface, Variants}; use smallvec::{smallvec, SmallVec}; use tracing::debug; diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 2208ec37a4235..caafae6c26750 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -7,9 +7,9 @@ use rustc_codegen_ssa::{ common::IntPredicate, traits::{BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods}, }; -use rustc_middle::ty::layout::HasTyCtxt; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::Ty; -use rustc_target::abi::{Align, Endian, HasDataLayout, LayoutOf, Size}; +use rustc_target::abi::{Align, Endian, HasDataLayout, Size}; fn round_pointer_up_to_alignment( bx: &mut Builder<'a, 'll, 'tcx>, diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 63f457bb979e3..5188abdbe6286 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -6,7 +6,7 @@ use rustc_span::symbol::Symbol; use std::io; use std::path::{Path, PathBuf}; -pub fn find_library( +pub(super) fn find_library( name: Symbol, verbatim: bool, search_paths: &[PathBuf], @@ -48,14 +48,9 @@ pub trait ArchiveBuilder<'a> { fn remove_file(&mut self, name: &str); fn src_files(&mut self) -> Vec; - fn add_rlib( - &mut self, - path: &Path, - name: &str, - lto: bool, - skip_objects: bool, - ) -> io::Result<()>; - fn add_native_library(&mut self, name: Symbol, verbatim: bool); + fn add_archive(&mut self, archive: &Path, skip: F) -> io::Result<()> + where + F: FnMut(&str) -> bool + 'static; fn update_symbols(&mut self); fn build(self); diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index f5463bca3384c..903b630bbd627 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -19,7 +19,7 @@ use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo}; use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target}; -use super::archive::ArchiveBuilder; +use super::archive::{find_library, ArchiveBuilder}; use super::command::Command; use super::linker::{self, Linker}; use super::rpath::{self, RPathConfig}; @@ -230,6 +230,9 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>( tmpdir: &MaybeTempDir, ) -> Result { info!("preparing rlib to {:?}", out_filename); + + let lib_search_paths = archive_search_paths(sess); + let mut ab = ::new(sess, out_filename, None); for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { @@ -262,7 +265,15 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>( | NativeLibKind::Unspecified => continue, } if let Some(name) = lib.name { - ab.add_native_library(name, lib.verbatim.unwrap_or(false)); + let location = + find_library(name, lib.verbatim.unwrap_or(false), &lib_search_paths, sess); + ab.add_archive(&location, |_| false).unwrap_or_else(|e| { + sess.fatal(&format!( + "failed to add native library {}: {}", + location.to_string_lossy(), + e + )); + }); } } @@ -541,13 +552,35 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>( matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. }) && !relevant_lib(sess, lib) }); - ab.add_rlib( - path, - &name.as_str(), - are_upstream_rust_objects_already_included(sess) - && !ignored_for_lto(sess, &codegen_results.crate_info, cnum), - skip_object_files, - ) + + let lto = are_upstream_rust_objects_already_included(sess) + && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); + + // Ignoring obj file starting with the crate name + // as simple comparison is not enough - there + // might be also an extra name suffix + let obj_start = name.as_str().to_owned(); + + ab.add_archive(path, move |fname: &str| { + // Ignore metadata files, no matter the name. + if fname == METADATA_FILENAME { + return true; + } + + // Don't include Rust objects if LTO is enabled + if lto && looks_like_rust_object_file(fname) { + return true; + } + + // Otherwise if this is *not* a rust object and we're skipping + // objects then skip this file + if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { + return true; + } + + // ok, don't skip this + false + }) .unwrap(); all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); @@ -1218,7 +1251,7 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool { sess.split_debuginfo() == SplitDebuginfo::Unpacked } -pub fn archive_search_paths(sess: &Session) -> Vec { +fn archive_search_paths(sess: &Session) -> Vec { sess.target_filesearch(PathKind::Native).search_path_dirs() } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f427dd7669399..a6bf1d8d1e51a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -22,14 +22,14 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::cstore::EncodedMetadata; use rustc_middle::middle::lang_items; use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; -use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{self, EntryFnType}; use rustc_session::Session; use rustc_span::symbol::sym; -use rustc_target::abi::{Align, LayoutOf, VariantIdx}; +use rustc_target::abi::{Align, VariantIdx}; use std::convert::TryFrom; use std::ops::{Deref, DerefMut}; diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index b6def164fac63..8d75b2e7a3d4c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -9,8 +9,7 @@ use rustc_index::vec::IndexVec; use rustc_middle::mir::traversal; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, Location, TerminatorKind}; -use rustc_middle::ty::layout::HasTyCtxt; -use rustc_target::abi::LayoutOf; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx: &FunctionCx<'a, 'tcx, Bx>, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 2a76ad0fb1356..2ca7e8fd7e8e3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -14,13 +14,13 @@ use rustc_hir::lang_items::LangItem; use rustc_index::vec::Idx; use rustc_middle::mir::AssertKind; use rustc_middle::mir::{self, SwitchTargets}; -use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt}; +use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Instance, Ty, TypeFoldable}; use rustc_span::source_map::Span; use rustc_span::{sym, Symbol}; use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; -use rustc_target::abi::{self, HasDataLayout, LayoutOf}; +use rustc_target::abi::{self, HasDataLayout}; use rustc_target::spec::abi::Abi; /// Used by `FunctionCx::codegen_terminator` for emitting common patterns diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index cfb2befdf9137..5cee25b5cca3b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -8,9 +8,9 @@ use crate::MemFlags; use rustc_middle::mir; use rustc_middle::mir::interpret::{ConstValue, Pointer, Scalar}; -use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; -use rustc_target::abi::{Abi, Align, LayoutOf, Size}; +use rustc_target::abi::{Abi, Align, Size}; use std::fmt; diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 20be46606a0aa..b48d6d42b4357 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -8,10 +8,10 @@ use crate::MemFlags; use rustc_middle::mir; use rustc_middle::mir::tcx::PlaceTy; -use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::{Abi, Align, FieldsShape, Int, TagEncoding}; -use rustc_target::abi::{LayoutOf, VariantIdx, Variants}; +use rustc_target::abi::{VariantIdx, Variants}; #[derive(Copy, Clone, Debug)] pub struct PlaceRef<'tcx, V> { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 02e2db54e741b..3d8ea29160bd0 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -11,10 +11,10 @@ use rustc_apfloat::{ieee, Float, Round, Status}; use rustc_hir::lang_items::LangItem; use rustc_middle::mir; use rustc_middle::ty::cast::{CastTy, IntTy}; -use rustc_middle::ty::layout::HasTyCtxt; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; use rustc_span::source_map::{Span, DUMMY_SP}; -use rustc_target::abi::{Abi, Int, LayoutOf, Variants}; +use rustc_target::abi::{Abi, Int, Variants}; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_rvalue( diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 48d753e0d8435..5f0f50ae2df1d 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -4,8 +4,7 @@ use crate::traits::*; use rustc_hir as hir; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; -use rustc_middle::ty::layout::HasTyCtxt; -use rustc_target::abi::LayoutOf; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; pub trait MonoItemExt<'a, 'tcx> { fn define>(&self, cx: &'a Bx::CodegenCx); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 96e53f51dac8f..dbb7e1ee8b17f 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -8,15 +8,14 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorReported; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; -use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::{ config::{self, OutputFilenames, PrintRequest}, Session, }; use rustc_span::symbol::Symbol; -use rustc_target::abi::LayoutOf; use rustc_target::spec::Target; pub use rustc_data_structures::sync::MetadataRef; @@ -39,17 +38,12 @@ pub trait BackendTypes { } pub trait Backend<'tcx>: - Sized - + BackendTypes - + HasTyCtxt<'tcx> - + LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> + Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> { } impl<'tcx, T> Backend<'tcx> for T where - Self: BackendTypes - + HasTyCtxt<'tcx> - + LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> + Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> { } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 88b9e92119f60..2850e7a6b44e9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -41,16 +41,17 @@ use rustc_hir::{ForeignItemKind, GenericParamKind, PatKind}; use rustc_hir::{HirId, Node}; use rustc_index::vec::Idx; use rustc_middle::lint::LintDiagnosticBuilder; +use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::Instance; -use rustc_middle::ty::{self, layout::LayoutError, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, InnerSpan, MultiSpan, Span}; -use rustc_target::abi::{LayoutOf, VariantIdx}; +use rustc_target::abi::VariantIdx; use rustc_trait_selection::traits::misc::can_type_implement_copy; use crate::nonstandard_style::{method_context, MethodLateContext}; diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 7dbc3d60439c4..4c45e33db79c7 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -31,7 +31,7 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::middle::stability; -use rustc_middle::ty::layout::{LayoutError, TyAndLayout}; +use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; use rustc_serialize::json::Json; @@ -41,7 +41,7 @@ use rustc_session::Session; use rustc_session::SessionLintStore; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP}; -use rustc_target::abi::{self, LayoutOf}; +use rustc_target::abi; use tracing::debug; use std::cell::Cell; @@ -1080,12 +1080,12 @@ impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> { } } -impl<'tcx> LayoutOf<'tcx> for LateContext<'tcx> { - type Ty = Ty<'tcx>; - type TyAndLayout = Result, LayoutError<'tcx>>; +impl<'tcx> LayoutOfHelpers<'tcx> for LateContext<'tcx> { + type LayoutOfResult = Result, LayoutError<'tcx>>; - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx.layout_of(self.param_env.and(ty)) + #[inline] + fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> { + err } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 5d25578163976..480f7756db3fe 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -6,14 +6,14 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{is_range_literal, Expr, ExprKind, Node}; -use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton}; +use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeFoldable}; use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_target::abi::Abi; -use rustc_target::abi::{Integer, LayoutOf, TagEncoding, Variants}; +use rustc_target::abi::{Integer, TagEncoding, Variants}; use rustc_target::spec::abi::Abi as SpecAbi; use if_chain::if_chain; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 573fa913d680a..6868be50f1d06 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -31,6 +31,7 @@ #![feature(box_patterns)] #![feature(core_intrinsics)] #![feature(discriminant_kind)] +#![feature(exhaustive_patterns)] #![feature(if_let_guard)] #![feature(never_type)] #![feature(extern_types)] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index dada94edc95ff..c93996162e3e3 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -996,6 +996,12 @@ rustc_queries! { desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) } } + query own_existential_vtable_entries( + key: ty::PolyExistentialTraitRef<'tcx> + ) -> &'tcx [DefId] { + desc { |tcx| "finding all existential vtable entries for trait {}", tcx.def_path_str(key.def_id()) } + } + query vtable_entries(key: ty::PolyTraitRef<'tcx>) -> &'tcx [ty::VtblEntry<'tcx>] { desc { |tcx| "finding all vtable entries for trait {}", tcx.def_path_str(key.def_id()) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 5e5902abe662f..f7ab9dd82ac73 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -13,7 +13,7 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; use rustc_session::{config::OptLevel, DataTypeKind, FieldInfo, SizeKind, VariantInfo}; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::call::{ ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind, }; @@ -2062,29 +2062,113 @@ impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> { } } +pub trait MaybeResult { + type Error; + + fn from(x: Result) -> Self; + fn to_result(self) -> Result; +} + +impl MaybeResult for T { + type Error = !; + + fn from(Ok(x): Result) -> Self { + x + } + fn to_result(self) -> Result { + Ok(self) + } +} + +impl MaybeResult for Result { + type Error = E; + + fn from(x: Result) -> Self { + x + } + fn to_result(self) -> Result { + self + } +} + pub type TyAndLayout<'tcx> = rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>; -impl LayoutOf<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> { - type Ty = Ty<'tcx>; - type TyAndLayout = Result, LayoutError<'tcx>>; +/// Trait for contexts that want to be able to compute layouts of types. +/// This automatically gives access to `LayoutOf`, through a blanket `impl`. +pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasParamEnv<'tcx> { + /// The `TyAndLayout`-wrapping type (or `TyAndLayout` itself), which will be + /// returned from `layout_of` (see also `handle_layout_err`). + type LayoutOfResult: MaybeResult>; + /// `Span` to use for `tcx.at(span)`, from `layout_of`. + // FIXME(eddyb) perhaps make this mandatory to get contexts to track it better? + #[inline] + fn layout_tcx_at_span(&self) -> Span { + DUMMY_SP + } + + /// Helper used for `layout_of`, to adapt `tcx.layout_of(...)` into a + /// `Self::LayoutOfResult` (which does not need to be a `Result<...>`). + /// + /// Most `impl`s, which propagate `LayoutError`s, should simply return `err`, + /// but this hook allows e.g. codegen to return only `TyAndLayout` from its + /// `cx.layout_of(...)`, without any `Result<...>` around it to deal with + /// (and any `LayoutError`s are turned into fatal errors or ICEs). + fn handle_layout_err( + &self, + err: LayoutError<'tcx>, + span: Span, + ty: Ty<'tcx>, + ) -> >>::Error; +} + +/// Blanket extension trait for contexts that can compute layouts of types. +pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> { /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode, and will normalize the input type. #[inline] - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx.layout_of(self.param_env.and(ty)) + fn layout_of(&self, ty: Ty<'tcx>) -> Self::LayoutOfResult { + self.spanned_layout_of(ty, DUMMY_SP) + } + + /// Computes the layout of a type, at `span`. Note that this implicitly + /// executes in "reveal all" mode, and will normalize the input type. + // FIXME(eddyb) avoid passing information like this, and instead add more + // `TyCtxt::at`-like APIs to be able to do e.g. `cx.at(span).layout_of(ty)`. + #[inline] + fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::LayoutOfResult { + let span = if !span.is_dummy() { span } else { self.layout_tcx_at_span() }; + MaybeResult::from( + self.tcx() + .at(span) + .layout_of(self.param_env().and(ty)) + .map_err(|err| self.handle_layout_err(err, span, ty)), + ) } } -impl LayoutOf<'tcx> for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { - type Ty = Ty<'tcx>; - type TyAndLayout = Result, LayoutError<'tcx>>; +impl> LayoutOf<'tcx> for C {} + +impl LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> { + type LayoutOfResult = Result, LayoutError<'tcx>>; + + #[inline] + fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> { + err + } +} + +impl LayoutOfHelpers<'tcx> for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { + type LayoutOfResult = Result, LayoutError<'tcx>>; + + #[inline] + fn layout_tcx_at_span(&self) -> Span { + self.tcx.span + } - /// Computes the layout of a type. Note that this implicitly - /// executes in "reveal all" mode, and will normalize the input type. #[inline] - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx.layout_of(self.param_env.and(ty)) + fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> { + err } } @@ -2559,11 +2643,7 @@ impl<'tcx> ty::Instance<'tcx> { pub trait FnAbiExt<'tcx, C> where - C: LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, + C: LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> + HasTargetSpec, { /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. /// @@ -2746,11 +2826,7 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>> where - C: LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> - + HasDataLayout - + HasTargetSpec - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, + C: LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> + HasTargetSpec, { fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { call::FnAbi::new_internal(cx, sig, extra_args, None, CodegenFnAttrFlags::empty(), false) diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index dc6a6b0b9f3d8..3e8a93e08c29d 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -12,10 +12,11 @@ use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::Reveal; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, subst::Subst, TyCtxt}; use rustc_span::source_map::Span; -use rustc_target::abi::{Abi, LayoutOf}; +use rustc_target::abi::Abi; use std::borrow::Cow; use std::convert::TryInto; diff --git a/compiler/rustc_mir/src/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs index 6f18009cf4730..4c4b0bd2d1f27 100644 --- a/compiler/rustc_mir/src/interpret/cast.rs +++ b/compiler/rustc_mir/src/interpret/cast.rs @@ -5,9 +5,9 @@ use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::mir::CastKind; use rustc_middle::ty::adjustment::PointerCast; -use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; +use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut}; -use rustc_target::abi::{Integer, LayoutOf, Variants}; +use rustc_target::abi::{Integer, Variants}; use super::{ util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy, diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index c6003d87f3ac6..05502d8b21f1c 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -8,18 +8,18 @@ use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use rustc_middle::ich::StableHashingContext; use rustc_middle::mir; -use rustc_middle::ty::layout::{self, TyAndLayout}; +use rustc_middle::ty::layout::{self, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::{ self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, }; use rustc_session::Limit; use rustc_span::{Pos, Span}; -use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout}; +use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout}; use super::{ - AllocId, GlobalId, Immediate, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, - MemoryKind, Operand, Place, PlaceTy, Pointer, Provenance, Scalar, ScalarMaybeUninit, - StackPopJump, + AllocId, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, + MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, Pointer, Provenance, Scalar, + ScalarMaybeUninit, StackPopJump, }; use crate::transform::validate::equal_up_to_regions; use crate::util::storage::AlwaysLiveLocals; @@ -313,15 +313,22 @@ where } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOf<'tcx> for InterpCx<'mir, 'tcx, M> { - type Ty = Ty<'tcx>; - type TyAndLayout = InterpResult<'tcx, TyAndLayout<'tcx>>; +impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'mir, 'tcx, M> { + type LayoutOfResult = InterpResult<'tcx, TyAndLayout<'tcx>>; #[inline] - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx - .layout_of(self.param_env.and(ty)) - .map_err(|layout| err_inval!(Layout(layout)).into()) + fn layout_tcx_at_span(&self) -> Span { + self.tcx.span + } + + #[inline] + fn handle_layout_err( + &self, + err: LayoutError<'tcx>, + _: Span, + _: Ty<'tcx>, + ) -> InterpErrorInfo<'tcx> { + err_inval!(Layout(err)).into() } } diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index bfab886b6ee4f..07e974b72664b 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -11,10 +11,11 @@ use rustc_middle::mir::{ BinOp, }; use rustc_middle::ty; +use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; -use rustc_target::abi::{Abi, Align, LayoutOf as _, Primitive, Size}; +use rustc_target::abi::{Abi, Align, Primitive, Size}; use super::{ util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy, diff --git a/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs index 022129b2a2204..d4cbba1802931 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs @@ -3,9 +3,9 @@ use std::convert::TryFrom; use rustc_ast::Mutability; use rustc_hir::lang_items::LangItem; use rustc_middle::mir::TerminatorKind; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::subst::Subst; use rustc_span::{Span, Symbol}; -use rustc_target::abi::LayoutOf; use crate::interpret::{ intrinsics::{InterpCx, Machine}, diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 4afce2b6b80f2..e67a6690836ad 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -7,11 +7,11 @@ use std::fmt::Write; use rustc_errors::ErrorReported; use rustc_hir::def::Namespace; use rustc_macros::HashStable; -use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; +use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer}; use rustc_middle::ty::{ConstInt, Ty}; use rustc_middle::{mir, ty}; -use rustc_target::abi::{Abi, HasDataLayout, LayoutOf, Size, TagEncoding}; +use rustc_target::abi::{Abi, HasDataLayout, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; use super::{ diff --git a/compiler/rustc_mir/src/interpret/operator.rs b/compiler/rustc_mir/src/interpret/operator.rs index 79b493d74e19b..ac000b1bb566f 100644 --- a/compiler/rustc_mir/src/interpret/operator.rs +++ b/compiler/rustc_mir/src/interpret/operator.rs @@ -3,8 +3,8 @@ use std::convert::TryFrom; use rustc_apfloat::Float; use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; -use rustc_middle::ty::{self, layout::TyAndLayout, FloatTy, Ty}; -use rustc_target::abi::LayoutOf; +use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::ty::{self, FloatTy, Ty}; use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index afad9716b3fe1..95a44e3fecf3d 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -8,10 +8,10 @@ use std::hash::Hash; use rustc_ast::Mutability; use rustc_macros::HashStable; use rustc_middle::mir; -use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; +use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::{Abi, Align, FieldsShape, TagEncoding}; -use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants}; +use rustc_target::abi::{HasDataLayout, Size, VariantIdx, Variants}; use super::{ alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, diff --git a/compiler/rustc_mir/src/interpret/step.rs b/compiler/rustc_mir/src/interpret/step.rs index f2a8a067dfac2..1e96581c392d2 100644 --- a/compiler/rustc_mir/src/interpret/step.rs +++ b/compiler/rustc_mir/src/interpret/step.rs @@ -4,7 +4,7 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; -use rustc_target::abi::LayoutOf; +use rustc_middle::ty::layout::LayoutOf; use super::{InterpCx, Machine}; diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs index 63496045e0d73..1c8e5e9e23c3c 100644 --- a/compiler/rustc_mir/src/interpret/terminator.rs +++ b/compiler/rustc_mir/src/interpret/terminator.rs @@ -2,13 +2,13 @@ use std::borrow::Cow; use std::convert::TryFrom; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::ty::layout::{self, TyAndLayout}; +use rustc_middle::ty::layout::{self, LayoutOf as _, TyAndLayout}; use rustc_middle::ty::Instance; use rustc_middle::{ mir, ty::{self, Ty}, }; -use rustc_target::abi::{self, LayoutOf as _}; +use rustc_target::abi; use rustc_target::spec::abi::Abi; use super::{ diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index 2bb2f88725784..03e0a8e7901d9 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -12,11 +12,9 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_middle::mir::interpret::InterpError; use rustc_middle::ty; -use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_span::symbol::{sym, Symbol}; -use rustc_target::abi::{ - Abi, LayoutOf, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange, -}; +use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange}; use std::hash::Hash; diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 5c51aa4ed679b..71c07be4c6d8d 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -17,14 +17,14 @@ use rustc_middle::mir::{ Location, Operand, Place, Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, }; -use rustc_middle::ty::layout::{LayoutError, TyAndLayout}; +use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, }; use rustc_session::lint; use rustc_span::{def_id::DefId, Span}; -use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TargetDataLayout}; +use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; @@ -330,12 +330,12 @@ struct ConstPropagator<'mir, 'tcx> { source_info: Option, } -impl<'mir, 'tcx> LayoutOf<'tcx> for ConstPropagator<'mir, 'tcx> { - type Ty = Ty<'tcx>; - type TyAndLayout = Result, LayoutError<'tcx>>; +impl<'mir, 'tcx> LayoutOfHelpers<'tcx> for ConstPropagator<'mir, 'tcx> { + type LayoutOfResult = Result, LayoutError<'tcx>>; - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx.layout_of(self.param_env.and(ty)) + #[inline] + fn handle_layout_err(&self, err: LayoutError<'tcx>, _: Span, _: Ty<'tcx>) -> LayoutError<'tcx> { + err } } diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index e9f0038b2d65d..b402b8ba53ada 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,10 +1,10 @@ -use super::{AttrWrapper, Capturing, Parser, PathStyle}; +use super::{AttrWrapper, Capturing, ForceCollect, Parser, PathStyle}; use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Nonterminal}; use rustc_ast_pretty::pprust; -use rustc_errors::{error_code, PResult}; -use rustc_span::{sym, Span}; +use rustc_errors::{error_code, DiagnosticBuilder, PResult}; +use rustc_span::{sym, BytePos, Span}; use std::convert::TryInto; use tracing::debug; @@ -25,6 +25,12 @@ pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPo prev_attr_sp: None, }; +enum OuterAttributeType { + DocComment, + DocBlockComment, + Attribute, +} + impl<'a> Parser<'a> { /// Parses attributes that appear before an item. pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> { @@ -49,18 +55,32 @@ impl<'a> Parser<'a> { Some(self.parse_attribute(inner_parse_policy)?) } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind { if attr_style != ast::AttrStyle::Outer { - self.sess - .span_diagnostic - .struct_span_err_with_code( - self.token.span, - "expected outer doc comment", - error_code!(E0753), - ) - .note( - "inner doc comments like this (starting with \ - `//!` or `/*!`) can only appear before items", - ) - .emit(); + let span = self.token.span; + let mut err = self.sess.span_diagnostic.struct_span_err_with_code( + span, + "expected outer doc comment", + error_code!(E0753), + ); + if let Some(replacement_span) = self.annotate_following_item_if_applicable( + &mut err, + span, + match comment_kind { + token::CommentKind::Line => OuterAttributeType::DocComment, + token::CommentKind::Block => OuterAttributeType::DocBlockComment, + }, + ) { + err.note( + "inner doc comments like this (starting with `//!` or `/*!`) can \ + only appear before items", + ); + err.span_suggestion_verbose( + replacement_span, + "you might have meant to write a regular comment", + String::new(), + rustc_errors::Applicability::MachineApplicable, + ); + } + err.emit(); } self.bump(); just_parsed_doc_comment = true; @@ -97,7 +117,7 @@ impl<'a> Parser<'a> { inner_parse_policy, self.token ); let lo = self.token.span; - // Attributse can't have attributes of their own + // Attributes can't have attributes of their own [Editor's note: not with that attitude] self.collect_tokens_no_attrs(|this| { if this.eat(&token::Pound) { let style = if this.eat(&token::Not) { @@ -125,6 +145,75 @@ impl<'a> Parser<'a> { }) } + fn annotate_following_item_if_applicable( + &self, + err: &mut DiagnosticBuilder<'_>, + span: Span, + attr_type: OuterAttributeType, + ) -> Option { + let mut snapshot = self.clone(); + let lo = span.lo() + + BytePos(match attr_type { + OuterAttributeType::Attribute => 1, + _ => 2, + }); + let hi = lo + BytePos(1); + let replacement_span = span.with_lo(lo).with_hi(hi); + if let OuterAttributeType::DocBlockComment | OuterAttributeType::DocComment = attr_type { + snapshot.bump(); + } + loop { + // skip any other attributes, we want the item + if snapshot.token.kind == token::Pound { + if let Err(mut err) = snapshot.parse_attribute(InnerAttrPolicy::Permitted) { + err.cancel(); + return Some(replacement_span); + } + } else { + break; + } + } + match snapshot.parse_item_common( + AttrWrapper::empty(), + true, + false, + |_| true, + ForceCollect::No, + ) { + Ok(Some(item)) => { + let attr_name = match attr_type { + OuterAttributeType::Attribute => "attribute", + _ => "doc comment", + }; + err.span_label( + item.span, + &format!("the inner {} doesn't annotate this {}", attr_name, item.kind.descr()), + ); + err.span_suggestion_verbose( + replacement_span, + &format!( + "to annotate the {}, change the {} from inner to outer style", + item.kind.descr(), + attr_name + ), + (match attr_type { + OuterAttributeType::Attribute => "", + OuterAttributeType::DocBlockComment => "*", + OuterAttributeType::DocComment => "/", + }) + .to_string(), + rustc_errors::Applicability::MachineApplicable, + ); + return None; + } + Err(mut item_err) => { + item_err.cancel(); + } + Ok(None) => {} + } + Some(replacement_span) + } + pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) { if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_attr_sp } = policy { let prev_attr_note = @@ -138,11 +227,20 @@ impl<'a> Parser<'a> { } diag.note( - "inner attributes, like `#![no_std]`, annotate the item enclosing them, \ - and are usually found at the beginning of source files. \ - Outer attributes, like `#[test]`, annotate the item following them.", - ) - .emit(); + "inner attributes, like `#![no_std]`, annotate the item enclosing them, and \ + are usually found at the beginning of source files", + ); + if self + .annotate_following_item_if_applicable( + &mut diag, + attr_sp, + OuterAttributeType::Attribute, + ) + .is_some() + { + diag.note("outer attributes, like `#[test]`, annotate the item following them"); + }; + diag.emit(); } } diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 64ea4ee570e82..aa78fcfb4b373 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -3,10 +3,11 @@ use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::ItemKind; -use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, TyAndLayout}; +use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_span::symbol::sym; -use rustc_target::abi::{HasDataLayout, LayoutOf, TargetDataLayout}; +use rustc_span::Span; +use rustc_target::abi::{HasDataLayout, TargetDataLayout}; pub fn test_layout(tcx: TyCtxt<'_>) { if tcx.features().rustc_attrs { @@ -113,12 +114,16 @@ struct UnwrapLayoutCx<'tcx> { param_env: ParamEnv<'tcx>, } -impl LayoutOf<'tcx> for UnwrapLayoutCx<'tcx> { - type Ty = Ty<'tcx>; - type TyAndLayout = TyAndLayout<'tcx>; +impl LayoutOfHelpers<'tcx> for UnwrapLayoutCx<'tcx> { + type LayoutOfResult = TyAndLayout<'tcx>; - fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { - self.tcx.layout_of(self.param_env.and(ty)).unwrap() + fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { + span_bug!( + span, + "`#[rustc_layout(..)]` test resulted in `layout_of({}) = Err({})`", + ty, + err + ); } } diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index c973eae6b0665..42e8b4023cfad 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -294,6 +294,16 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> { } } +impl<'tcx> Key for ty::PolyExistentialTraitRef<'tcx> { + #[inline(always)] + fn query_crate_is_local(&self) -> bool { + self.def_id().krate == LOCAL_CRATE + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + tcx.def_span(self.def_id()) + } +} + impl<'tcx> Key for (ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>) { #[inline(always)] fn query_crate_is_local(&self) -> bool { diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 820399943f0af..b0ecd117dd20e 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -13,7 +13,6 @@ use std::str::FromStr; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable_Generic; use rustc_serialize::json::{Json, ToJson}; -use rustc_span::Span; pub mod call; @@ -1173,46 +1172,6 @@ impl<'a, Ty> Deref for TyAndLayout<'a, Ty> { } } -/// Trait for context types that can compute layouts of things. -pub trait LayoutOf<'a>: Sized { - type Ty: TyAbiInterface<'a, Self>; - type TyAndLayout: MaybeResult>; - - fn layout_of(&self, ty: Self::Ty) -> Self::TyAndLayout; - fn spanned_layout_of(&self, ty: Self::Ty, _span: Span) -> Self::TyAndLayout { - self.layout_of(ty) - } -} - -pub trait MaybeResult { - type Error; - - fn from(x: Result) -> Self; - fn to_result(self) -> Result; -} - -impl MaybeResult for T { - type Error = !; - - fn from(Ok(x): Result) -> Self { - x - } - fn to_result(self) -> Result { - Ok(self) - } -} - -impl MaybeResult for Result { - type Error = E; - - fn from(x: Result) -> Self { - x - } - fn to_result(self) -> Result { - self - } -} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PointerKind { /// Most general case, we know no restrictions to tell LLVM. diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 17a4184c3c9ef..44c675243838a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -625,6 +625,31 @@ fn dump_vtable_entries<'tcx>( tcx.sess.struct_span_err(sp, &msg).emit(); } +fn own_existential_vtable_entries<'tcx>( + tcx: TyCtxt<'tcx>, + trait_ref: ty::PolyExistentialTraitRef<'tcx>, +) -> &'tcx [DefId] { + let trait_methods = tcx + .associated_items(trait_ref.def_id()) + .in_definition_order() + .filter(|item| item.kind == ty::AssocKind::Fn); + // Now list each method's DefId (for within its trait). + let own_entries = trait_methods.filter_map(move |trait_method| { + debug!("own_existential_vtable_entry: trait_method={:?}", trait_method); + let def_id = trait_method.def_id; + + // Some methods cannot be called on an object; skip those. + if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) { + debug!("own_existential_vtable_entry: not vtable safe"); + return None; + } + + Some(def_id) + }); + + tcx.arena.alloc_from_iter(own_entries.into_iter()) +} + /// Given a trait `trait_ref`, iterates the vtable entries /// that come from `trait_ref`, including its supertraits. fn vtable_entries<'tcx>( @@ -641,21 +666,15 @@ fn vtable_entries<'tcx>( entries.extend(COMMON_VTABLE_ENTRIES); } VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { - let trait_methods = tcx - .associated_items(trait_ref.def_id()) - .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Fn); - // Now list each method's DefId and InternalSubsts (for within its trait). - // If the method can never be called from this object, produce `Vacant`. - let own_entries = trait_methods.map(move |trait_method| { - debug!("vtable_entries: trait_method={:?}", trait_method); - let def_id = trait_method.def_id; - - // Some methods cannot be called on an object; skip those. - if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) { - debug!("vtable_entries: not vtable safe"); - return VtblEntry::Vacant; - } + let existential_trait_ref = trait_ref + .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + + // Lookup the shape of vtable for the trait. + let own_existential_entries = + tcx.own_existential_vtable_entries(existential_trait_ref); + + let own_entries = own_existential_entries.iter().copied().map(|def_id| { + debug!("vtable_entries: trait_method={:?}", def_id); // The method may have some early-bound lifetimes; add regions for those. let substs = trait_ref.map_bound(|trait_ref| { @@ -804,6 +823,7 @@ pub fn provide(providers: &mut ty::query::Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, codegen_fulfill_obligation: codegen::codegen_fulfill_obligation, + own_existential_vtable_entries, vtable_entries, vtable_trait_upcasting_coercion_new_vptr_slot, subst_and_check_impossible_predicates, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index fd94f9f799847..b108d85bb20c9 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -285,15 +285,10 @@ pub fn upcast_choices( /// that come from `trait_ref`, excluding its supertraits. Used in /// computing the vtable base for an upcast trait of a trait object. pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> usize { - let mut entries = 0; - // Count number of methods and add them to the total offset. - // Skip over associated types and constants. - for trait_item in tcx.associated_items(trait_ref.def_id()).in_definition_order() { - if trait_item.kind == ty::AssocKind::Fn { - entries += 1; - } - } - entries + let existential_trait_ref = + trait_ref.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let existential_trait_ref = tcx.erase_regions(existential_trait_ref); + tcx.own_existential_vtable_entries(existential_trait_ref).len() } /// Given an upcast trait object described by `object`, returns the @@ -304,22 +299,21 @@ pub fn get_vtable_index_of_object_method( object: &super::ImplSourceObjectData<'tcx, N>, method_def_id: DefId, ) -> usize { + let existential_trait_ref = object + .upcast_trait_ref + .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); + let existential_trait_ref = tcx.erase_regions(existential_trait_ref); // Count number of methods preceding the one we are selecting and // add them to the total offset. - // Skip over associated types and constants, as those aren't stored in the vtable. - let mut entries = object.vtable_base; - for trait_item in tcx.associated_items(object.upcast_trait_ref.def_id()).in_definition_order() { - if trait_item.def_id == method_def_id { - // The item with the ID we were given really ought to be a method. - assert_eq!(trait_item.kind, ty::AssocKind::Fn); - return entries; - } - if trait_item.kind == ty::AssocKind::Fn { - entries += 1; - } - } - - bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id); + let index = tcx + .own_existential_vtable_entries(existential_trait_ref) + .iter() + .copied() + .position(|def_id| def_id == method_def_id) + .unwrap_or_else(|| { + bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id); + }); + object.vtable_base + index } pub fn closure_trait_ref_and_return_type( diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 17e0c42440c21..9748c0835bf12 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -945,7 +945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(s) if s.starts_with('<') => sugg, _ => format!("<{}>", sugg), }; - let replace = String::from("use `dyn`"); + let sugg_label = "use `dyn`"; if self.sess().edition() >= Edition::Edition2021 { let mut err = rustc_errors::struct_span_err!( self.sess(), @@ -956,8 +956,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_suggestion( self_ty.span, - &sugg, - replace, + sugg_label, + sugg, Applicability::MachineApplicable, ) .emit(); @@ -968,7 +968,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty.span, |lint| { let mut db = lint.build(msg); - db.span_suggestion(self_ty.span, &replace, sugg, app); + db.span_suggestion(self_ty.span, sugg_label, sugg, app); db.emit() }, ); diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 3caada06f6b58..be21018512d8b 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -323,7 +323,7 @@ impl RawVec { pub fn reserve(&mut self, len: usize, additional: usize) { // Callers expect this function to be very cheap when there is already sufficient capacity. // Therefore, we move all the resizing and error-handling logic from grow_amortized and - // handle_reserve behind a call, while making sure that the this function is likely to be + // handle_reserve behind a call, while making sure that this function is likely to be // inlined as just a comparison and a call if the comparison fails. #[cold] fn do_reserve_and_handle( diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 70cccd31b92de..8c33a43ab330e 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -396,7 +396,7 @@ impl [T; N] { /// /// This method is particularly useful if combined with other methods, like /// [`map`](#method.map). This way, you can avoid moving the original - /// array if its elements are not `Copy`. + /// array if its elements are not [`Copy`]. /// /// ``` /// #![feature(array_methods)] diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index dcafaae2f5b49..ca1c0ae759892 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -2,7 +2,7 @@ #[lang = "bool"] impl bool { - /// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise. + /// Returns `Some(t)` if the `bool` is [`true`](keyword.true.html), or `None` otherwise. /// /// # Examples /// @@ -18,7 +18,7 @@ impl bool { if self { Some(t) } else { None } } - /// Returns `Some(f())` if the `bool` is `true`, or `None` otherwise. + /// Returns `Some(f())` if the `bool` is [`true`](keyword.true.html), or `None` otherwise. /// /// # Examples /// diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 0dadbdd1bd054..e6d3ac8f2d2c5 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -96,7 +96,7 @@ impl char { /// Converts a `u32` to a `char`. /// /// Note that all `char`s are valid [`u32`]s, and can be cast to one with - /// `as`: + /// [`as`](keyword.as.html): /// /// ``` /// let c = '💯'; @@ -372,7 +372,7 @@ impl char { /// println!("\\u{{2764}}"); /// ``` /// - /// Using `to_string`: + /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string): /// /// ``` /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}"); @@ -422,7 +422,7 @@ impl char { /// Returns an iterator that yields the literal escape code of a character /// as `char`s. /// - /// This will escape the characters similar to the `Debug` implementations + /// This will escape the characters similar to the [`Debug`](core::fmt::Debug) implementations /// of `str` or `char`. /// /// # Examples @@ -448,7 +448,7 @@ impl char { /// println!("\\n"); /// ``` /// - /// Using `to_string`: + /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string): /// /// ``` /// assert_eq!('\n'.escape_debug().to_string(), "\\n"); @@ -502,7 +502,7 @@ impl char { /// println!("\\\""); /// ``` /// - /// Using `to_string`: + /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string): /// /// ``` /// assert_eq!('"'.escape_default().to_string(), "\\\""); @@ -937,7 +937,7 @@ impl char { /// println!("i\u{307}"); /// ``` /// - /// Using `to_string`: + /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string): /// /// ``` /// assert_eq!('C'.to_lowercase().to_string(), "c"); @@ -1002,7 +1002,7 @@ impl char { /// println!("SS"); /// ``` /// - /// Using `to_string`: + /// Using [`to_string`](string/trait.ToString.html#tymethod.to_string): /// /// ``` /// assert_eq!('c'.to_uppercase().to_string(), "C"); @@ -1131,7 +1131,7 @@ impl char { /// Checks that two values are an ASCII case-insensitive match. /// - /// Equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`. + /// Equivalent to [to_ascii_lowercase]\(a) == [to_ascii_lowercase]\(b). /// /// # Examples /// @@ -1144,6 +1144,8 @@ impl char { /// assert!(upper_a.eq_ignore_ascii_case(&upper_a)); /// assert!(!upper_a.eq_ignore_ascii_case(&lower_z)); /// ``` + /// + /// [to_ascii_lowercase]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 261d0e648e2ef..b85489dabe94c 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -3,16 +3,16 @@ #[doc(alias = "false")] /// The boolean type. /// -/// The `bool` represents a value, which could only be either `true` or `false`. If you cast -/// a `bool` into an integer, `true` will be 1 and `false` will be 0. +/// The `bool` represents a value, which could only be either [`true`] or [`false`]. If you cast +/// a `bool` into an integer, [`true`] will be 1 and [`false`] will be 0. /// /// # Basic usage /// /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc., /// which allow us to perform boolean operations using `&`, `|` and `!`. /// -/// `if` requires a `bool` value as its conditional. [`assert!`], which is an -/// important macro in testing, checks whether an expression is `true` and panics +/// [`if`] requires a `bool` value as its conditional. [`assert!`], which is an +/// important macro in testing, checks whether an expression is [`true`] and panics /// if it isn't. /// /// ``` @@ -20,9 +20,12 @@ /// assert!(!bool_val); /// ``` /// +/// [`true`]: keyword.true.html +/// [`false`]: keyword.false.html /// [`BitAnd`]: ops::BitAnd /// [`BitOr`]: ops::BitOr /// [`Not`]: ops::Not +/// [`if`]: keyword.if.html /// /// # Examples /// @@ -574,8 +577,8 @@ mod prim_pointer {} /// /// # Editions /// -/// Prior to Rust 1.53, arrays did not implement `IntoIterator` by value, so the method call -/// `array.into_iter()` auto-referenced into a slice iterator. Right now, the old behavior +/// Prior to Rust 1.53, arrays did not implement [`IntoIterator`] by value, so the method call +/// `array.into_iter()` auto-referenced into a [slice iterator](slice::iter). Right now, the old behavior /// is preserved in the 2015 and 2018 editions of Rust for compatibility, ignoring /// `IntoIterator` by value. In the future, the behavior on the 2015 and 2018 edition /// might be made consistent to the behavior of later editions. @@ -833,7 +836,7 @@ mod prim_str {} /// ``` /// /// The sequential nature of the tuple applies to its implementations of various -/// traits. For example, in `PartialOrd` and `Ord`, the elements are compared +/// traits. For example, in [`PartialOrd`] and [`Ord`], the elements are compared /// sequentially until the first non-equal set is found. /// /// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type). @@ -1037,14 +1040,16 @@ mod prim_usize {} /// References, both shared and mutable. /// /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut` -/// operators on a value, or by using a `ref` or `ref mut` pattern. +/// operators on a value, or by using a [`ref`](keyword.ref.html) or +/// [ref](keyword.ref.html) [mut](keyword.mut.html) pattern. /// /// For those familiar with pointers, a reference is just a pointer that is assumed to be /// aligned, not null, and pointing to memory containing a valid value of `T` - for example, -/// `&bool` can only point to an allocation containing the integer values `1` (`true`) or `0` -/// (`false`), but creating a `&bool` that points to an allocation containing -/// the value `3` causes undefined behaviour. -/// In fact, `Option<&T>` has the same memory representation as a +/// &[bool] can only point to an allocation containing the integer values `1` +/// ([`true`](keyword.true.html)) or `0` ([`false`](keyword.false.html)), but creating a +/// &[bool] that points to an allocation containing the value `3` causes +/// undefined behaviour. +/// In fact, [Option]\<&T> has the same memory representation as a /// nullable but aligned pointer, and can be passed across FFI boundaries as such. /// /// In most cases, references can be used much like the original value. Field access, method @@ -1140,7 +1145,7 @@ mod prim_usize {} /// * [`ExactSizeIterator`] /// * [`FusedIterator`] /// * [`TrustedLen`] -/// * [`Send`] \(note that `&T` references only get `Send` if `T: Sync`) +/// * [`Send`] \(note that `&T` references only get `Send` if T: [Sync]) /// * [`io::Write`] /// * [`Read`] /// * [`Seek`] @@ -1172,7 +1177,8 @@ mod prim_ref {} /// Function pointers are pointers that point to *code*, not data. They can be called /// just like functions. Like references, function pointers are, among other things, assumed to /// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null -/// pointers, make your type `Option` with your required signature. +/// pointers, make your type [`Option`](core::option#options-and-pointers-nullable-pointers) +/// with your required signature. /// /// ### Safety /// diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 4eb335979b983..f5fad4b413684 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -107,6 +107,11 @@ impl Step for Std { add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); } + // don't run on std twice with x.py clippy + if builder.kind == Kind::Clippy { + return; + } + // Then run cargo again, once we've put the rmeta files for the library // crates into the sysroot. This is needed because e.g., core's tests // depend on `libtest` -- Cargo presumes it will exist, but it doesn't @@ -120,6 +125,7 @@ impl Step for Std { target, cargo_subcommand(builder.kind), ); + cargo.arg("--all-targets"); std_cargo(builder, target, compiler.stage, &mut cargo); @@ -192,7 +198,12 @@ impl Step for Rustc { cargo_subcommand(builder.kind), ); rustc_cargo(builder, &mut cargo, target); - cargo.arg("--all-targets"); + + // For ./x.py clippy, don't run with --all-targets because + // linting tests and benchmarks can produce very noisy results + if builder.kind != Kind::Clippy { + cargo.arg("--all-targets"); + } // Explicitly pass -p for all compiler krates -- this will force cargo // to also check the tests/benches/examples for these crates, rather @@ -313,7 +324,12 @@ macro_rules! tool_check_step { $source_type, &[], ); - cargo.arg("--all-targets"); + + // For ./x.py clippy, don't run with --all-targets because + // linting tests and benchmarks can produce very noisy results + if builder.kind != Kind::Clippy { + cargo.arg("--all-targets"); + } // Enable internal lints for clippy and rustdoc // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]` diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 9217209fcf051..11adb56490b32 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -331,9 +331,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { match br { // We only care about named late bound regions, as we need to add them // to the 'for<>' section - ty::BrNamed(_, name) => { - Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime }) - } + ty::BrNamed(_, name) => Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + }), _ => None, } }) @@ -659,7 +660,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { bounds.insert(0, GenericBound::maybe_sized(self.cx)); } } - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Lifetime { .. } => {} GenericParamDefKind::Const { ref mut default, .. } => { // We never want something like `impl` default.take(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d06506803c2ce..71348b3eb65ff 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -30,6 +30,7 @@ use rustc_target::spec::abi::Abi; use rustc_typeck::check::intrinsic::intrinsic_operation_unsafety; use rustc_typeck::hir_ty_to_ty; +use std::assert_matches::assert_matches; use std::collections::hash_map::Entry; use std::default::Default; use std::hash::Hash; @@ -199,9 +200,10 @@ impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { .collect_referenced_late_bound_regions(&poly_trait_ref) .into_iter() .filter_map(|br| match br { - ty::BrNamed(_, name) => { - Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime }) - } + ty::BrNamed(_, name) => Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + }), _ => None, }) .collect(); @@ -241,30 +243,6 @@ impl Clean for hir::Lifetime { } } -impl Clean for hir::GenericParam<'_> { - fn clean(&self, _: &mut DocContext<'_>) -> Lifetime { - match self.kind { - hir::GenericParamKind::Lifetime { .. } => { - if !self.bounds.is_empty() { - let mut bounds = self.bounds.iter().map(|bound| match bound { - hir::GenericBound::Outlives(lt) => lt, - _ => panic!(), - }); - let name = bounds.next().expect("no more bounds").name.ident(); - let mut s = format!("{}: {}", self.name.ident(), name); - for bound in bounds { - s.push_str(&format!(" + {}", bound.name.ident())); - } - Lifetime(Symbol::intern(&s)) - } else { - Lifetime(self.name.ident().name) - } - } - _ => panic!(), - } - } -} - impl Clean for hir::ConstArg { fn clean(&self, cx: &mut DocContext<'_>) -> Constant { Constant { @@ -302,11 +280,30 @@ impl Clean> for ty::RegionKind { impl Clean for hir::WherePredicate<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { match *self { - hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate { - ty: wbp.bounded_ty.clean(cx), - bounds: wbp.bounds.clean(cx), - bound_params: wbp.bound_generic_params.into_iter().map(|x| x.clean(cx)).collect(), - }, + hir::WherePredicate::BoundPredicate(ref wbp) => { + let bound_params = wbp + .bound_generic_params + .into_iter() + .map(|param| { + // Higher-ranked params must be lifetimes. + // Higher-ranked lifetimes can't have bounds. + assert_matches!( + param, + hir::GenericParam { + kind: hir::GenericParamKind::Lifetime { .. }, + bounds: [], + .. + } + ); + Lifetime(param.name.ident().name) + }) + .collect(); + WherePredicate::BoundPredicate { + ty: wbp.bounded_ty.clean(cx), + bounds: wbp.bounds.clean(cx), + bound_params, + } + } hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate { lifetime: wrp.lifetime.clean(cx), @@ -412,7 +409,9 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { impl Clean for ty::GenericParamDef { fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { let (name, kind) = match self.kind { - ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime), + ty::GenericParamDefKind::Lifetime => { + (self.name, GenericParamDefKind::Lifetime { outlives: vec![] }) + } ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { let default = if has_default { let mut default = cx.tcx.type_of(self.def_id).clean(cx); @@ -462,21 +461,15 @@ impl Clean for hir::GenericParam<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { let (name, kind) = match self.kind { hir::GenericParamKind::Lifetime { .. } => { - let name = if !self.bounds.is_empty() { - let mut bounds = self.bounds.iter().map(|bound| match bound { - hir::GenericBound::Outlives(lt) => lt, + let outlives = self + .bounds + .iter() + .map(|bound| match bound { + hir::GenericBound::Outlives(lt) => lt.clean(cx), _ => panic!(), - }); - let name = bounds.next().expect("no more bounds").name.ident(); - let mut s = format!("{}: {}", self.name.ident(), name); - for bound in bounds { - s.push_str(&format!(" + {}", bound.name.ident())); - } - Symbol::intern(&s) - } else { - self.name.ident().name - }; - (name, GenericParamDefKind::Lifetime) + }) + .collect(); + (self.name.ident().name, GenericParamDefKind::Lifetime { outlives }) } hir::GenericParamKind::Type { ref default, synthetic } => ( self.name.ident().name, @@ -536,7 +529,7 @@ impl Clean for hir::Generics<'_> { .map(|param| { let param: GenericParamDef = param.clean(cx); match param.kind { - GenericParamDefKind::Lifetime => unreachable!(), + GenericParamDefKind::Lifetime { .. } => unreachable!(), GenericParamDefKind::Type { did, ref bounds, .. } => { cx.impl_trait_bounds.insert(did.into(), bounds.clone()); } @@ -569,7 +562,7 @@ impl Clean for hir::Generics<'_> { { for param in &mut generics.params { match param.kind { - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Lifetime { .. } => {} GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => { if ¶m.name == name { mem::swap(bounds, ty_bounds); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 47176070f657a..5eff56a2200e1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1231,7 +1231,9 @@ impl WherePredicate { #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate enum GenericParamDefKind { - Lifetime, + Lifetime { + outlives: Vec, + }, Type { did: DefId, bounds: Vec, @@ -1257,7 +1259,7 @@ impl GenericParamDefKind { match self { GenericParamDefKind::Type { default, .. } => default.clone(), GenericParamDefKind::Const { ty, .. } => Some(ty.clone()), - GenericParamDefKind::Lifetime => None, + GenericParamDefKind::Lifetime { .. } => None, } } } @@ -1271,7 +1273,7 @@ crate struct GenericParamDef { impl GenericParamDef { crate fn is_synthetic_type_param(&self) -> bool { match self.kind { - GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => false, + GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false, GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(), } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 54be830bf42e7..ea0458034899c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -155,9 +155,23 @@ impl clean::GenericParamDef { &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { - display_fn(move |f| match self.kind { - clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name), - clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => { + display_fn(move |f| match &self.kind { + clean::GenericParamDefKind::Lifetime { outlives } => { + write!(f, "{}", self.name)?; + + if !outlives.is_empty() { + f.write_str(": ")?; + for (i, lt) in outlives.iter().enumerate() { + if i != 0 { + f.write_str(" + ")?; + } + write!(f, "{}", lt.print())?; + } + } + + Ok(()) + } + clean::GenericParamDefKind::Type { bounds, default, .. } => { f.write_str(&*self.name.as_str())?; if !bounds.is_empty() { @@ -178,7 +192,7 @@ impl clean::GenericParamDef { Ok(()) } - clean::GenericParamDefKind::Const { ref ty, ref default, .. } => { + clean::GenericParamDefKind::Const { ty, default, .. } => { if f.alternate() { write!(f, "const {}: {:#}", self.name, ty.print(cx))?; } else { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 46eeee8e3a490..e6bbd237cda7d 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -326,7 +326,9 @@ impl FromWithTcx for GenericParamDefKind { fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self { use clean::GenericParamDefKind::*; match kind { - Lifetime => GenericParamDefKind::Lifetime, + Lifetime { outlives } => GenericParamDefKind::Lifetime { + outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(), + }, Type { did: _, bounds, default, synthetic: _ } => GenericParamDefKind::Type { bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), default: default.map(|x| x.into_tcx(tcx)), diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 8bdf1a5981230..5089cc30a1e39 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -234,7 +234,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), - format_version: 6, + format_version: 7, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b81acd1a93fc2..2dbe4c42b888e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -4,6 +4,7 @@ )] #![feature(rustc_private)] #![feature(array_methods)] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(in_band_lifetimes)] diff --git a/src/llvm-project b/src/llvm-project index a04279dd5736b..ec995b75d71c5 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit a04279dd5736be294843af15ac07ca499c02acef +Subproject commit ec995b75d71c5f3b9a82fe084259477eb22f74da diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 38ba87322c238..37cdc94441df7 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -323,7 +323,7 @@ pub struct GenericParamDef { #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "snake_case")] pub enum GenericParamDefKind { - Lifetime, + Lifetime { outlives: Vec }, Type { bounds: Vec, default: Option }, Const { ty: Type, default: Option }, } diff --git a/src/test/rustdoc-json/structs/with_primitives.rs b/src/test/rustdoc-json/structs/with_primitives.rs index ea98676863b5e..9e64317ec203f 100644 --- a/src/test/rustdoc-json/structs/with_primitives.rs +++ b/src/test/rustdoc-json/structs/with_primitives.rs @@ -1,7 +1,7 @@ // @has with_primitives.json "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\" // @has - "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\" // @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\" -// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind" \"lifetime\" +// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" [] // @has - "$.index[*][?(@.name=='WithPrimitives')].inner.struct_type" \"plain\" // @has - "$.index[*][?(@.name=='WithPrimitives')].inner.fields_stripped" true pub struct WithPrimitives<'a> { diff --git a/src/test/rustdoc-ui/bounded-hr-lifetime.rs b/src/test/rustdoc-ui/bounded-hr-lifetime.rs new file mode 100644 index 0000000000000..b2e000b975740 --- /dev/null +++ b/src/test/rustdoc-ui/bounded-hr-lifetime.rs @@ -0,0 +1,9 @@ +// This test ensures that rustdoc doesn't panic on higher-ranked lifetimes +// with bounds, because an error should have already been emitted by rustc. + +pub fn hrlt<'b, 'c>() +where + for<'a: 'b + 'c> &'a (): std::fmt::Debug, + //~^ ERROR lifetime bounds cannot be used in this context +{ +} diff --git a/src/test/rustdoc-ui/bounded-hr-lifetime.stderr b/src/test/rustdoc-ui/bounded-hr-lifetime.stderr new file mode 100644 index 0000000000000..d8fcd6cb4b13f --- /dev/null +++ b/src/test/rustdoc-ui/bounded-hr-lifetime.stderr @@ -0,0 +1,10 @@ +error: lifetime bounds cannot be used in this context + --> $DIR/bounded-hr-lifetime.rs:6:13 + | +LL | for<'a: 'b + 'c> &'a (): std::fmt::Debug, + | ^^ ^^ + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/editions/dyn-trait-sugg-2021.rs b/src/test/ui/editions/dyn-trait-sugg-2021.rs new file mode 100644 index 0000000000000..47c48e7ec9e8b --- /dev/null +++ b/src/test/ui/editions/dyn-trait-sugg-2021.rs @@ -0,0 +1,12 @@ +// edition:2021 + +trait Foo {} + +impl dyn Foo { + fn hi(_x: T) {} +} + +fn main() { + Foo::hi(123); + //~^ ERROR trait objects without an explicit `dyn` are deprecated +} diff --git a/src/test/ui/editions/dyn-trait-sugg-2021.stderr b/src/test/ui/editions/dyn-trait-sugg-2021.stderr new file mode 100644 index 0000000000000..f6e9fa96a15b5 --- /dev/null +++ b/src/test/ui/editions/dyn-trait-sugg-2021.stderr @@ -0,0 +1,9 @@ +error[E0783]: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-trait-sugg-2021.rs:10:5 + | +LL | Foo::hi(123); + | ^^^ help: use `dyn`: `` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0783`. diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr index cec6980c008c4..d38b98a190117 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -4,7 +4,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `]` --> $DIR/attr-stmt-expr-attr-bad.rs:7:40 @@ -24,7 +25,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `)` --> $DIR/attr-stmt-expr-attr-bad.rs:11:44 @@ -38,7 +40,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `)` --> $DIR/attr-stmt-expr-attr-bad.rs:14:46 @@ -52,7 +55,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:19:33 @@ -60,7 +64,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:21:33 @@ -68,7 +73,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:23:34 @@ -82,7 +88,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:27:40 @@ -90,7 +97,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:29:35 @@ -98,7 +106,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:31:40 @@ -106,7 +115,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `..` --> $DIR/attr-stmt-expr-attr-bad.rs:33:40 @@ -126,7 +136,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:39:45 @@ -134,7 +145,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:41:37 @@ -151,7 +163,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:45:40 @@ -174,7 +187,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:51:45 @@ -200,7 +214,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:57:45 @@ -217,7 +232,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:61:48 @@ -240,7 +256,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:67:53 @@ -266,7 +283,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:74:32 @@ -276,7 +294,8 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } | | | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:76:32 @@ -286,37 +305,56 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } | | | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:78:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); } + | error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:80:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; } + | error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:82:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | + | ------- ^^^^^^^^ ------ the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; } + | error[E0586]: inclusive range with no end --> $DIR/attr-stmt-expr-attr-bad.rs:88:35 diff --git a/src/test/ui/parser/attr.stderr b/src/test/ui/parser/attr.stderr index 400a0276b3b60..3cec61fe41eea 100644 --- a/src/test/ui/parser/attr.stderr +++ b/src/test/ui/parser/attr.stderr @@ -3,8 +3,16 @@ error: an inner attribute is not permitted in this context | LL | #![lang = "foo"] | ^^^^^^^^^^^^^^^^ +LL | +LL | fn foo() {} + | ----------- the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![lang = "foo"] +LL + #[lang = "foo"] + | error[E0522]: definition of an unknown language item: `foo` --> $DIR/attr.rs:5:1 diff --git a/src/test/ui/parser/doc-comment-in-if-statement.stderr b/src/test/ui/parser/doc-comment-in-if-statement.stderr index be52a0afd46b7..b7c1847fc7c0d 100644 --- a/src/test/ui/parser/doc-comment-in-if-statement.stderr +++ b/src/test/ui/parser/doc-comment-in-if-statement.stderr @@ -5,6 +5,11 @@ LL | if true /*!*/ {} | ^^^^^ | = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - if true /*!*/ {} +LL + if true /**/ {} + | error: outer attributes are not allowed on `if` and `else` branches --> $DIR/doc-comment-in-if-statement.rs:2:13 diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.stderr b/src/test/ui/parser/inner-attr-after-doc-comment.stderr index c1e9e7a427f89..404800ee15bdd 100644 --- a/src/test/ui/parser/inner-attr-after-doc-comment.stderr +++ b/src/test/ui/parser/inner-attr-after-doc-comment.stderr @@ -8,8 +8,16 @@ LL | | */ LL | LL | #![recursion_limit="100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute +LL | +LL | fn main() {} + | ------------ the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![recursion_limit="100"] +LL + #[recursion_limit="100"] + | error: aborting due to previous error diff --git a/src/test/ui/parser/inner-attr.stderr b/src/test/ui/parser/inner-attr.stderr index e1bf2cca1c963..1adac74590881 100644 --- a/src/test/ui/parser/inner-attr.stderr +++ b/src/test/ui/parser/inner-attr.stderr @@ -6,8 +6,15 @@ LL | #[feature(lang_items)] LL | LL | #![recursion_limit="100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute +LL | fn main() {} + | ------------ the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![recursion_limit="100"] +LL + #[recursion_limit="100"] + | error: aborting due to previous error diff --git a/src/test/ui/parser/issue-30318.fixed b/src/test/ui/parser/issue-30318.fixed new file mode 100644 index 0000000000000..71fc82172a54d --- /dev/null +++ b/src/test/ui/parser/issue-30318.fixed @@ -0,0 +1,27 @@ +// run-rustfix +#![allow(unused)] +fn foo() { } + +/// Misplaced comment... +//~^ ERROR expected outer doc comment +fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function + +#[test] //~ ERROR an inner attribute is not permitted in this context +fn baz() { } //~ NOTE the inner attribute doesn't annotate this function +//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually + +/** Misplaced comment... */ +//~^ ERROR expected outer doc comment +fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function + +fn main() { } + +// Misplaced comment... +//~^ ERROR expected outer doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +//~| NOTE other attributes here +/* Misplaced comment... */ +//~^ ERROR expected outer doc comment +//~| NOTE this doc comment doesn't document anything +//~| ERROR expected item after doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items diff --git a/src/test/ui/parser/issue-30318.rs b/src/test/ui/parser/issue-30318.rs index 38e30de716d0a..465dca2ff8224 100644 --- a/src/test/ui/parser/issue-30318.rs +++ b/src/test/ui/parser/issue-30318.rs @@ -1,7 +1,27 @@ +// run-rustfix +#![allow(unused)] fn foo() { } //! Misplaced comment... //~^ ERROR expected outer doc comment -//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function + +#![test] //~ ERROR an inner attribute is not permitted in this context +fn baz() { } //~ NOTE the inner attribute doesn't annotate this function +//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually + +/*! Misplaced comment... */ +//~^ ERROR expected outer doc comment +fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function fn main() { } + +//! Misplaced comment... +//~^ ERROR expected outer doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +//~| NOTE other attributes here +/*! Misplaced comment... */ +//~^ ERROR expected outer doc comment +//~| NOTE this doc comment doesn't document anything +//~| ERROR expected item after doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items diff --git a/src/test/ui/parser/issue-30318.stderr b/src/test/ui/parser/issue-30318.stderr index b3a27f1985171..7e7108845546a 100644 --- a/src/test/ui/parser/issue-30318.stderr +++ b/src/test/ui/parser/issue-30318.stderr @@ -1,11 +1,81 @@ error[E0753]: expected outer doc comment - --> $DIR/issue-30318.rs:3:1 + --> $DIR/issue-30318.rs:5:1 + | +LL | //! Misplaced comment... + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn bar() { } + | ------------ the inner doc comment doesn't annotate this function + | +help: to annotate the function, change the doc comment from inner to outer style + | +LL | /// Misplaced comment... + | ~ + +error: an inner attribute is not permitted in this context + --> $DIR/issue-30318.rs:9:1 + | +LL | #![test] + | ^^^^^^^^ +LL | fn baz() { } + | ------------ the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![test] +LL + #[test] + | + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:13:1 + | +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn bat() { } + | ------------ the inner doc comment doesn't annotate this function + | +help: to annotate the function, change the doc comment from inner to outer style + | +LL | /** Misplaced comment... */ + | ~ + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:19:1 | LL | //! Misplaced comment... | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - //! Misplaced comment... +LL + // Misplaced comment... + | + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:23:1 + | +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - /*! Misplaced comment... */ +LL + /* Misplaced comment... */ + | + +error: expected item after doc comment + --> $DIR/issue-30318.rs:23:1 + | +LL | //! Misplaced comment... + | ------------------------ other attributes here +... +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything -error: aborting due to previous error +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0753`. diff --git a/src/test/ui/parser/issue-45296.rs b/src/test/ui/parser/issue-45296.rs index f242c1d29372f..d3a97e89f9abb 100644 --- a/src/test/ui/parser/issue-45296.rs +++ b/src/test/ui/parser/issue-45296.rs @@ -2,4 +2,5 @@ fn main() { let unused = (); #![allow(unused_variables)] //~ ERROR not permitted in this context + fn foo() {} } diff --git a/src/test/ui/parser/issue-45296.stderr b/src/test/ui/parser/issue-45296.stderr index c0d4ce1243e01..6abe266d4e90e 100644 --- a/src/test/ui/parser/issue-45296.stderr +++ b/src/test/ui/parser/issue-45296.stderr @@ -3,8 +3,15 @@ error: an inner attribute is not permitted in this context | LL | #![allow(unused_variables)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo() {} + | ----------- the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![allow(unused_variables)] +LL + #[allow(unused_variables)] + | error: aborting due to previous error diff --git a/src/test/ui/parser/stmt_expr_attrs_placement.stderr b/src/test/ui/parser/stmt_expr_attrs_placement.stderr index 808903d9c62f3..bf4005698a3d6 100644 --- a/src/test/ui/parser/stmt_expr_attrs_placement.stderr +++ b/src/test/ui/parser/stmt_expr_attrs_placement.stderr @@ -4,7 +4,8 @@ error: an inner attribute is not permitted in this context LL | let a = #![allow(warnings)] (1, 2); | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:10:14 @@ -12,7 +13,8 @@ error: an inner attribute is not permitted in this context LL | let b = (#![allow(warnings)] 1, 2); | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:15:10 @@ -20,7 +22,8 @@ error: an inner attribute is not permitted in this context LL | (#![allow(warnings)] 1, 2) | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:21:18 @@ -28,7 +31,8 @@ error: an inner attribute is not permitted in this context LL | let e = (#![allow(warnings)] 1, 2); | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:26:14 @@ -36,7 +40,8 @@ error: an inner attribute is not permitted in this context LL | let e = [#![allow(warnings)] 1, 2]; | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:29:14 @@ -44,7 +49,8 @@ error: an inner attribute is not permitted in this context LL | let f = [#![allow(warnings)] 1; 0]; | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:36:24 @@ -52,7 +58,8 @@ error: an inner attribute is not permitted in this context LL | let h = MyStruct { #![allow(warnings)] field: 0 }; | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: aborting due to 7 previous errors diff --git a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.fixed b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.fixed new file mode 100644 index 0000000000000..426a5fa723fcf --- /dev/null +++ b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.fixed @@ -0,0 +1,12 @@ +// aux-build:test-macros.rs +// run-rustfix + +#[macro_use] +extern crate test_macros; + +/// Inner doc comment +//~^ ERROR expected outer doc comment +#[derive(Empty)] +pub struct Foo; //~ NOTE the inner doc comment doesn't annotate this struct + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs index 8be1ae77738e9..31e3f3c859236 100644 --- a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs +++ b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs @@ -1,4 +1,5 @@ // aux-build:test-macros.rs +// run-rustfix #[macro_use] extern crate test_macros; @@ -6,6 +7,6 @@ extern crate test_macros; //! Inner doc comment //~^ ERROR expected outer doc comment #[derive(Empty)] -pub struct Foo; +pub struct Foo; //~ NOTE the inner doc comment doesn't annotate this struct fn main() {} diff --git a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr index 0b2e612ee5bb9..a92f07522e5f2 100644 --- a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr +++ b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr @@ -1,10 +1,16 @@ error[E0753]: expected outer doc comment - --> $DIR/issue-86781-bad-inner-doc.rs:6:1 + --> $DIR/issue-86781-bad-inner-doc.rs:7:1 | LL | //! Inner doc comment | ^^^^^^^^^^^^^^^^^^^^^ +... +LL | pub struct Foo; + | --------------- the inner doc comment doesn't annotate this struct | - = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: to annotate the struct, change the doc comment from inner to outer style + | +LL | /// Inner doc comment + | ~ error: aborting due to previous error diff --git a/src/test/ui/traits/vtable/vtable-non-object-safe.rs b/src/test/ui/traits/vtable/vtable-non-object-safe.rs new file mode 100644 index 0000000000000..45b6a8a98a79f --- /dev/null +++ b/src/test/ui/traits/vtable/vtable-non-object-safe.rs @@ -0,0 +1,18 @@ +// build-fail +#![feature(rustc_attrs)] + +// Ensure that non-object-safe methods in Iterator does not generate +// vtable entries. + +#[rustc_dump_vtable] +trait A: Iterator {} +//~^ error Vtable + +impl A for T where T: Iterator {} + +fn foo(_a: &mut dyn A) { +} + +fn main() { + foo(&mut vec![0, 1, 2, 3].into_iter()); +} diff --git a/src/test/ui/traits/vtable/vtable-non-object-safe.stderr b/src/test/ui/traits/vtable/vtable-non-object-safe.stderr new file mode 100644 index 0000000000000..f3175b805d1b6 --- /dev/null +++ b/src/test/ui/traits/vtable/vtable-non-object-safe.stderr @@ -0,0 +1,16 @@ +error: Vtable entries for ` as A>`: [ + MetadataDropInPlace, + MetadataSize, + MetadataAlign, + Method( as Iterator>::next), + Method( as Iterator>::size_hint), + Method( as Iterator>::advance_by), + Method( as Iterator>::nth), +] + --> $DIR/vtable-non-object-safe.rs:8:1 + | +LL | trait A: Iterator {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/traits/vtable/vtable-vacant.rs b/src/test/ui/traits/vtable/vtable-vacant.rs index ebea94171f2ab..429ce523799f3 100644 --- a/src/test/ui/traits/vtable/vtable-vacant.rs +++ b/src/test/ui/traits/vtable/vtable-vacant.rs @@ -1,22 +1,25 @@ // build-fail #![feature(rustc_attrs)] +#![feature(negative_impls)] +#![allow(where_clauses_object_safety)] // B --> A #[rustc_dump_vtable] trait A { fn foo_a1(&self) {} - fn foo_a2(&self) where Self: Sized {} + fn foo_a2(&self) where Self: Send {} } #[rustc_dump_vtable] trait B: A { //~^ error Vtable fn foo_b1(&self) {} - fn foo_b2() where Self: Sized {} + fn foo_b2(&self) where Self: Send {} } struct S; +impl !Send for S {} impl A for S {} impl B for S {} diff --git a/src/test/ui/traits/vtable/vtable-vacant.stderr b/src/test/ui/traits/vtable/vtable-vacant.stderr index 768cca526894a..f5cd36264fcff 100644 --- a/src/test/ui/traits/vtable/vtable-vacant.stderr +++ b/src/test/ui/traits/vtable/vtable-vacant.stderr @@ -7,12 +7,12 @@ error: Vtable entries for ``: [ Method(::foo_b1), Vacant, ] - --> $DIR/vtable-vacant.rs:13:1 + --> $DIR/vtable-vacant.rs:15:1 | LL | / trait B: A { LL | | LL | | fn foo_b1(&self) {} -LL | | fn foo_b2() where Self: Sized {} +LL | | fn foo_b2(&self) where Self: Send {} LL | | } | |_^ diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs index 62a119d662bb2..5dcf1824ef0b7 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -3,9 +3,9 @@ use clippy_utils::is_hir_ty_cfg_dependant; use if_chain::if_chain; use rustc_hir::{Expr, ExprKind, GenericArg}; use rustc_lint::LateContext; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; -use rustc_target::abi::LayoutOf; use super::CAST_PTR_ALIGNMENT; diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 685dbf26250ce..1ba241d377616 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -5,11 +5,11 @@ use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKi use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, TraitRef, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; use rustc_span::symbol::kw; -use rustc_target::abi::LayoutOf; use rustc_target::spec::abi::Abi; use rustc_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; @@ -171,7 +171,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { // skip if there is a `self` parameter binding to a type // that contains `Self` (i.e.: `self: Box`), see #4804 if let Some(trait_self_ty) = self.trait_self_ty { - if map.name(cmt.hir_id) == kw::SelfLower && contains_ty(self.cx.tcx, cmt.place.ty(), trait_self_ty) { + if map.name(cmt.hir_id) == kw::SelfLower && contains_ty(self.cx.tcx, cmt.place.ty(), trait_self_ty) + { return; } } diff --git a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs index 3b28b1212048a..b1f70b30c12cf 100644 --- a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs @@ -2,10 +2,10 @@ use std::cmp::Ordering; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, IntTy, UintTy}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; -use rustc_target::abi::LayoutOf; use clippy_utils::comparisons::Rel; use clippy_utils::consts::{constant, Constant}; diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 5d4e06c2af082..10281496c11cb 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -1,10 +1,10 @@ -use crate::rustc_target::abi::LayoutOf; use clippy_utils::diagnostics::span_lint_and_then; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::interpret::ConstValue; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ConstKind}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{BytePos, Pos, Span}; diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index cde2336b690fd..e4b8e7546283b 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -6,8 +6,8 @@ use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind, VariantData}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; +use rustc_middle::ty::layout::LayoutOf; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_target::abi::LayoutOf; declare_clippy_lint! { /// ### What it does diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 7088630bfdbb4..bbb6c1f902ce0 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -4,11 +4,10 @@ use if_chain::if_chain; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::interpret::ConstValue; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ConstKind}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use crate::rustc_target::abi::LayoutOf; - declare_clippy_lint! { /// ### What it does /// Checks for local arrays that may be too large. diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs index 2fddea7068d96..7ecafa1f3ba5b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -6,7 +6,7 @@ use rustc_ast::ast; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_target::abi::LayoutOf; +use rustc_middle::ty::layout::LayoutOf; pub fn check( cx: &LateContext<'_>, diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 157b18c1f6b1f..6229b9608b3cb 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -13,10 +13,10 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{BindingAnnotation, Body, FnDecl, HirId, Impl, ItemKind, MutTy, Mutability, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; +use rustc_middle::ty::layout::LayoutOf; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span}; -use rustc_target::abi::LayoutOf; use rustc_target::spec::abi::Abi; use rustc_target::spec::Target; diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs index 7a444174626f4..e7e2016d8f2f3 100644 --- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs @@ -5,9 +5,9 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{self as hir, def_id::DefId, GenericArg, QPath, TyKind}; use rustc_lint::LateContext; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::TypeFoldable; use rustc_span::symbol::sym; -use rustc_target::abi::LayoutOf; use rustc_typeck::hir_ty_to_ty; use super::VEC_BOX; diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs index 95a45fa937f11..e76d5f81c9640 100644 --- a/src/tools/clippy/clippy_lints/src/vec.rs +++ b/src/tools/clippy/clippy_lints/src/vec.rs @@ -1,4 +1,3 @@ -use crate::rustc_target::abi::LayoutOf; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::higher; @@ -8,6 +7,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 2fbe27f94798b..8e1cd655b6111 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -3,10 +3,10 @@ use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item}; use if_chain::if_chain; use rustc_hir::{self as hir, HirId, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{Adt, Ty, TypeFoldable}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; -use rustc_target::abi::LayoutOf as _; use rustc_typeck::hir_ty_to_ty; declare_clippy_lint! {