Skip to content

Commit

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

Rollup of 7 pull requests

Successful merges:

 - rust-lang#132232 (CI: build FreeBSD artifacts on FreeBSD 13.4)
 - rust-lang#135625 ([cfg_match] Document the use of expressions.)
 - rust-lang#135750 (Add an example of using `carrying_mul_add` to write wider multiplication)
 - rust-lang#135793 (Ignore `mermaid.min.js`)
 - rust-lang#135810 (Add Kobzol on vacation)
 - rust-lang#135816 (Use `structurally_normalize` instead of manual `normalizes-to` goals in alias relate errors)
 - rust-lang#135821 (fix OsString::from_encoded_bytes_unchecked description)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jan 21, 2025
2 parents cd805f0 + 1e3f266 commit f77ead0
Show file tree
Hide file tree
Showing 35 changed files with 322 additions and 134 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ __pycache__/
node_modules
package-lock.json
package.json
/src/doc/rustc-dev-guide/mermaid.min.js

## Rustdoc GUI tests
tests/rustdoc-gui/src/**.lock
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CustomTypeOp::new(
|ocx| {
let structurally_normalize = |ty| {
ocx.structurally_normalize(
ocx.structurally_normalize_ty(
&ObligationCause::misc(
location.to_locations().span(body),
body.source.def_id().expect_local(),
Expand Down Expand Up @@ -230,7 +230,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ConstraintCategory::Boring,
CustomTypeOp::new(
|ocx| {
ocx.structurally_normalize(
ocx.structurally_normalize_ty(
&ObligationCause::misc(
location.to_locations().span(body),
body.source.def_id().expect_local(),
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/autoderef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
if self.infcx.next_trait_solver()
&& let ty::Alias(..) = ty.kind()
{
let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
let (normalized_ty, obligations) = self.structurally_normalize_ty(ty)?;
self.state.obligations.extend(obligations);
(AutoderefKind::Builtin, normalized_ty)
} else {
Expand Down Expand Up @@ -166,20 +166,20 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
}

let (normalized_ty, obligations) =
self.structurally_normalize(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
self.structurally_normalize_ty(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
self.state.obligations.extend(obligations);

Some(self.infcx.resolve_vars_if_possible(normalized_ty))
}

#[instrument(level = "debug", skip(self), ret)]
pub fn structurally_normalize(
pub fn structurally_normalize_ty(
&self,
ty: Ty<'tcx>,
) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> {
let ocx = ObligationCtxt::new(self.infcx);
let Ok(normalized_ty) = ocx.structurally_normalize(
let Ok(normalized_ty) = ocx.structurally_normalize_ty(
&traits::ObligationCause::misc(self.span, self.body_id),
self.param_env,
ty,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ fn orphan_check<'tcx>(
}

let ty = if infcx.next_trait_solver() {
ocx.structurally_normalize(
ocx.structurally_normalize_ty(
&cause,
ty::ParamEnv::empty(),
infcx.resolve_vars_if_possible(ty),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if self.next_trait_solver()
&& let ty::Alias(..) = ty.kind()
{
ocx.structurally_normalize(&cause, self.param_env, ty)
ocx.structurally_normalize_ty(&cause, self.param_env, ty)
} else {
Ok(ty)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1433,7 +1433,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// in a reentrant borrow, causing an ICE.
let result = self
.at(&self.misc(sp), self.param_env)
.structurally_normalize(ty, &mut **self.fulfillment_cx.borrow_mut());
.structurally_normalize_ty(ty, &mut **self.fulfillment_cx.borrow_mut());
match result {
Ok(normalized_ty) => normalized_ty,
Err(errors) => {
Expand Down
42 changes: 19 additions & 23 deletions compiler/rustc_next_trait_solver/src/solve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,23 +277,7 @@ where
param_env: I::ParamEnv,
ty: I::Ty,
) -> Result<I::Ty, NoSolution> {
if let ty::Alias(..) = ty.kind() {
let normalized_ty = self.next_ty_infer();
let alias_relate_goal = Goal::new(
self.cx(),
param_env,
ty::PredicateKind::AliasRelate(
ty.into(),
normalized_ty.into(),
ty::AliasRelationDirection::Equate,
),
);
self.add_goal(GoalSource::Misc, alias_relate_goal);
self.try_evaluate_added_goals()?;
Ok(self.resolve_vars_if_possible(normalized_ty))
} else {
Ok(ty)
}
self.structurally_normalize_term(param_env, ty.into()).map(|term| term.expect_ty())
}

/// Normalize a const for when it is structurally matched on, or more likely
Expand All @@ -308,22 +292,34 @@ where
param_env: I::ParamEnv,
ct: I::Const,
) -> Result<I::Const, NoSolution> {
if let ty::ConstKind::Unevaluated(..) = ct.kind() {
let normalized_ct = self.next_const_infer();
self.structurally_normalize_term(param_env, ct.into()).map(|term| term.expect_const())
}

/// Normalize a term for when it is structurally matched on.
///
/// This function is necessary in nearly all cases before matching on a ty/const.
/// Not doing so is likely to be incomplete and therefore unsound during coherence.
fn structurally_normalize_term(
&mut self,
param_env: I::ParamEnv,
term: I::Term,
) -> Result<I::Term, NoSolution> {
if let Some(_) = term.to_alias_term() {
let normalized_term = self.next_term_infer_of_kind(term);
let alias_relate_goal = Goal::new(
self.cx(),
param_env,
ty::PredicateKind::AliasRelate(
ct.into(),
normalized_ct.into(),
term,
normalized_term,
ty::AliasRelationDirection::Equate,
),
);
self.add_goal(GoalSource::Misc, alias_relate_goal);
self.try_evaluate_added_goals()?;
Ok(self.resolve_vars_if_possible(normalized_ct))
Ok(self.resolve_vars_if_possible(normalized_term))
} else {
Ok(ct)
Ok(term)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1338,20 +1338,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let derive_better_type_error =
|alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| {
let ocx = ObligationCtxt::new(self);
let normalized_term = match expected_term.unpack() {
ty::TermKind::Ty(_) => self.next_ty_var(DUMMY_SP).into(),
ty::TermKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
};
ocx.register_obligation(Obligation::new(
self.tcx,
ObligationCause::dummy(),

let Ok(normalized_term) = ocx.structurally_normalize_term(
&ObligationCause::dummy(),
obligation.param_env,
ty::PredicateKind::NormalizesTo(ty::NormalizesTo {
alias: alias_term,
term: normalized_term,
}),
));
let _ = ocx.select_where_possible();
alias_term.to_term(self.tcx),
) else {
return None;
};

if let Err(terr) = ocx.eq(
&ObligationCause::dummy(),
obligation.param_env,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
if matches!(ty.kind(), ty::Alias(..)) {
let ocx = ObligationCtxt::new(infcx);
ty = ocx
.structurally_normalize(&ObligationCause::dummy(), param_env, ty)
.structurally_normalize_ty(&ObligationCause::dummy(), param_env, ty)
.map_err(|_| ())?;
if !ocx.select_where_possible().is_empty() {
return Err(());
Expand Down
15 changes: 13 additions & 2 deletions compiler/rustc_trait_selection/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,15 @@ where
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
}

pub fn structurally_normalize(
pub fn structurally_normalize_ty(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: Ty<'tcx>,
) -> Result<Ty<'tcx>, Vec<E>> {
self.infcx
.at(cause, param_env)
.structurally_normalize(value, &mut **self.engine.borrow_mut())
.structurally_normalize_ty(value, &mut **self.engine.borrow_mut())
}

pub fn structurally_normalize_const(
Expand All @@ -340,4 +340,15 @@ where
.at(cause, param_env)
.structurally_normalize_const(value, &mut **self.engine.borrow_mut())
}

pub fn structurally_normalize_term(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: ty::Term<'tcx>,
) -> Result<ty::Term<'tcx>, Vec<E>> {
self.infcx
.at(cause, param_env)
.structurally_normalize_term(value, &mut **self.engine.borrow_mut())
}
}
73 changes: 25 additions & 48 deletions compiler/rustc_trait_selection/src/traits/structural_normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,42 @@ use crate::traits::{NormalizeExt, Obligation};

#[extension(pub trait StructurallyNormalizeExt<'tcx>)]
impl<'tcx> At<'_, 'tcx> {
fn structurally_normalize<E: 'tcx>(
fn structurally_normalize_ty<E: 'tcx>(
&self,
ty: Ty<'tcx>,
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
) -> Result<Ty<'tcx>, Vec<E>> {
assert!(!ty.is_ty_var(), "should have resolved vars before calling");

if self.infcx.next_trait_solver() {
let ty::Alias(..) = *ty.kind() else {
return Ok(ty);
};

let new_infer_ty = self.infcx.next_ty_var(self.cause.span);

// We simply emit an `alias-eq` goal here, since that will take care of
// normalizing the LHS of the projection until it is a rigid projection
// (or a not-yet-defined opaque in scope).
let obligation = Obligation::new(
self.infcx.tcx,
self.cause.clone(),
self.param_env,
ty::PredicateKind::AliasRelate(
ty.into(),
new_infer_ty.into(),
ty::AliasRelationDirection::Equate,
),
);

fulfill_cx.register_predicate_obligation(self.infcx, obligation);
let errors = fulfill_cx.select_where_possible(self.infcx);
if !errors.is_empty() {
return Err(errors);
}

Ok(self.infcx.resolve_vars_if_possible(new_infer_ty))
} else {
Ok(self.normalize(ty).into_value_registering_obligations(self.infcx, fulfill_cx))
}
self.structurally_normalize_term(ty.into(), fulfill_cx).map(|term| term.expect_type())
}

fn structurally_normalize_const<E: 'tcx>(
&self,
ct: ty::Const<'tcx>,
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
) -> Result<ty::Const<'tcx>, Vec<E>> {
assert!(!ct.is_ct_infer(), "should have resolved vars before calling");
if self.infcx.tcx.features().generic_const_exprs() {
return Ok(super::evaluate_const(&self.infcx, ct, self.param_env));
}

self.structurally_normalize_term(ct.into(), fulfill_cx).map(|term| term.expect_const())
}

fn structurally_normalize_term<E: 'tcx>(
&self,
term: ty::Term<'tcx>,
fulfill_cx: &mut dyn TraitEngine<'tcx, E>,
) -> Result<ty::Term<'tcx>, Vec<E>> {
assert!(!term.is_infer(), "should have resolved vars before calling");

if self.infcx.next_trait_solver() {
let ty::ConstKind::Unevaluated(..) = ct.kind() else {
return Ok(ct);
};
if let None = term.to_alias_term() {
return Ok(term);
}

let new_infer_ct = self.infcx.next_const_var(self.cause.span);
let new_infer = match term.unpack() {
ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
};

// We simply emit an `alias-eq` goal here, since that will take care of
// normalizing the LHS of the projection until it is a rigid projection
Expand All @@ -68,11 +51,7 @@ impl<'tcx> At<'_, 'tcx> {
self.infcx.tcx,
self.cause.clone(),
self.param_env,
ty::PredicateKind::AliasRelate(
ct.into(),
new_infer_ct.into(),
ty::AliasRelationDirection::Equate,
),
ty::PredicateKind::AliasRelate(term, new_infer, ty::AliasRelationDirection::Equate),
);

fulfill_cx.register_predicate_obligation(self.infcx, obligation);
Expand All @@ -81,11 +60,9 @@ impl<'tcx> At<'_, 'tcx> {
return Err(errors);
}

Ok(self.infcx.resolve_vars_if_possible(new_infer_ct))
} else if self.infcx.tcx.features().generic_const_exprs() {
Ok(super::evaluate_const(&self.infcx, ct, self.param_env))
Ok(self.infcx.resolve_vars_if_possible(new_infer))
} else {
Ok(self.normalize(ct).into_value_registering_obligations(self.infcx, fulfill_cx))
Ok(self.normalize(term).into_value_registering_obligations(self.infcx, fulfill_cx))
}
}
}
11 changes: 11 additions & 0 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,17 @@ pub macro cfg_match {
/// }
/// }
/// ```
///
/// If desired, it is possible to return expressions through the use of surrounding braces:
///
/// ```
/// #![feature(cfg_match)]
///
/// let _some_string = cfg_match! {{
/// unix => { "With great power comes great electricity bills" },
/// _ => { "Behind every successful diet is an unwatched pizza" },
/// }};
/// ```
#[cfg(not(bootstrap))]
#[unstable(feature = "cfg_match", issue = "115585")]
#[rustc_diagnostic_item = "cfg_match"]
Expand Down
33 changes: 31 additions & 2 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2663,8 +2663,8 @@ macro_rules! uint_impl {
///
/// Basic usage:
///
/// Please note that this example is shared between integer types.
/// Which explains why `u32` is used here.
/// Please note that this example is shared between integer types,
/// which explains why `u32` is used here.
///
/// ```
/// #![feature(bigint_helper_methods)]
Expand All @@ -2677,6 +2677,35 @@ macro_rules! uint_impl {
"(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX));"
)]
/// ```
///
/// This is the core per-digit operation for "grade school" O(n²) multiplication.
///
/// Please note that this example is shared between integer types,
/// using `u8` for simplicity of the demonstration.
///
/// ```
/// #![feature(bigint_helper_methods)]
///
/// fn quadratic_mul<const N: usize>(a: [u8; N], b: [u8; N]) -> [u8; N] {
/// let mut out = [0; N];
/// for j in 0..N {
/// let mut carry = 0;
/// for i in 0..(N - j) {
/// (out[j + i], carry) = u8::carrying_mul_add(a[i], b[j], out[j + i], carry);
/// }
/// }
/// out
/// }
///
/// // -1 * -1 == 1
/// assert_eq!(quadratic_mul([0xFF; 3], [0xFF; 3]), [1, 0, 0]);
///
/// assert_eq!(u32::wrapping_mul(0x9e3779b9, 0x7f4a7c15), 0xCFFC982D);
/// assert_eq!(
/// quadratic_mul(u32::to_le_bytes(0x9e3779b9), u32::to_le_bytes(0x7f4a7c15)),
/// u32::to_le_bytes(0xCFFC982D)
/// );
/// ```
#[unstable(feature = "bigint_helper_methods", issue = "85532")]
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")]
#[must_use = "this returns the result of the operation, \
Expand Down
Loading

0 comments on commit f77ead0

Please sign in to comment.