Skip to content

Commit

Permalink
Auto merge of #112839 - GuillaumeGomez:rollup-jc5nqug, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #112464 (Fix windows `Socket::connect_timeout` overflow)
 - #112720 (Rustdoc: search: color item type and reduce size to avoid clashing)
 - #112762 (Sort the errors from arguments checking so that suggestions are handled properly)
 - #112786 (change binders from tuple structs to named fields)
 - #112794 (Fix linker failures when #[global_allocator] is used in a dependency)
 - #112819 (Disable feature(unboxed_closures, fn_traits) in weird-exprs)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 20, 2023
2 parents 6fc0273 + 2368fa2 commit 1b6d4cd
Show file tree
Hide file tree
Showing 25 changed files with 226 additions and 92 deletions.
18 changes: 16 additions & 2 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::mir::place::PlaceRef;
use crate::traits::*;
use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCodegen, ModuleKind};

use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::expand::allocator::{global_fn_name, AllocatorKind, ALLOCATOR_METHODS};
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
Expand Down Expand Up @@ -921,7 +921,21 @@ impl CrateInfo {
missing_weak_lang_items
.iter()
.map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text)),
)
);
if tcx.allocator_kind(()).is_some() {
// At least one crate needs a global allocator. This crate may be placed
// after the crate that defines it in the linker order, in which case some
// linkers return an error. By adding the global allocator shim methods to
// the linked_symbols list, linking the generated symbols.o will ensure that
// circular dependencies involving the global allocator don't lead to linker
// errors.
linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
(
format!("{prefix}{}", global_fn_name(method.name).as_str()),
SymbolExportKind::Text,
)
}));
}
});
}

Expand Down
41 changes: 36 additions & 5 deletions compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::cmp;

use core::cmp::Ordering;
use rustc_index::IndexVec;
use rustc_middle::ty::error::TypeError;
use std::cmp;

rustc_index::newtype_index! {
#[debug_format = "ExpectedIdx({})"]
Expand Down Expand Up @@ -34,14 +34,14 @@ enum Issue {
Permutation(Vec<Option<usize>>),
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) enum Compatibility<'tcx> {
Compatible,
Incompatible(Option<TypeError<'tcx>>),
}

/// Similar to `Issue`, but contains some extra information
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum Error<'tcx> {
/// The provided argument is the invalid type for the expected input
Invalid(ProvidedIdx, ExpectedIdx, Compatibility<'tcx>),
Expand All @@ -55,6 +55,34 @@ pub(crate) enum Error<'tcx> {
Permutation(Vec<(ExpectedIdx, ProvidedIdx)>),
}

impl Ord for Error<'_> {
fn cmp(&self, other: &Self) -> Ordering {
let key = |error: &Error<'_>| -> usize {
match error {
Error::Invalid(..) => 0,
Error::Extra(_) => 1,
Error::Missing(_) => 2,
Error::Swap(..) => 3,
Error::Permutation(..) => 4,
}
};
match (self, other) {
(Error::Invalid(a, _, _), Error::Invalid(b, _, _)) => a.cmp(b),
(Error::Extra(a), Error::Extra(b)) => a.cmp(b),
(Error::Missing(a), Error::Missing(b)) => a.cmp(b),
(Error::Swap(a, b, ..), Error::Swap(c, d, ..)) => a.cmp(c).then(b.cmp(d)),
(Error::Permutation(a), Error::Permutation(b)) => a.cmp(b),
_ => key(self).cmp(&key(other)),
}
}
}

impl PartialOrd for Error<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

pub(crate) struct ArgMatrix<'tcx> {
/// Maps the indices in the `compatibility_matrix` rows to the indices of
/// the *user provided* inputs
Expand Down Expand Up @@ -177,7 +205,7 @@ impl<'tcx> ArgMatrix<'tcx> {
// If an argument is unsatisfied, and the input in its position is useless
// then the most likely explanation is that we just got the types wrong
(true, true, true, true) => return Some(Issue::Invalid(i)),
// Otherwise, if an input is useless, then indicate that this is an extra argument
// Otherwise, if an input is useless then indicate that this is an extra input
(true, _, true, _) => return Some(Issue::Extra(i)),
// Otherwise, if an argument is unsatisfiable, indicate that it's missing
(_, true, _, true) => return Some(Issue::Missing(i)),
Expand Down Expand Up @@ -376,6 +404,9 @@ impl<'tcx> ArgMatrix<'tcx> {
};
}

// sort errors with same type by the order they appear in the source
// so that suggestion will be handled properly, see #112507
errors.sort();
return (errors, matched_inputs);
}
}
62 changes: 32 additions & 30 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,10 @@ impl BoundVariableKind {
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(HashStable, Lift)]
pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
pub struct Binder<'tcx, T> {
value: T,
bound_vars: &'tcx List<BoundVariableKind>,
}

impl<'tcx, T> Binder<'tcx, T>
where
Expand All @@ -1023,15 +1026,15 @@ where
!value.has_escaping_bound_vars(),
"`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
);
Binder(value, ty::List::empty())
Binder { value, bound_vars: ty::List::empty() }
}

pub fn bind_with_vars(value: T, vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
if cfg!(debug_assertions) {
let mut validator = ValidateBoundVars::new(vars);
let mut validator = ValidateBoundVars::new(bound_vars);
value.visit_with(&mut validator);
}
Binder(value, vars)
Binder { value, bound_vars }
}
}

Expand All @@ -1053,30 +1056,30 @@ impl<'tcx, T> Binder<'tcx, T> {
/// - comparing the self type of a PolyTraitRef to see if it is equal to
/// a type parameter `X`, since the type `X` does not reference any regions
pub fn skip_binder(self) -> T {
self.0
self.value
}

pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> {
self.1
self.bound_vars
}

pub fn as_ref(&self) -> Binder<'tcx, &T> {
Binder(&self.0, self.1)
Binder { value: &self.value, bound_vars: self.bound_vars }
}

pub fn as_deref(&self) -> Binder<'tcx, &T::Target>
where
T: Deref,
{
Binder(&self.0, self.1)
Binder { value: &self.value, bound_vars: self.bound_vars }
}

pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
where
F: FnOnce(&T) -> U,
{
let value = f(&self.0);
Binder(value, self.1)
let value = f(&self.value);
Binder { value, bound_vars: self.bound_vars }
}

pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
Expand All @@ -1090,12 +1093,13 @@ impl<'tcx, T> Binder<'tcx, T> {
where
F: FnOnce(T) -> U,
{
let value = f(self.0);
let Binder { value, bound_vars } = self;
let value = f(value);
if cfg!(debug_assertions) {
let mut validator = ValidateBoundVars::new(self.1);
let mut validator = ValidateBoundVars::new(bound_vars);
value.visit_with(&mut validator);
}
Binder(value, self.1)
Binder { value, bound_vars }
}

pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
Expand All @@ -1105,12 +1109,13 @@ impl<'tcx, T> Binder<'tcx, T> {
where
F: FnOnce(T) -> Result<U, E>,
{
let value = f(self.0)?;
let Binder { value, bound_vars } = self;
let value = f(value)?;
if cfg!(debug_assertions) {
let mut validator = ValidateBoundVars::new(self.1);
let mut validator = ValidateBoundVars::new(bound_vars);
value.visit_with(&mut validator);
}
Ok(Binder(value, self.1))
Ok(Binder { value, bound_vars })
}

/// Wraps a `value` in a binder, using the same bound variables as the
Expand All @@ -1126,11 +1131,7 @@ impl<'tcx, T> Binder<'tcx, T> {
where
U: TypeVisitable<TyCtxt<'tcx>>,
{
if cfg!(debug_assertions) {
let mut validator = ValidateBoundVars::new(self.bound_vars());
value.visit_with(&mut validator);
}
Binder(value, self.1)
Binder::bind_with_vars(value, self.bound_vars)
}

/// Unwraps and returns the value within, but only if it contains
Expand All @@ -1147,7 +1148,7 @@ impl<'tcx, T> Binder<'tcx, T> {
where
T: TypeVisitable<TyCtxt<'tcx>>,
{
if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
}

/// Splits the contents into two things that share the same binder
Expand All @@ -1160,22 +1161,23 @@ impl<'tcx, T> Binder<'tcx, T> {
where
F: FnOnce(T) -> (U, V),
{
let (u, v) = f(self.0);
(Binder(u, self.1), Binder(v, self.1))
let Binder { value, bound_vars } = self;
let (u, v) = f(value);
(Binder { value: u, bound_vars }, Binder { value: v, bound_vars })
}
}

impl<'tcx, T> Binder<'tcx, Option<T>> {
pub fn transpose(self) -> Option<Binder<'tcx, T>> {
let bound_vars = self.1;
self.0.map(|v| Binder(v, bound_vars))
let Binder { value, bound_vars } = self;
value.map(|value| Binder { value, bound_vars })
}
}

impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> {
let bound_vars = self.1;
self.0.into_iter().map(|v| Binder(v, bound_vars))
let Binder { value, bound_vars } = self;
value.into_iter().map(|value| Binder { value, bound_vars })
}
}

Expand All @@ -1184,7 +1186,7 @@ where
T: IntoDiagnosticArg,
{
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
self.0.into_diagnostic_arg()
self.value.into_diagnostic_arg()
}
}

Expand Down
Loading

0 comments on commit 1b6d4cd

Please sign in to comment.