Skip to content

Commit

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

Rollup of 7 pull requests

Successful merges:

 - rust-lang#116099 (Add regression test for issue rust-lang#79865)
 - rust-lang#116102 (Correct codegen of `ConstValue::Indirect` scalar and scalar pair)
 - rust-lang#116131 (Rename `cold_path` to `outline`)
 - rust-lang#116144 (subst -> instantiate)
 - rust-lang#116151 (Fix typo in rustdoc unstable features doc)
 - rust-lang#116153 (Update books)
 - rust-lang#116162 (Gate and validate `#[rustc_safe_intrinsic]`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Sep 26, 2023
2 parents 8bf0dec + b62471d commit c35a363
Show file tree
Hide file tree
Showing 52 changed files with 212 additions and 118 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ use std::ptr::{self, NonNull};
use std::slice;
use std::{cmp, intrinsics};

/// This calls the passed function while ensuring it won't be inlined into the caller.
#[inline(never)]
#[cold]
fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
fn outline<F: FnOnce() -> R, R>(f: F) -> R {
f()
}

Expand Down Expand Up @@ -600,7 +601,7 @@ impl DroplessArena {
unsafe { self.write_from_iter(iter, len, mem) }
}
(_, _) => {
cold_path(move || -> &mut [T] {
outline(move || -> &mut [T] {
let mut vec: SmallVec<[_; 8]> = iter.collect();
if vec.is_empty() {
return &mut [];
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
lifetime.ident,
));

// Now make an arg that we can use for the substs of the opaque tykind.
// Now make an arg that we can use for the generic params of the opaque tykind.
let id = self.next_node_id();
let lifetime_arg = self.new_named_lifetime_with_res(id, lifetime.ident, res);
let duplicated_lifetime_def_id = self.local_def_id(duplicated_lifetime_node_id);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub(crate) struct RegionName {
/// This helps to print the right kinds of diagnostics.
#[derive(Debug, Clone)]
pub(crate) enum RegionNameSource {
/// A bound (not free) region that was substituted at the def site (not an HRTB).
/// A bound (not free) region that was instantiated at the def site (not an HRTB).
NamedEarlyBoundRegion(Span),
/// A free region that the user has a name (`'a`) for.
NamedFreeRegion(Span),
Expand Down Expand Up @@ -619,7 +619,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
// programs, so we need to use delay_span_bug here. See #82126.
self.infcx.tcx.sess.delay_span_bug(
hir_arg.span(),
format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"),
format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2250,7 +2250,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {

pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
// Query canonicalization can create local superuniverses (for example in
// `InferCtx::query_response_substitution_guess`), but they don't have an associated
// `InferCtx::query_response_instantiation_guess`), but they don't have an associated
// `UniverseInfo` explaining why they were created.
// This can cause ICEs if these causes are accessed in diagnostics, for example in issue
// #114907 where this happens via liveness and dropck outlives results.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}

pub(super) fn register_predefined_opaques_in_new_solver(&mut self) {
// OK to use the identity substitutions for each opaque type key, since
// OK to use the identity arguments for each opaque type key, since
// we remap opaques from HIR typeck back to their definition params.
let opaques: Vec<_> = self
.infcx
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,10 +639,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
};

let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
let subst_mapping =
iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));

UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static }
}

fn compute_inputs_and_output(
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
stack = &stack[..index + ENCODE_METADATA.len()];
}

const SUBST_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::subst_and_normalize_erasing_regions";
if let Some(index) = stack.find(SUBST_AND_NORMALIZE_ERASING_REGIONS) {
stack = &stack[..index + SUBST_AND_NORMALIZE_ERASING_REGIONS.len()];
const INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::instantiate_and_normalize_erasing_regions";
if let Some(index) = stack.find(INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS) {
stack = &stack[..index + INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS.len()];
}

const NORMALIZE_ERASING_LATE_BOUND_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::normalize_erasing_late_bound_regions";
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
{
self.instance.subst_mir_and_normalize_erasing_regions(
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(value),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn make_mir_scope<'ll, 'tcx>(
Some((callee, _)) => {
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
let callee = cx.tcx.subst_and_normalize_erasing_regions(
let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(callee),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) {
// If the method does *not* belong to a trait, proceed
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
cx.tcx.type_of(impl_def_id),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
T: Copy + TypeFoldable<TyCtxt<'tcx>>,
{
debug!("monomorphize: self.instance={:?}", self.instance);
self.instance.subst_mir_and_normalize_erasing_regions(
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.cx.tcx(),
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(value),
Expand Down
23 changes: 11 additions & 12 deletions compiler/rustc_codegen_ssa/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
assert_eq!(alloc_align, layout.align.abi);

let read_scalar = |start, size, s: abi::Scalar, ty| {
let val = alloc
.0
.read_scalar(
bx,
alloc_range(start, size),
/*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
)
.unwrap();
bx.scalar_to_backend(val, s, ty)
match alloc.0.read_scalar(
bx,
alloc_range(start, size),
/*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
) {
Ok(val) => bx.scalar_to_backend(val, s, ty),
Err(_) => bx.const_poison(ty),
}
};

// It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point.
Expand All @@ -156,18 +155,18 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
Abi::Scalar(s @ abi::Scalar::Initialized { .. }) => {
let size = s.size(bx);
assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
let val = read_scalar(Size::ZERO, size, s, bx.type_ptr());
let val = read_scalar(offset, size, s, bx.backend_type(layout));
OperandRef { val: OperandValue::Immediate(val), layout }
}
Abi::ScalarPair(
a @ abi::Scalar::Initialized { .. },
b @ abi::Scalar::Initialized { .. },
) => {
let (a_size, b_size) = (a.size(bx), b.size(bx));
let b_offset = a_size.align_to(b.align(bx).abi);
let b_offset = (offset + a_size).align_to(b.align(bx).abi);
assert!(b_offset.bytes() > 0);
let a_val = read_scalar(
Size::ZERO,
offset,
a_size,
a,
bx.scalar_pair_element_backend_type(layout, 0, true),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> Result<T, ErrorHandled> {
frame
.instance
.try_subst_mir_and_normalize_erasing_regions(
.try_instantiate_mir_and_normalize_erasing_regions(
*self.tcx,
self.param_env,
ty::EarlyBinder::bind(value),
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/src/interpret/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_middle::ty::{
};
use std::ops::ControlFlow;

/// Checks whether a type contains generic parameters which require substitution.
/// Checks whether a type contains generic parameters which must be instantiated.
///
/// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization
/// types may be "concrete enough" even though they still contain generic parameters in
Expand Down Expand Up @@ -43,7 +43,8 @@ where
.try_into()
.expect("more generic parameters than can fit into a `u32`");
// Only recurse when generic parameters in fns, closures and generators
// are used and require substitution.
// are used and have to be instantiated.
//
// Just in case there are closures or generators within this subst,
// recurse.
if unused_params.is_used(index) && subst.has_param() {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
}
}

/// A faster version of the validation pass that only checks those things which may break when apply
/// generic substitutions.
/// A faster version of the validation pass that only checks those things which may break when
/// instantiating any generic parameters.
pub fn validate_types<'tcx>(
tcx: TyCtxt<'tcx>,
mir_phase: MirPhase,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ use std::fmt;

pub use rustc_index::static_assert_size;

/// This calls the passed function while ensuring it won't be inlined into the caller.
#[inline(never)]
#[cold]
pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
pub fn outline<F: FnOnce() -> R, R>(f: F) -> R {
f()
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@
//!
//! [mm]: https://github.com/rust-lang/measureme/

use crate::cold_path;
use crate::fx::FxHashMap;
use crate::outline;

use std::borrow::Borrow;
use std::collections::hash_map::Entry;
Expand Down Expand Up @@ -697,7 +697,7 @@ impl<'a> TimingGuard<'a> {
#[inline]
pub fn finish_with_query_invocation_id(self, query_invocation_id: QueryInvocationId) {
if let Some(guard) = self.0 {
cold_path(|| {
outline(|| {
let event_id = StringId::new_virtual(query_invocation_id.0);
let event_id = EventId::from_virtual(event_id);
guard.finish_with_override_event_id(event_id);
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_data_structures/src/sync/worker_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::ptr;
use std::sync::Arc;

#[cfg(parallel_compiler)]
use {crate::cold_path, crate::sync::CacheAligned};
use {crate::outline, crate::sync::CacheAligned};

/// A pointer to the `RegistryData` which uniquely identifies a registry.
/// This identifier can be reused if the registry gets freed.
Expand All @@ -25,11 +25,7 @@ impl RegistryId {
fn verify(self) -> usize {
let (id, index) = THREAD_DATA.with(|data| (data.registry_id.get(), data.index.get()));

if id == self {
index
} else {
cold_path(|| panic!("Unable to verify registry association"))
}
if id == self { index } else { outline(|| panic!("Unable to verify registry association")) }
}
}

Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0038.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,13 @@ fn foo<T>(x: T) {
```

The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any
other type substitution is different. Hence the compiler generates the
other instantiation is different. Hence the compiler generates the
implementation on-demand. If you call `foo()` with a `bool` parameter, the
compiler will only generate code for `foo::<bool>()`. When we have additional
type parameters, the number of monomorphized implementations the compiler
generates does not grow drastically, since the compiler will only generate an
implementation if the function is called with unparameterized substitutions
(i.e., substitutions where none of the substituted types are themselves
parameterized).
implementation if the function is called with fully concrete arguments
(i.e., arguments which do not contain any generic parameters).

However, with trait objects we have to make a table containing _every_ object
that implements the trait. Now, if it has type parameters, we need to add
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0094.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ An invalid number of generic parameters was passed to an intrinsic function.
Erroneous code example:

```compile_fail,E0094
#![feature(intrinsics)]
#![feature(intrinsics, rustc_attrs)]
#![allow(internal_features)]
extern "rust-intrinsic" {
Expand All @@ -18,7 +18,7 @@ and verify with the function declaration in the Rust source code.
Example:

```
#![feature(intrinsics)]
#![feature(intrinsics, rustc_attrs)]
#![allow(internal_features)]
extern "rust-intrinsic" {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0211.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ You used a function or type which doesn't fit the requirements for where it was
used. Erroneous code examples:

```compile_fail
#![feature(intrinsics)]
#![feature(intrinsics, rustc_attrs)]
#![allow(internal_features)]
extern "rust-intrinsic" {
Expand Down Expand Up @@ -41,7 +41,7 @@ impl Foo {
For the first code example, please check the function definition. Example:

```
#![feature(intrinsics)]
#![feature(intrinsics, rustc_attrs)]
#![allow(internal_features)]
extern "rust-intrinsic" {
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
allow_internal_unsafe, Normal, template!(Word), WarnFollowing,
"allow_internal_unsafe side-steps the unsafe_code lint",
),
ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk),
rustc_attr!(rustc_allowed_through_unstable_modules, Normal, template!(Word), WarnFollowing,
"rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
through unstable paths"),
Expand Down Expand Up @@ -806,6 +805,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
r#"`rustc_doc_primitive` is a rustc internal attribute"#,
),
rustc_attr!(
rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
"the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
),

// ==========================================================================
// Internal attributes, Testing:
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
let bound_vars = tcx.late_bound_vars(binding.hir_id);
ty::Binder::bind_with_vars(subst_output, bound_vars)
} else {
// Include substitutions for generic parameters of associated types
// Append the generic arguments of the associated type to the `trait_ref`.
candidate.map_bound(|trait_ref| {
let ident = Ident::new(assoc_item.name, binding.item_name.span);
let item_segment = hir::PathSegment {
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_hir_analysis/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,22 +139,22 @@ fn generic_arg_mismatch_err(
err.emit()
}

/// Creates the relevant generic argument substitutions
/// Creates the relevant generic arguments
/// corresponding to a set of generic parameters. This is a
/// rather complex function. Let us try to explain the role
/// of each of its parameters:
///
/// To start, we are given the `def_id` of the thing we are
/// creating the substitutions for, and a partial set of
/// substitutions `parent_args`. In general, the substitutions
/// for an item begin with substitutions for all the "parents" of
/// To start, we are given the `def_id` of the thing whose generic
/// parameters we are instantiating, and a partial set of
/// arguments `parent_args`. In general, the generic arguments
/// for an item begin with arguments for all the "parents" of
/// that item -- e.g., for a method it might include the
/// parameters from the impl.
///
/// Therefore, the method begins by walking down these parents,
/// starting with the outermost parent and proceed inwards until
/// it reaches `def_id`. For each parent `P`, it will check `parent_args`
/// first to see if the parent's substitutions are listed in there. If so,
/// first to see if the parent's arguments are listed in there. If so,
/// we can append those and move on. Otherwise, it invokes the
/// three callback functions:
///
Expand Down Expand Up @@ -188,15 +188,16 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
stack.push((def_id, parent_defs));
}

// We manually build up the substitution, rather than using convenience
// We manually build up the generic arguments, rather than using convenience
// methods in `subst.rs`, so that we can iterate over the arguments and
// parameters in lock-step linearly, instead of trying to match each pair.
let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
// Iterate over each segment of the path.
while let Some((def_id, defs)) = stack.pop() {
let mut params = defs.params.iter().peekable();

// If we have already computed substitutions for parents, we can use those directly.
// If we have already computed the generic arguments for parents,
// we can use those directly.
while let Some(&param) = params.peek() {
if let Some(&kind) = parent_args.get(param.index as usize) {
args.push(kind);
Expand Down
Loading

0 comments on commit c35a363

Please sign in to comment.