diff options
Diffstat (limited to 'compiler/rustc_metadata')
| -rw-r--r-- | compiler/rustc_metadata/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/dependency_format.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/errors.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/mod.rs | 1 |
7 files changed, 60 insertions, 15 deletions
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index f456dd09dea..3d0846ae6de 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -38,6 +38,9 @@ metadata_crate_dep_multiple = cannot satisfy dependencies so `{$crate_name}` only shows up once .help = having upstream crates all available in one format will likely make this go away +metadata_crate_dep_not_static = + `{$crate_name}` was unavailable as a static crate, preventing fully static linking + metadata_crate_location_unknown_type = extern location for {$crate_name} is of an unknown type: {$path} diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index b80a9e9612a..4d1bd455412 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -54,7 +54,7 @@ use crate::creader::CStore; use crate::errors::{ BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired, - RequiredPanicStrategy, RlibRequired, RustcLibRequired, TwoPanicRuntimes, + NonStaticCrateDep, RequiredPanicStrategy, RlibRequired, RustcLibRequired, TwoPanicRuntimes, }; use rustc_data_structures::fx::FxHashMap; @@ -123,13 +123,15 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { CrateType::Rlib => Linkage::NotLinked, }; + let mut unavailable_as_static = Vec::new(); + match preferred_linkage { // If the crate is not linked, there are no link-time dependencies. Linkage::NotLinked => return Vec::new(), Linkage::Static => { // Attempt static linkage first. For dylibs and executables, we may be // able to retry below with dynamic linkage. - if let Some(v) = attempt_static(tcx) { + if let Some(v) = attempt_static(tcx, &mut unavailable_as_static) { return v; } @@ -169,11 +171,11 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { let src = tcx.used_crate_source(cnum); if src.dylib.is_some() { info!("adding dylib: {}", name); - add_library(tcx, cnum, RequireDynamic, &mut formats); + add_library(tcx, cnum, RequireDynamic, &mut formats, &mut unavailable_as_static); let deps = tcx.dylib_dependency_formats(cnum); for &(depnum, style) in deps.iter() { info!("adding {:?}: {}", style, tcx.crate_name(depnum)); - add_library(tcx, depnum, style, &mut formats); + add_library(tcx, depnum, style, &mut formats, &mut unavailable_as_static); } } } @@ -201,7 +203,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { { assert!(src.rlib.is_some() || src.rmeta.is_some()); info!("adding staticlib: {}", tcx.crate_name(cnum)); - add_library(tcx, cnum, RequireStatic, &mut formats); + add_library(tcx, cnum, RequireStatic, &mut formats, &mut unavailable_as_static); ret[cnum.as_usize() - 1] = Linkage::Static; } } @@ -252,6 +254,7 @@ fn add_library( cnum: CrateNum, link: LinkagePreference, m: &mut FxHashMap<CrateNum, LinkagePreference>, + unavailable_as_static: &mut Vec<CrateNum>, ) { match m.get(&cnum) { Some(&link2) => { @@ -263,7 +266,13 @@ fn add_library( // This error is probably a little obscure, but I imagine that it // can be refined over time. if link2 != link || link == RequireStatic { - tcx.dcx().emit_err(CrateDepMultiple { crate_name: tcx.crate_name(cnum) }); + tcx.dcx().emit_err(CrateDepMultiple { + crate_name: tcx.crate_name(cnum), + non_static_deps: unavailable_as_static + .drain(..) + .map(|cnum| NonStaticCrateDep { crate_name: tcx.crate_name(cnum) }) + .collect(), + }); } } None => { @@ -272,7 +281,7 @@ fn add_library( } } -fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> { +fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<DependencyList> { let all_crates_available_as_rlib = tcx .crates(()) .iter() @@ -281,7 +290,11 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> { if tcx.dep_kind(cnum).macros_only() { return None; } - Some(tcx.used_crate_source(cnum).rlib.is_some()) + let is_rlib = tcx.used_crate_source(cnum).rlib.is_some(); + if !is_rlib { + unavailable.push(cnum); + } + Some(is_rlib) }) .all(|is_rlib| is_rlib); if !all_crates_available_as_rlib { diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 8bf6b665de8..b50ae057709 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -38,6 +38,14 @@ pub struct RustcLibRequired<'a> { #[help] pub struct CrateDepMultiple { pub crate_name: Symbol, + #[subdiagnostic] + pub non_static_deps: Vec<NonStaticCrateDep>, +} + +#[derive(Subdiagnostic)] +#[note(metadata_crate_dep_not_static)] +pub struct NonStaticCrateDep { + pub crate_name: Symbol, } #[derive(Diagnostic)] diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 03783fa9798..596da58b091 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1063,6 +1063,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ty::EarlyBinder::bind(&*output) } + fn get_explicit_item_super_predicates( + self, + index: DefIndex, + tcx: TyCtxt<'tcx>, + ) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> { + let lazy = self.root.tables.explicit_item_super_predicates.get(self, index); + let output = if lazy.is_default() { + &mut [] + } else { + tcx.arena.alloc_from_iter(lazy.decode((self, tcx))) + }; + ty::EarlyBinder::bind(&*output) + } + fn get_variant( self, kind: DefKind, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 1c59af51589..1aabd296641 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -206,6 +206,7 @@ impl IntoArgs for (CrateNum, SimplifiedType) { provide! { tcx, def_id, other, cdata, explicit_item_bounds => { cdata.get_explicit_item_bounds(def_id.index, tcx) } + explicit_item_super_predicates => { cdata.get_explicit_item_super_predicates(def_id.index, tcx) } explicit_predicates_of => { table } generics_of => { table } inferred_outlives_of => { table_defaulted_array } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d8cfceab460..42724f7dd2b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -817,8 +817,8 @@ struct AnalyzeAttrState { #[inline] fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState) -> bool { let mut should_encode = false; - if rustc_feature::is_builtin_only_local(attr.name_or_empty()) { - // Attributes marked local-only don't need to be encoded for downstream crates. + if !rustc_feature::encode_cross_crate(attr.name_or_empty()) { + // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. } else if attr.doc_str().is_some() { // We keep all doc comments reachable to rustdoc because they might be "imported" into // downstream crates if they use `#[doc(inline)]` to copy an item's documentation into @@ -1067,14 +1067,11 @@ fn should_encode_mir( // Full-fledged functions + closures DefKind::AssocFn | DefKind::Fn | DefKind::Closure => { let generics = tcx.generics_of(def_id); - let mut opt = tcx.sess.opts.unstable_opts.always_encode_mir + let opt = tcx.sess.opts.unstable_opts.always_encode_mir || (tcx.sess.opts.output_types.should_codegen() && reachable_set.contains(&def_id) && (generics.requires_monomorphization(tcx) || tcx.cross_crate_inlinable(def_id))); - if let Some(intrinsic) = tcx.intrinsic(def_id) { - opt &= !intrinsic.must_be_overridden; - } // The function has a `const` modifier or is in a `#[const_trait]`. let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id()) || tcx.is_const_default_method(def_id.to_def_id()); @@ -1494,6 +1491,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if let DefKind::OpaqueTy = def_kind { self.encode_explicit_item_bounds(def_id); + self.encode_explicit_item_super_predicates(def_id); self.tables .is_type_alias_impl_trait .set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id)); @@ -1602,6 +1600,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds); } + fn encode_explicit_item_super_predicates(&mut self, def_id: DefId) { + debug!("EncodeContext::encode_explicit_item_super_predicates({:?})", def_id); + let bounds = self.tcx.explicit_item_super_predicates(def_id).skip_binder(); + record_defaulted_array!(self.tables.explicit_item_super_predicates[def_id] <- bounds); + } + #[instrument(level = "debug", skip(self))] fn encode_info_for_assoc_item(&mut self, def_id: DefId) { let tcx = self.tcx; @@ -1614,6 +1618,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { AssocItemContainer::TraitContainer => { if let ty::AssocKind::Type = item.kind { self.encode_explicit_item_bounds(def_id); + self.encode_explicit_item_super_predicates(def_id); } } AssocItemContainer::ImplContainer => { @@ -2201,7 +2206,7 @@ impl<D: Decoder> Decodable<D> for EncodedMetadata { let mmap = if len > 0 { let mut mmap = MmapMut::map_anon(len).unwrap(); for _ in 0..len { - (&mut mmap[..]).write(&[d.read_u8()]).unwrap(); + (&mut mmap[..]).write_all(&[d.read_u8()]).unwrap(); } mmap.flush().unwrap(); Some(mmap.make_read_only().unwrap()) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 8aa31ef564f..5b0be8ac230 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -387,6 +387,7 @@ define_tables! { // corresponding DefPathHash. def_path_hashes: Table<DefIndex, u64>, explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, + explicit_item_super_predicates: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, inherent_impls: Table<DefIndex, LazyArray<DefIndex>>, associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>, |
