Skip to content

Commit

Permalink
Auto merge of rust-lang#120876 - matthiaskrgr:rollup-ava53mi, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#117614 (static mut: allow mutable reference to arbitrary types, not just slices and arrays)
 - rust-lang#120588 (wasm: Store rlib metadata in wasm object files)
 - rust-lang#120719 (Remove support for `associated_type_bound` nested in `dyn` types)
 - rust-lang#120823 (Clarify that atomic and regular integers can differ in alignment)
 - rust-lang#120859 (Loosen an assertion to account for stashed errors.)
 - rust-lang#120865 (Turn the "no saved object file in work product" ICE into a translatable fatal error)
 - rust-lang#120866 (Remove unnecessary `#![feature(min_specialization)]`)
 - rust-lang#120870 (Allow restricted trait impls under `#[allow_internal_unstable(min_specialization)]`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Feb 10, 2024
2 parents 232919c + 6966cad commit db92e8a
Show file tree
Hide file tree
Showing 61 changed files with 308 additions and 549 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2608,6 +2608,7 @@ dependencies = [
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
"ruzstd",
"wasmparser",
]

[[package]]
Expand Down Expand Up @@ -6036,6 +6037,16 @@ version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"

[[package]]
name = "wasmparser"
version = "0.118.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9"
dependencies = [
"indexmap",
"semver",
]

[[package]]
name = "web-sys"
version = "0.3.61"
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(min_specialization)]
#![cfg_attr(bootstrap, feature(min_specialization))]
#![feature(negative_impls)]
#![feature(stmt_expr_attributes)]

Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_ast_lowering/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ ast_lowering_arbitrary_expression_in_pattern =
ast_lowering_argument = argument
ast_lowering_assoc_ty_binding_in_dyn =
associated type bounds are not allowed in `dyn` types
.suggestion = use `impl Trait` to introduce a type instead
ast_lowering_assoc_ty_parentheses =
parenthesized generic arguments cannot be used in associated type constraints
Expand Down Expand Up @@ -100,9 +104,6 @@ ast_lowering_match_arm_with_no_body =
`match` arm with no body
.suggestion = add a body after the pattern
ast_lowering_misplaced_assoc_ty_binding =
associated type bounds are only allowed in where clauses and function signatures, not in {$position}
ast_lowering_misplaced_double_dot =
`..` patterns are not allowed here
.note = only allowed in tuple, tuple struct, and slice patterns
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ pub struct MisplacedImplTrait<'a> {
}

#[derive(Diagnostic)]
#[diag(ast_lowering_misplaced_assoc_ty_binding)]
pub struct MisplacedAssocTyBinding<'a> {
#[diag(ast_lowering_assoc_ty_binding_in_dyn)]
pub struct MisplacedAssocTyBinding {
#[primary_span]
pub span: Span,
pub position: DiagnosticArgFromDisplay<'a>,
#[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
pub suggestion: Option<Span>,
}

#[derive(Diagnostic, Clone, Copy)]
Expand Down
116 changes: 30 additions & 86 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ trait ResolverAstLoweringExt {
fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId);
}

impl ResolverAstLoweringExt for ResolverAstLowering {
Expand Down Expand Up @@ -256,11 +255,6 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
}

fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId) {
let lifetimes = self.extra_lifetime_params_map.remove(&from).unwrap_or_default();
self.extra_lifetime_params_map.insert(to, lifetimes);
}
}

/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
Expand Down Expand Up @@ -1084,88 +1078,38 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TypeBindingKind::Equality { term }
}
AssocConstraintKind::Bound { bounds } => {
enum DesugarKind {
ImplTrait,
Error(ImplTraitPosition),
Bound,
}

// Piggy-back on the `impl Trait` context to figure out the correct behavior.
let desugar_kind = match itctx {
// in an argument, RPIT, or TAIT, if we are within a dyn type:
//
// fn foo(x: dyn Iterator<Item: Debug>)
//
// then desugar to:
//
// fn foo(x: dyn Iterator<Item = impl Debug>)
//
// This is because dyn traits must have all of their associated types specified.
ImplTraitContext::ReturnPositionOpaqueTy { .. }
| ImplTraitContext::TypeAliasesOpaqueTy { .. }
| ImplTraitContext::Universal
if self.is_in_dyn_type =>
{
DesugarKind::ImplTrait
}

ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
DesugarKind::Error(position)
}

// We are in the parameter position, but not within a dyn type:
//
// fn foo(x: impl Iterator<Item: Debug>)
//
// so we leave it as is and this gets expanded in astconv to a bound like
// `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
// `impl Iterator`.
_ => DesugarKind::Bound,
};

match desugar_kind {
DesugarKind::ImplTrait => {
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
// constructing the HIR for `impl bounds...` and then lowering that.

let impl_trait_node_id = self.next_node_id();
// Shift `impl Trait` lifetime captures from the associated type bound's
// node id to the opaque node id, so that the opaque can actually use
// these lifetime bounds.
self.resolver
.remap_extra_lifetime_params(constraint.id, impl_trait_node_id);

self.with_dyn_type_scope(false, |this| {
let node_id = this.next_node_id();
let ty = this.lower_ty(
&Ty {
id: node_id,
kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
span: this.lower_span(constraint.span),
tokens: None,
},
itctx,
);
// Disallow ATB in dyn types
if self.is_in_dyn_type {
let suggestion = match itctx {
ImplTraitContext::ReturnPositionOpaqueTy { .. }
| ImplTraitContext::TypeAliasesOpaqueTy { .. }
| ImplTraitContext::Universal => {
let bound_end_span = constraint
.gen_args
.as_ref()
.map_or(constraint.ident.span, |args| args.span());
if bound_end_span.eq_ctxt(constraint.span) {
Some(self.tcx.sess.source_map().next_point(bound_end_span))
} else {
None
}
}
_ => None,
};

hir::TypeBindingKind::Equality { term: ty.into() }
})
}
DesugarKind::Bound => {
// Desugar `AssocTy: Bounds` into a type binding where the
// later desugars into a trait predicate.
let bounds = self.lower_param_bounds(bounds, itctx);
let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
span: constraint.span,
suggestion,
});
let err_ty =
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
hir::TypeBindingKind::Equality { term: err_ty.into() }
} else {
// Desugar `AssocTy: Bounds` into a type binding where the
// later desugars into a trait predicate.
let bounds = self.lower_param_bounds(bounds, itctx);

hir::TypeBindingKind::Constraint { bounds }
}
DesugarKind::Error(position) => {
let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
span: constraint.span,
position: DiagnosticArgFromDisplay(&position),
});
let err_ty =
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
hir::TypeBindingKind::Equality { term: err_ty.into() }
}
hir::TypeBindingKind::Constraint { bounds }
}
}
};
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#![feature(hash_raw_entry)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(impl_trait_in_assoc_type)]

#[macro_use]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ libc = "0.2.50"
[dependencies.object]
version = "0.32.1"
default-features = false
features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write"]
features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write", "wasm"]

[target.'cfg(windows)'.dependencies.windows]
version = "0.48.0"
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ codegen_ssa_no_module_named =
codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
codegen_ssa_no_saved_object_file = cached cgu {$cgu_name} should have an object file, but doesn't
codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
.note = {$output}
Expand Down
88 changes: 68 additions & 20 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
use rustc_metadata::creader::MetadataLoader;
use rustc_metadata::fs::METADATA_FILENAME;
use rustc_metadata::EncodedMetadata;
use rustc_serialize::leb128;
use rustc_session::Session;
use rustc_span::sym;
use rustc_target::abi::Endian;
Expand Down Expand Up @@ -420,10 +421,9 @@ pub enum MetadataPosition {
/// it's not in an allowlist of otherwise well known dwarf section names to
/// go into the final artifact.
///
/// * WebAssembly - we actually don't have any container format for this
/// target. WebAssembly doesn't support the `dylib` crate type anyway so
/// there's no need for us to support this at this time. Consequently the
/// metadata bytes are simply stored as-is into an rlib.
/// * WebAssembly - this uses wasm files themselves as the object file format
/// so an empty file with no linking metadata but a single custom section is
/// created holding our metadata.
///
/// * COFF - Windows-like targets create an object with a section that has
/// the `IMAGE_SCN_LNK_REMOVE` flag set which ensures that if the linker
Expand All @@ -438,22 +438,13 @@ pub fn create_wrapper_file(
data: &[u8],
) -> (Vec<u8>, MetadataPosition) {
let Some(mut file) = create_object_file(sess) else {
// This is used to handle all "other" targets. This includes targets
// in two categories:
//
// * Some targets don't have support in the `object` crate just yet
// to write an object file. These targets are likely to get filled
// out over time.
//
// * Targets like WebAssembly don't support dylibs, so the purpose
// of putting metadata in object files, to support linking rlibs
// into dylibs, is moot.
//
// In both of these cases it means that linking into dylibs will
// not be supported by rustc. This doesn't matter for targets like
// WebAssembly and for targets not supported by the `object` crate
// yet it means that work will need to be done in the `object` crate
// to add a case above.
if sess.target.is_like_wasm {
return (create_metadata_file_for_wasm(data, &section_name), MetadataPosition::First);
}

// Targets using this branch don't have support implemented here yet or
// they're not yet implemented in the `object` crate and will likely
// fill out this module over time.
return (data.to_vec(), MetadataPosition::Last);
};
let section = if file.format() == BinaryFormat::Xcoff {
Expand Down Expand Up @@ -532,6 +523,9 @@ pub fn create_compressed_metadata_file(
packed_metadata.extend(metadata.raw_data());

let Some(mut file) = create_object_file(sess) else {
if sess.target.is_like_wasm {
return create_metadata_file_for_wasm(&packed_metadata, b".rustc");
}
return packed_metadata.to_vec();
};
if file.format() == BinaryFormat::Xcoff {
Expand Down Expand Up @@ -624,3 +618,57 @@ pub fn create_compressed_metadata_file_for_xcoff(
file.append_section_data(section, data, 1);
file.write().unwrap()
}

/// Creates a simple WebAssembly object file, which is itself a wasm module,
/// that contains a custom section of the name `section_name` with contents
/// `data`.
///
/// NB: the `object` crate does not yet have support for writing the the wasm
/// object file format. The format is simple enough that for now an extra crate
/// from crates.io (such as `wasm-encoder`). The file format is:
///
/// * 4-byte header "\0asm"
/// * 4-byte version number - 1u32 in little-endian format
/// * concatenated sections, which for this object is always "custom sections"
///
/// Custom sections are then defined by:
/// * 1-byte section identifier - 0 for a custom section
/// * leb-encoded section length (size of the contents beneath this bullet)
/// * leb-encoded custom section name length
/// * custom section name
/// * section contents
///
/// One custom section, `linking`, is added here in accordance with
/// <https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md>
/// which is required to inform LLD that this is an object file but it should
/// otherwise basically ignore it if it otherwise looks at it. The linking
/// section currently is defined by a single version byte (2) and then further
/// sections, but we have no more sections, so it's just the byte "2".
///
/// The next custom section is the one we're interested in.
pub fn create_metadata_file_for_wasm(data: &[u8], section_name: &[u8]) -> Vec<u8> {
let mut bytes = b"\0asm\x01\0\0\0".to_vec();

let mut append_custom_section = |section_name: &[u8], data: &[u8]| {
let mut section_name_len = [0; leb128::max_leb128_len::<usize>()];
let off = leb128::write_usize_leb128(&mut section_name_len, section_name.len());
let section_name_len = &section_name_len[..off];

let mut section_len = [0; leb128::max_leb128_len::<usize>()];
let off = leb128::write_usize_leb128(
&mut section_len,
data.len() + section_name_len.len() + section_name.len(),
);
let section_len = &section_len[..off];

bytes.push(0u8);
bytes.extend_from_slice(section_len);
bytes.extend_from_slice(section_name_len);
bytes.extend_from_slice(section_name);
bytes.extend_from_slice(data);
};

append_custom_section(b"linking", &[2]);
append_custom_section(section_name, data);
bytes
}
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,9 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(

let object = load_from_incr_comp_dir(
cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)),
module.source.saved_files.get("o").expect("no saved object file in work product"),
module.source.saved_files.get("o").unwrap_or_else(|| {
cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name })
}),
);
let dwarf_object =
module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ pub struct NoNatvisDirectory {
pub error: Error,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_no_saved_object_file)]
pub struct NoSavedObjectFile<'a> {
pub cgu_name: &'a str,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_copy_path_buf)]
pub struct CopyPathBuf {
Expand Down

0 comments on commit db92e8a

Please sign in to comment.