Skip to content
73 changes: 71 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use rustc_type_ir::solve::{
};
use rustc_type_ir::{
self as ty, CanonicalVarValues, ClauseKind, InferCtxtLike, Interner, MayBeErased,
OpaqueTypeKey, PredicateKind, Region, TypeFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, TypingMode, eager_resolve_vars,
OpaqueTypeKey, PredicateKind, Region, RegionVid, TypeFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, eager_resolve_vars, max_universe,
};
use thin_vec::ThinVec;
use tracing::{Level, debug, instrument, trace, warn};
Expand Down Expand Up @@ -1612,6 +1612,75 @@ where
r.retain(|(outlives, _)| !outlives.is_trivial() && unique.insert(*outlives));
}

#[derive(Default)]
struct NonTrivialVars {
vars: HashSet<RegionVid>,
}
impl<I> TypeVisitor<I> for NonTrivialVars
where
I: Interner,
{
type Result = ();
fn visit_ty(&mut self, t: I::Ty) {
// If a nested type doesn't have any `ReVar`s, then we won't insert
// anything into `vars` anyway, so skip for better perf.
if !t.has_infer_regions() {
return;
}
t.super_visit_with(self);
}
fn visit_const(&mut self, c: I::Const) {
// The same goes for consts.
if !c.has_infer_regions() {
return;
}
c.super_visit_with(self);
}
fn visit_region(&mut self, r: Region<I>) {
if let ty::ReVar(vid) = r.kind() {
self.vars.insert(vid);
}
}
}

// If we have a constraint like `'re: '?1`, where '?1 can name 're and '?1 appears
// only on the RHS of region constraints, then this kind of constraint is also trivial,
// since we're able to pick '?1 := 'empty, and 're: 'empty is always true for any 're.
if let ExternalRegionConstraints::Old(r) = &mut external_constraints.region_constraints
&& !r.is_empty()
{
let mut vis = NonTrivialVars::default();
var_values.visit_with(&mut vis);
// We have to visit each component of `external_constraints` individually here
// because we skip the RHS of outlives constraints, and `TypeVisitor` doesn't
// have a method we can easily override in order to do this.
external_constraints.opaque_types.visit_with(&mut vis);
external_constraints.normalization_nested_goals.visit_with(&mut vis);
for (constraint, _) in r.iter() {
match constraint {
ty::RegionConstraint::Outlives(ty::OutlivesClause(sup, _)) => {
sup.visit_with(&mut vis)
}
ty::RegionConstraint::Eq(eq) => eq.visit_with(&mut vis),
}
}

r.retain(|(outlives, _)| {
if let ty::RegionConstraint::Outlives(ty::OutlivesClause(sup, re)) = *outlives
&& let Some(sup_re) = sup.as_region()
&& let ty::RegionKind::ReVar(vid) = re.kind()
// This is only safe if we call `eager_resolve_vars` beforehand,
// which we do.
&& self.delegate.universe_of_lt(vid).unwrap()
.can_name(max_universe(&**self.delegate, sup_re))
{
vis.vars.contains(&vid)
} else {
true
}
});
}

let canonical = canonicalize_response(
self.delegate,
self.max_input_universe,
Expand Down
32 changes: 24 additions & 8 deletions library/core/src/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,12 @@ macro_rules! impl_Display {
}

impl $Signed {
/// Allows users to write an integer (in signed decimal format) into a variable `buf` of
/// type [`NumBuffer`] that is passed by the caller by mutable reference.
/// Formats this integer as a signed decimal number, using the memory pointed to by
/// `buf` as storage for the returned string slice.
///
/// This method can be used to convert integers to strings without involving the
/// dynamic dispatch that using [`Display`][fmt::Display] would.
/// This may be more efficient in situations where [`fmt`] is not otherwise used.
///
/// # Examples
///
Expand Down Expand Up @@ -298,8 +302,12 @@ macro_rules! impl_Display {
}

impl $Unsigned {
/// Allows users to write an integer (in unsigned decimal format) into a variable `buf`
/// of type [`NumBuffer`] that is passed by the caller by mutable reference.
/// Formats this integer as an unsigned decimal number, using the memory pointed to by
/// `buf` as storage for the returned string slice.
///
/// This method can be used to convert integers to strings without involving the
/// dynamic dispatch that using [`Display`][fmt::Display] would.
/// This may be more efficient in situations where [`fmt`] is not otherwise used.
///
/// # Examples
///
Expand Down Expand Up @@ -740,8 +748,12 @@ impl u128 {
offset
}

/// Allows users to write an integer (in unsigned decimal format) into a variable `buf` of
/// type [`NumBuffer`] that is passed by the caller by mutable reference.
/// Formats this integer as an unsigned decimal number, using the memory pointed to by
/// `buf` as storage for the returned string slice.
///
/// This method can be used to convert integers to strings without involving the
/// dynamic dispatch that using [`Display`][fmt::Display] would.
/// This may be more efficient in situations where [`fmt`] is not otherwise used.
///
/// # Examples
///
Expand Down Expand Up @@ -774,8 +786,12 @@ impl u128 {
}

impl i128 {
/// Allows users to write an integer (in signed decimal format) into a variable `buf` of
/// type [`NumBuffer`] that is passed by the caller by mutable reference.
/// Formats this integer as a signed decimal number, using the memory pointed to by
/// `buf` as storage for the returned string slice.
///
/// This method can be used to convert integers to strings without involving the
/// dynamic dispatch that using [`Display`][fmt::Display] would.
/// This may be more efficient in situations where [`fmt`] is not otherwise used.
///
/// # Examples
///
Expand Down
11 changes: 9 additions & 2 deletions library/core/src/fmt/num_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ impl_NumBufferTrait! {
i128, u128,
}

/// A buffer wrapper of which the internal size is based on the maximum
/// number of digits the associated integer can have.
/// Memory for formatting numbers using [`T::format_into()`][u8::format_into].
///
/// This type consists of enough memory to hold the longest decimal string representation
/// a number of type `T` could have.
/// It is used only by calling `format_into()`; there is no other way to access its contents.
/// Its purpose is to allow formatting numbers without involving the dynamic dispatch of the
/// [`fmt`] system, which may be more efficient when [`fmt`] is not otherwise used.
///
/// [`fmt`]: crate::fmt
///
/// # Examples
///
Expand Down
8 changes: 8 additions & 0 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2140,6 +2140,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn saturating_div(self, rhs: Self) -> Self {
match self.overflowing_div(rhs) {
(result, false) => result,
Expand Down Expand Up @@ -2283,6 +2284,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn wrapping_div(self, rhs: Self) -> Self {
self.overflowing_div(rhs).0
}
Expand All @@ -2309,6 +2311,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
self.overflowing_div_euclid(rhs).0
}
Expand All @@ -2335,6 +2338,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn wrapping_rem(self, rhs: Self) -> Self {
self.overflowing_rem(rhs).0
}
Expand All @@ -2360,6 +2364,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
self.overflowing_rem_euclid(rhs).0
}
Expand Down Expand Up @@ -2856,6 +2861,7 @@ macro_rules! int_impl {
#[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[track_caller]
pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
// Using `&` helps LLVM see that it is the same check made in division.
if intrinsics::unlikely((self == Self::MIN) & (rhs == -1)) {
Expand Down Expand Up @@ -2885,6 +2891,7 @@ macro_rules! int_impl {
#[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[track_caller]
pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
// Using `&` helps LLVM see that it is the same check made in division.
if intrinsics::unlikely((self == Self::MIN) & (rhs == -1)) {
Expand Down Expand Up @@ -2914,6 +2921,7 @@ macro_rules! int_impl {
#[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[track_caller]
pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
if intrinsics::unlikely(rhs == -1) {
(0, self == Self::MIN)
Expand Down
10 changes: 4 additions & 6 deletions src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2669,7 +2669,7 @@ pub fn run_cargo(
let (filenames_vec, crate_types) = match msg {
CargoMessage::CompilerArtifact {
filenames,
target: CargoTarget { crate_types, .. },
target: CargoTarget { crate_types },
..
} => {
let mut f: Vec<String> = filenames.into_iter().map(|s| s.into_owned()).collect();
Expand Down Expand Up @@ -2876,14 +2876,12 @@ pub fn stream_cargo(
status.success()
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize)]
pub struct CargoTarget<'a> {
pub crate_types: Vec<Cow<'a, str>>,
#[serde(default)]
pub doc: bool,
crate_types: Vec<Cow<'a, str>>,
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize)]
#[serde(tag = "reason", rename_all = "kebab-case")]
pub enum CargoMessage<'a> {
CompilerArtifact { filenames: Vec<Cow<'a, str>>, target: CargoTarget<'a> },
Expand Down
9 changes: 4 additions & 5 deletions src/bootstrap/src/core/build_steps/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::core::backend::CodegenBackendKind;
use crate::core::build_steps::compile::{
get_codegen_backend_file, libgccjit_path_relative_to_cg_dir, normalize_codegen_backend_name,
};
use crate::core::build_steps::doc::{CompilerWithTools, DocumentationFormat};
use crate::core::build_steps::doc::DocumentationFormat;
use crate::core::build_steps::gcc::GccTargetPair;
use crate::core::build_steps::llvm::{
LLVM_CI_LINK_TYPE_PATH, LlvmBuildStatus, LlvmKind, get_llvm_build_status,
Expand Down Expand Up @@ -185,7 +185,7 @@ impl CommandLineStep for JsonDocs {
}
}

/// Builds the `rustc-docs` component.
/// Builds the `rustc-docs` installer component.
/// Apart from the documentation of the `rustc_*` crates, it also includes the documentation of
/// various in-tree helper tools (bootstrap, build_helper, tidy),
/// and also rustc_private tools like rustdoc, clippy, miri or rustfmt.
Expand Down Expand Up @@ -214,12 +214,11 @@ impl CommandLineStep for RustcDocs {

fn run(self, builder: &Builder<'_>) -> Self::Output {
let target = self.target;
let combined_docs =
builder.ensure(CompilerWithTools::for_stage(builder, builder.top_stage, self.target));
builder.run_default_doc_steps();

let mut tarball = Tarball::new(builder, "rustc-docs", &target.triple);
tarball.set_product_name("Rustc Documentation");
tarball.add_bulk_dir(combined_docs, "share/doc/rust/html/rustc-docs");
tarball.add_bulk_dir(builder.compiler_doc_out(target), "share/doc/rust/html/rustc-docs");
tarball.generate()
}
}
Expand Down
Loading
Loading